2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00
ovs/tests/classifier.at

625 lines
28 KiB
Plaintext
Raw Permalink Normal View History

AT_BANNER([flow classifier unit tests])
m4_foreach(
[testname],
[[empty],
[destroy-null],
[single-rule],
[rule-replacement],
[many-rules-in-one-list],
[versioned many-rules-in-one-list],
[many-rules-in-one-table],
[versioned many-rules-in-one-table],
[many-rules-in-two-tables],
[versioned many-rules-in-two-tables],
[many-rules-in-five-tables],
[versioned many-rules-in-five-tables]],
[AT_SETUP([flow classifier - m4_bpatsubst(testname, [-], [ ])])
AT_CHECK([ovstest test-classifier m4_bpatsubst(testname, [versioned], [--versioned])], [0], [], [])
AT_CLEANUP])])
AT_BANNER([flow classifier stress tests])
AT_SETUP([flow classifier - prefixes reconfiguration stress test])
AT_CHECK([ovstest test-classifier stress-prefixes], [0], [stdout])
AT_CLEANUP
AT_BANNER([miniflow unit tests])
m4_foreach(
[testname],
[[miniflow],
[minimask_has_extra],
[minimask_combine]],
[AT_SETUP([miniflow - m4_bpatsubst(testname, [-], [ ])])
AT_CHECK([ovstest test-classifier testname], [0], [], [])
AT_CLEANUP])])
AT_BANNER([flow classifier lookup segmentation])
AT_SETUP([flow classifier - lookup segmentation])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3
AT_DATA([flows.txt], [dnl
table=0 in_port=1 priority=16,tcp,nw_dst=10.1.0.0/255.255.0.0,action=output(3)
table=0 in_port=1 priority=32,tcp,nw_dst=10.1.2.15,action=output(2)
table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=80,action=drop
table=0 in_port=1 priority=0,ip,action=drop
table=0 in_port=2 priority=16,tcp,nw_dst=192.168.0.0/255.255.0.0,action=output(1)
table=0 in_port=2 priority=0,ip,action=drop
table=0 in_port=3 priority=16,tcp,nw_src=10.1.0.0/255.255.0.0,action=output(1)
table=0 in_port=3 priority=0,ip,action=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=2,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=2,nw_dst=192.168.0.0/16,nw_frag=no
Datapath actions: 1
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=11.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=11.0.0.0/8,nw_frag=no
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=0x40/0xfff0
Datapath actions: 2
])
OVS_VSWITCHD_STOP
AT_CLEANUP
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
classifier: Fix missing masks on a final stage with ports trie. Flow lookup doesn't include masks of the final stage in a resulting flow wildcards in case that stage had L4 ports match. Only the result of ports trie lookup is added to the mask. It might be sufficient in many cases, but it's not correct, because ports trie is not how we decided that the packet didn't match in this subtable. In fact, we used a full subtable mask in order to determine that, so all the subtable mask bits has to be added. Ports trie can still be used to adjust ports' mask, but it is not sufficient to determine that the packet didn't match. Assuming we have following 2 OpenFlow rules on the bridge: table=0, priority=10,tcp,tp_dst=80,tcp_flags=+psh actions=drop table=0, priority=0 actions=output(1) The first high priority rule supposed to drop all the TCP data traffic sent on port 80. The handshake, however, is allowed for forwarding. Both 'tcp_flags' and 'tp_dst' are on the final stage in the flow. Since the stage mask from that stage is not incorporated into the flow wildcards and only ports mask is getting updated, we have the following megaflow for the SYN packet that has no match on 'tcp_flags': $ ovs-appctl ofproto/trace br0 "in_port=br0,tcp,tp_dst=80,tcp_flags=syn" Megaflow: recirc_id=0,eth,tcp,in_port=LOCAL,nw_frag=no,tp_dst=80 Datapath actions: 1 If this flow is getting installed into datapath flow table, all the packets for port 80, regardless of TCP flags, will be forwarded. Incorporating all the looked at bits from the final stage into the stages map in order to get all the necessary wildcards. Ports mask has to be updated as a last step, because it doesn't cover the full 64-bit slot in the flowmap. With this change, in the example above, OVS is producing correct flow wildcards including match on TCP flags: Megaflow: recirc_id=0,eth,tcp,in_port=LOCAL,nw_frag=no,tp_dst=80,tcp_flags=-psh Datapath actions: 1 This way only -psh packets will be forwarded, as expected. This issue affects all other fields on stage 4, not only TCP flags. Tests included to cover tcp_flags, nd_target and ct_tp_src/dst. First two are frequently used, ct ones are sharing the same flowmap slot with L4 ports, so important to test. Before the pre-computation of stage masks, flow wildcards were updated during lookup, so there was no issue. The bits of the final stage was lost with introduction of 'stages_map'. Recent adjustment of segment boundaries exposed 'tcp_flags' to the issue. Reported-at: https://github.com/openvswitch/ovs-issues/issues/272 Fixes: ca44218515f0 ("classifier: Adjust segment boundary to execute prerequisite processing.") Fixes: fa2fdbf8d0c1 ("classifier: Pre-compute stage masks.") Acked-by: Aaron Conole <aconole@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2023-02-17 21:09:59 +01:00
AT_SETUP([flow classifier - lookup segmentation - final stage])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3
AT_DATA([flows.txt], [dnl
table=0 in_port=1 priority=33,tcp,tp_dst=80,tcp_flags=+psh,action=output(2)
table=0 in_port=1 priority=0,ip,action=drop
table=0 in_port=2 priority=16,icmp6,nw_ttl=255,icmp_type=135,icmp_code=0,nd_target=1000::1 ,action=output(1)
table=0 in_port=2 priority=0,ip,action=drop
table=0 in_port=3 action=resubmit(,1)
table=1 in_port=3 priority=45,ct_state=+trk+rpl,ct_nw_proto=6,ct_tp_src=3/0x1,tcp,tp_dst=80,tcp_flags=+psh,action=output(2)
table=1 in_port=3 priority=10,ip,action=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=syn'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=-psh
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=syn|ack'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=-psh
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=ack|psh'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=+psh
Datapath actions: 2
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=-psh
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=0x40/0xfff0,tcp_flags=-psh
Datapath actions: drop
])
dnl Having both the port and the tcp flags in the resulting megaflow below
dnl is redundant, but that is how ports trie logic is implemented.
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=81'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=81,tcp_flags=-psh
Datapath actions: drop
])
dnl nd_target is redundant in the megaflow below and it is also not relevant
dnl for an icmp reply. Datapath may discard that match, but it is OK as long
dnl as we have prerequisites (icmp_type) in the match as well.
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=128,icmpv6_code=0"], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x80/0xfc,nd_target=::
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=135,icmpv6_code=0"], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=::
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=135,icmpv6_code=0,nd_target=1000::1"], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=1000::1
Datapath actions: 1
])
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=135,icmpv6_code=0,nd_target=1000::2"], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=1000::2
Datapath actions: drop
])
dnl Check that ports' mask doesn't affect ct ports.
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=3,ct_state=trk|rpl,ct_nw_proto=6,ct_tp_src=3,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=psh'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,ct_state=+rpl+trk,ct_nw_proto=6,ct_tp_src=0x1/0x1,eth,tcp,in_port=3,nw_frag=no,tp_dst=80,tcp_flags=+psh
Datapath actions: 2
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=3,ct_state=trk|rpl,ct_nw_proto=6,ct_tp_src=3,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79,tcp_flags=psh'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,ct_state=+rpl+trk,ct_nw_proto=6,ct_tp_src=0x1/0x1,eth,tcp,in_port=3,nw_frag=no,tp_dst=0x40/0xfff0,tcp_flags=+psh
Datapath actions: drop
])
OVS_VSWITCHD_STOP
AT_CLEANUP
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
AT_BANNER([flow classifier prefix lookup])
AT_SETUP([flow classifier - prefix lookup])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
AT_CHECK([ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- --id=@N1 create Flow_Table name=t0], [0], [ignore], [])
AT_DATA([flows.txt], [dnl
table=0 in_port=1 priority=16,tcp,nw_dst=10.1.0.0/255.255.0.0,action=output(3)
table=0 in_port=1 priority=32,tcp,nw_dst=10.1.2.0/255.255.255.0,tp_src=79,action=output(2)
table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=80,action=drop
table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=8080,action=output(2)
table=0 in_port=1 priority=33,tcp,nw_dst=10.1.2.15,tp_dst=192,action=output(2)
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
table=0 in_port=1 priority=0,ip,action=drop
table=0 in_port=2 priority=16,tcp,nw_dst=192.168.0.0/255.255.0.0,action=output(1)
table=0 in_port=2 priority=0,ip,action=drop
table=0 in_port=3 priority=16,tcp,nw_src=10.1.0.0/255.255.0.0,action=output(1)
table=0 in_port=3 priority=0,ip,action=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# nw_dst and nw_src should be on by default
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no
Datapath actions: drop
])
AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=ipv6_label], [0])
classifier: Increase the maximum number of prefixes (tries). Today users can enable prefix matches for tun_id, tun_src, tun_dst, ip_src, ip_dst, ipv6_src and ipv6_dst. However, they are limited to only 3 of these enabled at the same time. This means that if our flow table is handling both IPv4 and IPv6 traffic, we can't optimize all the addresses, we'll either have to split IPv4 and IPv6 rules into separate tables or sacrifice one of the fields, as we can select only 3 out of 4 fields (ip_src, ip_dst, ipv6_src and ipv6_dst). The maximum number of tries is a little arbitrary. Increasing it will slightly increase memory usage and may take a couple extra processing cycles, but should not change classification results, so should be reasonable. Actually enabling more prefixes will consume more memory and reduce efficiency of a single flow classification, but that's a trade user can make knowing the traffic pattern and how their particular flow table looks like. While efficiency of a single flow classification may go down, the overall performance of the system may be significantly improved by having way less datapath flows with wider matches. The number of tunnels in a typical setup is not that high, so I'm not sure if it makes sense to increase the limit higher. At the same time combined IPv4 + IPv6 handling is pretty common. For example, that's the case with OVN. Tests in ofproto-dpif.at cover IPv4 and IPv6 address classification separately, and these fields can't overlap, so not adding any new tests. Acked-by: Mike Pattrick <mkp@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2024-11-15 14:20:43 +01:00
AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst,nw_src,tun_dst,tun_src,ipv6_src], [1], [],
[ovs-vsctl: nw_dst,nw_src,tun_dst,tun_src,ipv6_src: 5 value(s) specified but the maximum number is 4
])
AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst,nw_dst], [1], [],
[ovs-vsctl: nw_dst,nw_dst: set contains duplicate value
])
AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=nw_dst], [0])
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=2,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=2,nw_dst=192.168.0.0/16,nw_frag=no
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
Datapath actions: 1
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
Datapath actions: drop
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_src=0x0/0xffc0,tp_dst=0x40/0xfff0
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
Datapath actions: 3
])
AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=none], [0])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=10.1.3.16,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.3.16,nw_frag=no
Datapath actions: 3
])
Classifier: Track address prefixes. Add a prefix tree (trie) structure for tracking the used address space, enabling skipping classifier tables containing longer masks than necessary for an address field value in a packet header being classified. This enables less unwildcarding for datapath flows in parts of the address space without host routes. Trie lookup is interwoven to the staged lookup, so that a trie is searched only when the configured trie field becomes relevant for the lookup. The trie lookup results are retained so that each trie is checked at most once for each classifier lookup. This implementation tracks the number of rules at each address prefix for the whole classifier. More aggressive table skipping would be possible by maintaining lists of tables that have prefixes at the lengths encountered on tree traversal, or by maintaining separate tries for subsets of rules separated by metadata fields. Prefix tracking is configured via OVSDB. A new column "prefixes" is added to the database table "Flow_Table". "prefixes" is a set of string values listing the field names for which prefix lookup should be used. As of now, the fields for which prefix lookup can be enabled are: - tun_id, tun_src, tun_dst - nw_src, nw_dst (or aliases ip_src and ip_dst) - ipv6_src, ipv6_dst There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. Examples: ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src ovs-vsctl set Flow_Table table1 prefixes=[] Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
2013-12-11 11:07:01 -08:00
OVS_VSWITCHD_STOP(["/'prefixes' with incompatible field: ipv6_label/d"])
AT_CLEANUP
AT_SETUP([flow classifier - prefix lookup defaults])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3
AT_DATA([flows.txt], [dnl
table=0 in_port=1 priority=16,tcp,nw_src=10.2.0.0/16,nw_dst=10.1.0.0/255.255.0.0,action=output(3)
table=0 in_port=1 priority=33,tcp,nw_src=10.2.2.14,nw_dst=10.1.2.15,tp_dst=80,action=drop
table=0 in_port=1 priority=33,tcp,nw_src=10.2.2.14,nw_dst=10.1.2.15,tp_dst=8080,action=output(2)
table=0 in_port=1 priority=16,tcp,nw_src=192.168.0.0/15,nw_dst=192.168.0.0/255.255.0.0,action=output(3)
table=0 in_port=1 priority=0,ip,action=drop
table=0 in_port=1 priority=16,tcp6,ipv6_src=aaaa:bbbb:c:d:e:f::/96,ipv6_dst=aaaa:bbbb:c:d:a:f:0000:0000/96,action=output(3)
table=0 in_port=1 priority=33,tcp6,ipv6_src=aaaa:bbbb:c:d:e:f:1:2,ipv6_dst=aaaa:bbbb:c:d:a:f:1:2,tp_dst=80,action=drop
table=0 in_port=1 priority=33,tcp6,ipv6_src=aaaa:bbbb:c:d:e:f:1:2,ipv6_dst=aaaa:bbbb:c:d:a:f:1:2,tp_dst=8080,action=output(2)
table=0 in_port=1 priority=16,tcp6,ipv6_src=cccc:dddd:a:b:c:c::/95,ipv6_dst=cccc:dddd:a:b:c:c::/95,action=output(3)
table=0 in_port=1 priority=0,ip6,action=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
dnl nw_dst and nw_src should be on by default.
AT_CHECK([ovs-appctl ofproto/trace br0 \
'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,
nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,
tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0], [dnl
Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_src=192.168.0.0/15,nw_dst=192.168.0.0/16,nw_frag=no
Datapath actions: 3
])
dnl ipv6_dst and ipv6_src should also be on by default.
AT_CHECK([ovs-appctl ofproto/trace br0 \
'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x86dd,
ipv6_src=cccc:dddd:a:b:c:d:7:8,ipv6_dst=cccc:dddd:a:b:c:d:7:9,
nw_proto=6,nw_tos=0,nw_ttl=128,
tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0], [dnl
Megaflow: recirc_id=0,eth,tcp6,in_port=1,ipv6_src=cccc:dddd:a:b:c:c::/95,ipv6_dst=cccc:dddd:a:b:c:c::/95,nw_frag=no
Datapath actions: 3
])
dnl Turn optimizations off and check that we fall back to exact match.
AT_CHECK([ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \
--id=@N1 create Flow_Table name=t0], [0], [ignore])
AT_CHECK([ovs-vsctl set Flow_Table t0 prefixes=none])
AT_CHECK([ovs-appctl ofproto/trace br0 \
'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,
nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,
tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0], [dnl
Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_frag=no
Datapath actions: 3
])
AT_CHECK([ovs-appctl ofproto/trace br0 \
'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x86dd,
ipv6_src=cccc:dddd:a:b:c:d:7:8,ipv6_dst=cccc:dddd:a:b:c:d:7:9,
nw_proto=6,nw_tos=0,nw_ttl=128,
tp_src=8,tp_dst=80'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0], [dnl
Megaflow: recirc_id=0,eth,tcp6,in_port=1,ipv6_src=cccc:dddd:a:b:c:d:7:8,ipv6_dst=cccc:dddd:a:b:c:d:7:9,nw_frag=no
Datapath actions: 3
])
OVS_VSWITCHD_STOP
AT_CLEANUP
classifier: Adjust segment boundary to execute prerequisite processing. During flow processing, the flow wildcards are checked as a series of stages, and these stages are intended to carry dependencies in a single direction. But when the neighbor discovery processing, for example, was executed there is an incorrect dependency chain - we need fields from stage 4 to determine whether we need fields from stage 3. We can build a set of flow rules to demonstrate this: table=0,priority=100,ipv6,ipv6_src=1000::/10 actions=resubmit(,1) table=0,priority=0 actions=NORMAL table=1,priority=110,ipv6,ipv6_dst=1000::3 actions=resubmit(,2) table=1,priority=100,ipv6,ipv6_dst=1000::4 actions=resubmit(,2) table=1,priority=0 actions=NORMAL table=2,priority=120,icmp6,nw_ttl=255,icmp_type=135,icmp_code=0,nd_sll=10:de:ad:be:ef:10 actions=NORMAL table=2,priority=100,tcp actions=NORMAL table=2,priority=100,icmp6 actions=NORMAL table=2,priority=0 actions=NORMAL With this set of flows, any IPv6 packet that executes through this pipeline will have the corresponding nd_sll field flagged as required match for classification even if that field doesn't make sense in such a context (for example, TCP packets). When the corresponding flow is installed into the kernel datapath, this field is not reflected when the revalidator executes the dump stage (see net/openvswitch/flow_netlink.c for more details). During the sweep stage, revalidator will compare the dumped WC with a generated WC - these will mismatch because the generated WC will match on the Neighbor Discovery fields, while the datapath WC will not match on these fields. We will then invalidate the flow and as a side effect force an upcall. By redefining the boundary, we shift these fields to the l4 subtable, and cause masks to be generated matching just the requisite fields. The list of fields being shifted: struct in6_addr nd_target; struct eth_addr arp_sha; struct eth_addr arp_tha; ovs_be16 tcp_flags; ovs_be16 pad2; struct ovs_key_nsh nsh; A standout field would be tcp_flags moving from l3 subtable matches to the l4 subtable matches. This reverts a partial performance optimization in the case of stateless firewalling. The tcp_flags field might have been a good candidate to retain in the l3 segment, but it got overloaded with ICMPv6 ND matching, and therefore we can't preserve this kind of optimization. Two other approaches were considered - moving the nd_target field alone and collapsing the l3/l4 segments into a single subtable for matching. Moving any field individually introduces ABI mismatch, and doesn't completely address the problems with other neighbor discovery related fields (such as nd_sll/nd_tll). Collapsing the two subtables creates an issue with datapath flow explosion, since the l3 and l4 fields will be unwildcarded together (this can be seen with some of the existing classifier tests). A simple test is added to showcase the behavior. Fixes: 476f36e83bc5 ("Classifier: Staged subtable matching.") Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2081773 Reported-by: Numan Siddique <nusiddiq@redhat.com> Suggested-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Aaron Conole <aconole@redhat.com> Acked-by: Eelco Chaudron <echaudro@redhat.com> Acked-by: Cian Ferriter <cian.ferriter@intel.com> Tested-by: Numan Siddique <numans@ovn.org> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2022-05-24 17:35:23 -04:00
AT_SETUP([flow classifier - ipv6 ND dependency])
OVS_VSWITCHD_START
add_of_ports br0 1 2
AT_DATA([flows.txt], [dnl
table=0,priority=100,ipv6,ipv6_src=1000::/10 actions=resubmit(,1)
table=0,priority=0 actions=NORMAL
table=1,priority=110,ipv6,ipv6_dst=1000::3 actions=resubmit(,2)
table=1,priority=100,ipv6,ipv6_dst=1000::4 actions=resubmit(,2)
table=1,priority=0 actions=NORMAL
table=2,priority=120,icmp6,nw_ttl=255,icmp_type=135,icmp_code=0,nd_target=1000::1 actions=NORMAL
table=2,priority=100,tcp actions=NORMAL
table=2,priority=100,icmp6 actions=NORMAL
table=2,priority=0 actions=NORMAL
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# test ICMPv6 echo request (which should have no nd_target field)
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=1,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,icmpv6_type=128,icmpv6_code=0"], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,icmp6,in_port=1,dl_src=f6:d2:b0:19:5e:7b,dl_dst=d2:49:19:91:78:fe,ipv6_src=1000::/10,ipv6_dst=1000::4,nw_ttl=0,nw_frag=no
Datapath actions: 100,2
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_BANNER([conjunctive match])
AT_SETUP([single conjunctive match])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3 4 5
AT_DATA([flows.txt], [dnl
conj_id=1,actions=3
priority=100,ip,ip_src=10.0.0.1,actions=conjunction(1,1/2)
priority=100,ip,ip_src=10.0.0.4,actions=conjunction(1,1/2)
priority=100,ip,ip_src=10.0.0.6,actions=conjunction(1,1/2)
priority=100,ip,ip_src=10.0.0.7,actions=conjunction(1,1/2)
priority=100,ip,ip_dst=10.0.0.2,actions=conjunction(1,2/2)
priority=100,ip,ip_dst=10.0.0.5,actions=conjunction(1,2/2)
priority=100,ip,ip_dst=10.0.0.7,actions=conjunction(1,2/2)
priority=100,ip,ip_dst=10.0.0.8,actions=conjunction(1,2/2)
priority=100,ip,ip_src=10.0.0.1,ip_dst=10.0.0.4,actions=4
priority=100,ip,ip_src=10.0.0.3,ip_dst=10.0.0.5,actions=5
priority=0 actions=2
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
for src in 0 1 2 3 4 5 6 7; do
for dst in 0 1 2 3 4 5 6 7; do
if test $src$dst = 14; then
out=4
elif test $src$dst = 35; then
out=5
else
out=2
case $src in [[1467]]) case $dst in [[2578]]) out=3 ;; esac ;; esac
fi
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=1,dl_type=0x0800,nw_src=10.0.0.$src,nw_dst=10.0.0.$dst"], [0], [stdout])
AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $out
])
dnl Check detailed output for conjunctive match.
if test $out = 3; then
AT_CHECK_UNQUOTED([cat stdout | grep conj\\. | sort], [0], [dnl
-> conj. priority=100,ip,nw_dst=10.0.0.$dst
-> conj. priority=100,ip,nw_src=10.0.0.$src
])
fi
done
done
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([multiple conjunctive match])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3 4 5
AT_DATA([flows.txt], [dnl
conj_id=1,actions=1
conj_id=2,actions=2
conj_id=3,actions=3
priority=5,ip,ip_src=20.0.0.0/8,actions=conjunction(1,1/2),conjunction(2,1/2)
priority=5,ip,ip_src=10.1.0.0/16,actions=conjunction(1,1/2),conjunction(3,2/3)
priority=5,ip,ip_src=10.2.0.0/16,actions=conjunction(1,1/2),conjunction(2,1/2)
priority=5,ip,ip_src=10.1.3.0/24,actions=conjunction(1,1/2),conjunction(3,2/3)
priority=5,ip,ip_src=10.1.4.5/32,actions=conjunction(1,1/2),conjunction(2,1/2)
priority=5,ip,ip_dst=20.0.0.0/8,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=10.1.0.0/16,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=10.2.0.0/16,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=10.1.3.0/24,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=10.1.4.5/32,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=30.0.0.0/8,actions=conjunction(2,2/2),conjunction(3,1/3)
priority=5,ip,ip_dst=40.5.0.0/16,actions=conjunction(2,2/2),conjunction(3,1/3)
priority=5,tcp,tcp_dst=80,actions=conjunction(3,3/3)
priority=5,tcp,tcp_dst=443,actions=conjunction(3,3/3)
priority=5,tcp,tcp_src=80,actions=conjunction(3,3/3)
priority=5,tcp,tcp_src=443,actions=conjunction(3,3/3)
priority=0,actions=4
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
for a0 in \
'1 20.0.0.1' \
'2 10.1.0.1' \
'3 10.2.0.1' \
'4 10.1.3.1' \
'5 10.1.4.5' \
'6 1.2.3.4'
do
for b0 in \
'1 20.0.0.1' \
'2 10.1.0.1' \
'3 10.2.0.1' \
'4 10.1.3.1' \
'5 10.1.4.5' \
'6 30.0.0.1' \
'7 40.5.0.1' \
'8 1.2.3.4'
do
for c0 in '1 80' '2 443' '3 8080'; do
for d0 in '1 80' '2 443' '3 8080'; do
set $a0; a=$1 ip_src=$2
set $b0; b=$1 ip_dst=$2
set $c0; c=$1 tcp_src=$2
set $d0; d=$1 tcp_dst=$2
case $a$b$c$d in
[[12345]][[12345]]??) out=1 ;;
[[135]][[67]]??) out=2 ;;
[[24]][[67]][[12]]? | [[24]][[67]]?[[12]]) out=3 ;;
*) out=4
esac
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=5,dl_type=0x0800,nw_proto=6,nw_src=$ip_src,nw_dst=$ip_dst,tcp_src=$tcp_src,tcp_dst=$tcp_dst"], [0], [stdout])
AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $out
])
done
done
done
done
OVS_VSWITCHD_STOP
AT_CLEANUP
# In conjunctive match, we can find some soft matches that turn out not to be a
# real match. Usually, that's the end of the road--there is no real match.
# But if there is a flow identical to one of the flows that was a soft match,
# except with a lower priority, then we have to try again with that lower
# priority flow. This test checks this special case.
AT_SETUP([conjunctive match priority fallback])
OVS_VSWITCHD_START
add_of_ports br0 1 2 3 4 5 6 7
AT_DATA([flows.txt], [dnl
conj_id=1,actions=1
conj_id=3,actions=3
priority=5,ip,ip_src=10.0.0.1,actions=conjunction(1,1/2)
priority=5,ip,ip_src=10.0.0.2,actions=conjunction(1,1/2)
priority=5,ip,ip_dst=10.0.0.1,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=10.0.0.2,actions=conjunction(1,2/2)
priority=5,ip,ip_dst=10.0.0.3,actions=conjunction(1,2/2)
priority=4,ip,ip_src=10.0.0.3,ip_dst=10.0.0.2,actions=2
priority=3,ip,ip_src=10.0.0.1,actions=conjunction(3,1/2)
priority=3,ip,ip_src=10.0.0.3,actions=conjunction(3,1/2)
priority=3,ip,ip_dst=10.0.0.2,actions=conjunction(3,2/2)
priority=3,ip,ip_dst=10.0.0.3,actions=conjunction(3,2/2)
priority=3,ip,ip_dst=10.0.0.4,actions=conjunction(3,2/2)
priority=2,ip,ip_dst=10.0.0.1,actions=4
priority=1,ip,ip_src=10.0.0.1,ip_dst=10.0.0.5,actions=5
priority=0,actions=6
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
for src in 0 1 2 3; do
for dst in 0 1 2 3 4 5; do
case $src$dst in
[[12]][[123]]) out=1 ;;
32) out=2 ;;
[[13]][[234]]) out=3 ;;
?1) out=4 ;;
15) out=5 ;;
*) out=6
esac
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=7,dl_type=0x0800,nw_src=10.0.0.$src,nw_dst=10.0.0.$dst"], [0], [stdout])
AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $out
])
done
done
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conjunctive match and other actions])
OVS_VSWITCHD_START
# It's OK to use "conjunction" actions with "note" actions.
AT_CHECK([ovs-ofctl add-flow br0 'actions=conjunction(3,1/2),note:41.42.43.44.45.46'])
AT_CHECK([ovs-ofctl add-flow br0 'actions=note:41.42.43.44.45.46,conjunction(3,1/2)'])
# It's not OK to use "conjunction" actions with other types of actions.
AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' add-flow br0 'actions=output:1,conjunction(3,1/2)'], [1], [], [dnl
ovs-ofctl: "conjunction" actions may be used along with "note" but not any other kind of action (such as the "output" action used here)
])
AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' add-flow br0 'actions=conjunction(3,1/2),output:1'], [1], [], [dnl
ovs-ofctl: "conjunction" actions may be used along with "note" but not any other kind of action (such as the "output" action used here)
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conjunctive match with same priority])
OVS_VSWITCHD_START
add_of_ports br0 1 2
AT_DATA([flows.txt], [dnl
conj_id=1,actions=2
conj_id=2,actions=drop
priority=10,ip,ip_dst=10.0.0.1,actions=conjunction(1,1/2)
priority=10,ip,ip_src=10.0.0.2,actions=conjunction(1,2/2)
priority=10,ip,ip_dst=10.0.0.3,actions=conjunction(2,1/2)
priority=10,ip,in_port=1,actions=conjunction(2,2/2)
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# Check that "priority=10,ip,in_port=1,actions=conjunction(2,2/2)" is
# correctly excluded from the output.
AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=1,dl_type=0x0800,nw_dst=10.0.0.1,nw_src=10.0.0.2" | grep conj\\. | sort], [0], [dnl
-> conj. priority=10,ip,nw_dst=10.0.0.1
-> conj. priority=10,ip,nw_src=10.0.0.2
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conjunctive match with metadata])
OVS_VSWITCHD_START
AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0"])
AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=1,len=8}->tun_metadata1"])
AT_DATA([flows.txt], [dnl
conj_id=7,actions=drop
priority=5,tun_metadata0=0x1,actions=conjunction(7,1/2)
priority=5,tun_metadata1=0x2,actions=conjunction(7,2/2)
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# Check that tunnel metadata is included in the output.
AT_CHECK([ovs-appctl ofproto/trace br0 "tun_metadata0=0x1,tun_metadata1=0x2,in_port=br0" | grep conj\\. | sort], [0], [dnl
-> conj. priority=5,tun_metadata0=0x1
-> conj. priority=5,tun_metadata1=0x2
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conjunctive match with or without port map])
OVS_VSWITCHD_START
add_of_ports br0 1 2
AT_DATA([flows.txt], [dnl
conj_id=1,actions=drop
conj_id=2,actions=drop
priority=10,ip,actions=conjunction(1,1/2),conjunction(2,1/2)
priority=10,in_port=p1,actions=conjunction(1,2/2)
priority=10,in_port=p2,actions=conjunction(1,2/2)
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 "ip,in_port=p1" --names | grep conj\\. | sort], [0], [dnl
-> conj. priority=10,in_port=p1
-> conj. priority=10,ip
])
AT_CHECK([ovs-appctl ofproto/trace br0 "ip,in_port=p2" | grep conj\\. | sort], [0], [dnl
-> conj. priority=10,in_port=2
-> conj. priority=10,ip
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conjunctive match with resubmit])
OVS_VSWITCHD_START
add_of_ports br0 1 2
AT_DATA([flows.txt], [dnl
conj_id=1,actions=resubmit(,2)
priority=10,ip,actions=conjunction(1,1/2)
priority=10,in_port=p1,actions=conjunction(1,2/2)
priority=10,in_port=p2,actions=conjunction(1,2/2)
table=2,conj_id=7,actions=resubmit(,3)
table=2,priority=20,ip,actions=conjunction(7,1/2)
table=2,priority=20,in_port=p1,actions=conjunction(7,2/2)
table=2,priority=20,in_port=p2,actions=conjunction(7,2/2)
table=3,actions=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
# Check that conj_flows are reset for each table and that they are output
# exactly once.
AT_CHECK([ovs-appctl ofproto/trace br0 "ip,in_port=p1" --names | grep conj\\. | sort], [0], [dnl
-> conj. priority=10,in_port=p1
-> conj. priority=10,ip
-> conj. priority=20,in_port=p1
-> conj. priority=20,ip
])
OVS_VSWITCHD_STOP
AT_CLEANUP
# Flow classifier a packet with excess of padding.
AT_SETUP([flow classifier - packet with extra padding])
OVS_VSWITCHD_START
add_of_ports br0 1 2
AT_DATA([flows.txt], [dnl
priority=5,ip,ip_dst=1.1.1.1,actions=1
priority=5,ip,ip_dst=1.1.1.2,actions=2
priority=0,actions=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
packet=00020202020000010101010008004500001c00010000401176cc01010101010101020d6a00350008ee3a
AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1 $packet] , [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
Datapath actions: 2
])
# normal packet plus 255 bytes of padding (8bit padding).
# 255 * 2 = 510
padding=$(printf '%*s' 510 | tr ' ' '0')
AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1 ${packet}${padding}] , [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
Datapath actions: 2
])
# normal packet plus padding up to 65535 bytes of length (16bit limit).
# 65535 - 43 = 65492
# 65492 * 2 = 130984
padding=$(printf '%*s' 130984 | tr ' ' '0')
AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1 ${packet}${padding}], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=1.1.1.2,nw_frag=no
Datapath actions: 2
])
OVS_VSWITCHD_STOP
AT_CLEANUP