From 9c22ea86ad2e5ac16a1a153bb76d3b8ba60d3a5a Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Fri, 15 Nov 2024 00:12:27 +0100 Subject: [PATCH] ofproto: Enable address prefix tracking for IPv6 by default. It is common to have flow tables with OpenFlow rules for both IPv4 and IPv6 traffic at the same time. One major example is OVN. Today only IPv4 addresses and L4 ports are prefix matched by default. Since recently, it's possible to turn on the optimization for all 4 fields at the same time (nw_dst, nw_src, ipv6_dst and ipv6_src), but it is an inconvenience for users. IPv6 configurations become more and more common in the real world, so having IPv6 tables not optimized by default is not good. Enable prefix tree lookups for IPv6 addresses by default in addition to IPv4. This change increases memory consumption slightly as well as takes a few extra cycle per flow to create and later iterate over additional prefix trees. However, IPv4 and IPv6 matches are mutually exclusive, so performance overhead should be minimal, especially in comparison with the benefits this configuration brings to IPv6 setups by default. A new test added to check that defaults are working as expected. Signed-off-by: Ilya Maximets --- NEWS | 2 ++ ofproto/ofproto.c | 4 +-- ofproto/ofproto.h | 2 +- tests/classifier.at | 65 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 0ec0c71b1b8..196e5838f4b 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ Post-v3.4.0 $ ovs-vsctl set Bridge br0 flow_tables:0=@N -- \ --id=@N create Flow_Table \ name=table0 prefixes=nw_dst,nw_src,ipv6_dst,ipv6_src + - Address prefix tracking is now enabled by default for both IPv4 and IPv6 + address fields: nw_dst, nw_src, ipv6_dst and ipv6_src. - Userspace datapath: * The default zone limit, if set, is now inherited by any zone that does not have a specific value defined, rather than being diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index cf4f50160b8..3df64efb9ac 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -79,8 +79,8 @@ COVERAGE_DEFINE(ofproto_update_port); /* Default fields to use for prefix tries in each flow table, unless something * else is configured. */ -const enum mf_field_id default_prefix_fields[2] = - { MFF_IPV4_DST, MFF_IPV4_SRC }; +const enum mf_field_id default_prefix_fields[4] = + { MFF_IPV4_DST, MFF_IPV4_SRC, MFF_IPV6_DST, MFF_IPV6_SRC }; /* oftable. */ static void oftable_init(struct oftable *); diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 642a9d001f9..3f85509a1ad 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -562,7 +562,7 @@ struct ofproto_table_settings { enum mf_field_id prefix_fields[CLS_MAX_TRIES]; }; -extern const enum mf_field_id default_prefix_fields[2]; +extern const enum mf_field_id default_prefix_fields[4]; BUILD_ASSERT_DECL(ARRAY_SIZE(default_prefix_fields) <= CLS_MAX_TRIES); int ofproto_get_n_tables(const struct ofproto *); diff --git a/tests/classifier.at b/tests/classifier.at index 05e82ea9688..b7310f15235 100644 --- a/tests/classifier.at +++ b/tests/classifier.at @@ -217,6 +217,71 @@ Datapath actions: 3 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/16,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:d::/96,ipv6_dst=cccc:dddd:a:b:c:d::/96,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/16,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:d::/96,ipv6_dst=cccc:dddd:a:b:c:d::/96,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 + AT_SETUP([flow classifier - ipv6 ND dependency]) OVS_VSWITCHD_START add_of_ports br0 1 2