NIKSS-vSwitch/nikss

Invalid byte order of key for LPM table

Opened this issue · 0 comments

tatry commented

Lets define P4 table in the following way (match Ethernet MAC address with LPM algorithm):

action a1(EthernetAddress dst) {
    hdr.ethernet.dstAddr = dst;
}

table tbl_lpm {
    key = {
        hdr.ethernet.dstAddr : lpm;
    }
    actions = { NoAction; a1; }
    default_action = NoAction;
}

At the line

if (ret != NO_ERROR) {

Command table add pipe 1 ingress_tbl_lpm action id 1 key 00:11:22:33:44:55 data 11:22:33:44:55:66 generates:

  • key buffer: 60 00 00 00 00 00 00 00 55 44 33 22 11 00 00 00
  • mk->data: 55 44 33 22 11 00 00 00
  • flags: WRITE_HOST_ORDER

Command table add pipe 1 ingress_tbl_lpm action id 1 key 00:11:22:33:44:55/64 data 11:22:33:44:55:66 (added prefix length to the key) generates:

  • key buffer: 60 00 00 00 00 00 00 00 00 00 00 11 22 33 44 55
  • mk->data: 55 44 33 22 11 00 00 00
  • flags: WRITE_NETWORK_ORDER

The two commands above should generate the same table key.


Another question is that if this is the right byte order for the LPM key and where padding have to placed. For the same table lets define such (passing!) PTF test:

self.table_add(table="ingress_tbl_lpm", key=["00:11:22:33:44:50/44"], action=1, data=["11:22:33:44:55:67"])
self.table_add(table="ingress_tbl_lpm", key=["00:11:22:33:44:55/48"], action=1, data=["11:22:33:44:55:66"])
pkt = testutils.simple_ip_packet(eth_dst="00:11:22:33:44:50")
exp_pkt = testutils.simple_ip_packet(eth_dst="11:22:33:44:55:66")

testutils.send_packet(self, PORT0, pkt)
testutils.verify_packet(self, exp_pkt, PORT1)

Which is equivalent to add following table entries:

table add pipe 1 ingress_tbl_lpm action id 1 key 00:11:22:33:44:50/44 data 11:22:33:44:55:67
table add pipe 1 ingress_tbl_lpm action id 1 key 00:11:22:33:44:55/48 data 11:22:33:44:55:66

and send packet which should match the first entry, but second one is executed. Below some portion of logs from program:

<...>-6202    [002] d.s1.  4857.592111: bpf_trace_printk: Control: applying tbl_lpm_0
<...>-6202    [002] d.s1.  4857.592111: bpf_trace_printk: Control: key hdr.ethernet.dstAddr=0x5044332211000000
<...>-6202    [002] d.s1.  4857.592112: bpf_trace_printk: Control: performing table lookup
<...>-6202    [002] d.s1.  4857.592112: bpf_trace_printk: Control: executing action ingress_a1
<...>-6202    [002] d.s1.  4857.592112: bpf_trace_printk: Control: param dst=0x112233445566 (48 bits)
<...>-6202    [002] d.s1.  4857.592112: bpf_trace_printk: Control: tbl_lpm_0 applied

Table dump:

{
    "entries": [
        {
            "key": [
                {
                    "type": "lpm",
                    "value": "0x1122334455",
                    "prefix_len": 48
                }
            ],
            "action": {
                "id": 1,
                "name": "ingress_a1",
                "parameters": [
                    {
                        "name": "dst",
                        "value": "0x112233445566"
                    }
                ]
            },
            "DirectCounter": {},
            "DirectMeter": {}
        },
        {
            "key": [
                {
                    "type": "lpm",
                    "value": "0x1122334450",
                    "prefix_len": 44
                }
            ],
            "action": {
                "id": 1,
                "name": "ingress_a1",
                "parameters": [
                    {
                        "name": "dst",
                        "value": "0x112233445567"
                    }
                ]
            },
            "DirectCounter": {},
            "DirectMeter": {}
        }
    ],
    "default_action": {
        "action": {
            "id": 0,
            "name": "_NoAction",
            "parameters": []
        },
        "DirectCounter": {},
        "DirectMeter": {}
    },
    "DirectCounter": {}
}