2010-05-26 12:48:32 -07:00
|
|
|
AT_BANNER([flow classifier unit tests])
|
|
|
|
m4_foreach(
|
|
|
|
[testname],
|
|
|
|
[[empty],
|
|
|
|
[destroy-null],
|
|
|
|
[single-rule],
|
|
|
|
[rule-replacement],
|
2010-11-03 11:00:58 -07:00
|
|
|
[many-rules-in-one-list],
|
2015-06-11 15:53:43 -07:00
|
|
|
[versioned many-rules-in-one-list],
|
2010-05-26 12:48:32 -07:00
|
|
|
[many-rules-in-one-table],
|
2015-06-11 15:53:43 -07:00
|
|
|
[versioned many-rules-in-one-table],
|
2010-11-03 11:00:58 -07:00
|
|
|
[many-rules-in-two-tables],
|
2015-06-11 15:53:43 -07:00
|
|
|
[versioned many-rules-in-two-tables],
|
|
|
|
[many-rules-in-five-tables],
|
|
|
|
[versioned many-rules-in-five-tables]],
|
2010-05-26 12:48:32 -07:00
|
|
|
[AT_SETUP([flow classifier - m4_bpatsubst(testname, [-], [ ])])
|
2015-06-11 15:53:43 -07:00
|
|
|
AT_CHECK([ovstest test-classifier m4_bpatsubst(testname, [versioned], [--versioned])], [0], [], [])
|
2010-05-26 12:48:32 -07:00
|
|
|
AT_CLEANUP])])
|
2012-09-04 12:43:53 -07:00
|
|
|
|
2025-05-16 23:25:17 +02:00
|
|
|
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
|
|
|
|
|
2012-09-04 12:43:53 -07:00
|
|
|
AT_BANNER([miniflow unit tests])
|
|
|
|
m4_foreach(
|
|
|
|
[testname],
|
|
|
|
[[miniflow],
|
|
|
|
[minimask_has_extra],
|
|
|
|
[minimask_combine]],
|
|
|
|
[AT_SETUP([miniflow - m4_bpatsubst(testname, [-], [ ])])
|
2014-04-01 00:47:01 -07:00
|
|
|
AT_CHECK([ovstest test-classifier testname], [0], [], [])
|
2012-09-04 12:43:53 -07:00
|
|
|
AT_CLEANUP])])
|
2013-11-19 17:31:29 -08:00
|
|
|
|
|
|
|
AT_BANNER([flow classifier lookup segmentation])
|
|
|
|
AT_SETUP([flow classifier - lookup segmentation])
|
|
|
|
OVS_VSWITCHD_START
|
2016-01-26 16:23:30 -08:00
|
|
|
add_of_ports br0 1 2 3
|
2013-11-19 17:31:29 -08:00
|
|
|
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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=2,nw_dst=192.168.0.0/16,nw_frag=no
|
2013-11-19 17:31:29 -08:00
|
|
|
Datapath actions: 1
|
|
|
|
])
|
2014-12-08 10:10:07 -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=11.1.2.15,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
|
2013-11-19 17:31:29 -08:00
|
|
|
AT_CHECK([tail -2 stdout], [0],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_dst=11.0.0.0/8,nw_frag=no
|
2013-11-19 17:31:29 -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=80'], [0], [stdout])
|
|
|
|
AT_CHECK([tail -2 stdout], [0],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80
|
2013-11-19 17:31:29 -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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=0x40/0xfff0
|
2013-11-19 17:31:29 -08:00
|
|
|
Datapath actions: 2
|
|
|
|
])
|
|
|
|
OVS_VSWITCHD_STOP
|
|
|
|
AT_CLEANUP
|
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
|
|
|
|
|
2013-12-11 11:07:01 -08:00
|
|
|
AT_BANNER([flow classifier prefix lookup])
|
|
|
|
AT_SETUP([flow classifier - prefix lookup])
|
|
|
|
OVS_VSWITCHD_START
|
2016-01-26 16:23:30 -08:00
|
|
|
add_of_ports br0 1 2 3
|
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
|
2014-04-30 14:09:08 -07:00
|
|
|
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)
|
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])
|
2014-05-16 12:51:11 -07:00
|
|
|
|
|
|
|
# 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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no
|
2014-05-16 12:51:11 -07:00
|
|
|
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
|
2014-05-16 12:51:11 -07:00
|
|
|
])
|
|
|
|
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])
|
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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=192.168.0.0/16,nw_frag=no
|
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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=2,nw_dst=192.168.0.0/16,nw_frag=no
|
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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.2.15,nw_frag=no,tp_dst=80
|
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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[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
|
2013-12-11 11:07:01 -08:00
|
|
|
Datapath actions: 3
|
|
|
|
])
|
2014-05-16 12:51:11 -07:00
|
|
|
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],
|
2017-08-05 13:41:09 +08:00
|
|
|
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_dst=10.1.3.16,nw_frag=no
|
2014-05-16 12:51:11 -07:00
|
|
|
Datapath actions: 3
|
|
|
|
])
|
2013-12-11 11:07:01 -08:00
|
|
|
OVS_VSWITCHD_STOP(["/'prefixes' with incompatible field: ipv6_label/d"])
|
|
|
|
AT_CLEANUP
|
2015-01-11 13:25:24 -08:00
|
|
|
|
2024-11-15 14:20:44 +01:00
|
|
|
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
|
|
|
|
|
2015-01-11 13:25:24 -08:00
|
|
|
AT_BANNER([conjunctive match])
|
|
|
|
|
|
|
|
AT_SETUP([single conjunctive match])
|
|
|
|
OVS_VSWITCHD_START
|
2016-01-26 16:23:30 -08:00
|
|
|
add_of_ports br0 1 2 3 4 5
|
2015-01-11 13:25:24 -08:00
|
|
|
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
|
|
|
|
])
|
2023-11-15 18:47:33 +09:00
|
|
|
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
|
2015-01-11 13:25:24 -08:00
|
|
|
done
|
|
|
|
done
|
|
|
|
OVS_VSWITCHD_STOP
|
|
|
|
AT_CLEANUP
|
|
|
|
|
|
|
|
AT_SETUP([multiple conjunctive match])
|
|
|
|
OVS_VSWITCHD_START
|
2016-01-26 16:23:30 -08:00
|
|
|
add_of_ports br0 1 2 3 4 5
|
2015-01-11 13:25:24 -08:00
|
|
|
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
|
2016-01-26 16:23:30 -08:00
|
|
|
add_of_ports br0 1 2 3 4 5 6 7
|
2015-01-11 13:25:24 -08:00
|
|
|
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 ;;
|
2018-05-25 17:11:07 -07:00
|
|
|
?1) out=4 ;;
|
2015-01-11 13:25:24 -08:00
|
|
|
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
|
2015-06-26 08:14:15 -07:00
|
|
|
|
|
|
|
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
|
2019-04-30 09:19:16 -07:00
|
|
|
ovs-ofctl: "conjunction" actions may be used along with "note" but not any other kind of action (such as the "output" action used here)
|
2015-06-26 08:14:15 -07:00
|
|
|
])
|
|
|
|
AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' add-flow br0 'actions=conjunction(3,1/2),output:1'], [1], [], [dnl
|
2019-04-30 09:19:16 -07:00
|
|
|
ovs-ofctl: "conjunction" actions may be used along with "note" but not any other kind of action (such as the "output" action used here)
|
2015-06-26 08:14:15 -07:00
|
|
|
])
|
|
|
|
OVS_VSWITCHD_STOP
|
|
|
|
AT_CLEANUP
|
2020-10-26 16:03:19 -03:00
|
|
|
|
2023-11-15 18:47:33 +09:00
|
|
|
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
|
|
|
|
|
2020-10-26 16:03:19 -03:00
|
|
|
# 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
|