NIKSS-vSwitch / nikss

Native In-Kernel P4-programmable Software Switch for Software-Defined Networking (previously PSA-eBPF)
Apache License 2.0
48 stars 4 forks source link

Invalid byte order of key for LPM table #82

Open tatry opened 2 years ago

tatry commented 2 years ago

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 https://github.com/NIKSS-vSwitch/nikss/blob/f04d2e861f220b25fbb9e11ec4b0b51a730fd87b/lib/nikss_table.c#L1270

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:

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:

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": {}
}