Skip to content

Commit

Permalink
ofproto: Enable address prefix tracking for IPv6 by default.
Browse files Browse the repository at this point in the history
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 cycles 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 reducing
the number of datapath flows by default.

A new test added to check that defaults are working as expected.

Acked-by: Mike Pattrick <[email protected]>
Signed-off-by: Ilya Maximets <[email protected]>
  • Loading branch information
igsilya committed Nov 27, 2024
1 parent 4394f72 commit 2af7cef
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 8 deletions.
4 changes: 3 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ Post-v3.4.0
$ ovs-vsctl set Bridge br0 flow_tables:123=@N -- \
--id=@N create Flow_Table \
name=table123 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.
This allows to significantly reduce amount of datapath flows generated
from mixed IPv4+IPv6 flow tables, if configured.
from mixed IPv4+IPv6 flow tables.
- 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
Expand Down
4 changes: 2 additions & 2 deletions ofproto/ofproto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
2 changes: 1 addition & 1 deletion ofproto/ofproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
65 changes: 65 additions & 0 deletions tests/classifier.at
Original file line number Diff line number Diff line change
Expand Up @@ -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/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

AT_SETUP([flow classifier - ipv6 ND dependency])
OVS_VSWITCHD_START
add_of_ports br0 1 2
Expand Down
8 changes: 4 additions & 4 deletions vswitchd/vswitch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4865,9 +4865,9 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
</p>

<p>
By default, the <code>prefixes=ip_dst,ip_src</code> are used
on each flow table. This instructs the flow classifier to
track the IP destination and source addresses used by the
By default, the <code>prefixes=ip_dst,ip_src,ipv6_dst,ipv6_src</code>
are used on each flow table. This instructs the flow classifier to
track the IPv4 and IPv6 destination and source addresses used by the
rules in this specific flow table.
</p>

Expand All @@ -4890,7 +4890,7 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \

<dt><code>ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src</code></dt>
<dd>
Enables prefix tracking for IP source and destination
Enables prefix tracking for IPv4 source and destination
address fields.
</dd>
</dl>
Expand Down

0 comments on commit 2af7cef

Please sign in to comment.