@@ -1,6 +1,9 @@
Post-v3.3.0
--------------------
-
+ - Userspace datapath:
+ * IPv6 UDP tunnels will now honour the csum option. Configuring the
+ interface with "options:csum=false" now has the same effect in OVS
+ as the udp6zerocsumtx option has with kernel UDP tunnels.
v3.3.0 - 16 Feb 2024
--------------------
@@ -424,7 +424,7 @@ udp_build_header(const struct netdev_tunnel_config *tnl_cfg,
udp = netdev_tnl_ip_build_header(data, params, IPPROTO_UDP, 0);
udp->udp_dst = tnl_cfg->dst_port;
- if (params->is_ipv6 || params->flow->tunnel.flags & FLOW_TNL_F_CSUM) {
+ if (params->flow->tunnel.flags & FLOW_TNL_F_CSUM) {
/* Write a value in now to mark that we should compute the checksum
* later. 0xffff is handy because it is transparent to the
* calculation. */
@@ -702,7 +702,9 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args, char **errp)
tnl_cfg.dst_port = htons(atoi(node->value));
} else if (!strcmp(node->key, "csum") && has_csum) {
if (!strcmp(node->value, "true")) {
- tnl_cfg.csum = true;
+ tnl_cfg.csum = NETDEV_TNL_CSUM_ENABLED;
+ } else if (!strcmp(node->value, "false")) {
+ tnl_cfg.csum = NETDEV_TNL_CSUM_DISABLED;
}
} else if (!strcmp(node->key, "seq") && has_seq) {
if (!strcmp(node->value, "true")) {
@@ -850,6 +852,11 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args, char **errp)
}
}
+ /* The default csum state for GRE is special. */
+ if (tnl_cfg.csum == NETDEV_TNL_CSUM_DEFAULT && strstr(type, "gre")) {
+ tnl_cfg.csum = NETDEV_TNL_CSUM_DEFAULT_GRE;
+ }
+
enum tunnel_layers layers = tunnel_supported_layers(type, &tnl_cfg);
const char *full_type = (strcmp(type, "vxlan") ? type
: (tnl_cfg.exts & (1 << OVS_VXLAN_EXT_GPE)
@@ -1026,8 +1033,10 @@ get_tunnel_config(const struct netdev *dev, struct smap *args)
}
}
- if (tnl_cfg->csum) {
+ if (tnl_cfg->csum == NETDEV_TNL_CSUM_ENABLED) {
smap_add(args, "csum", "true");
+ } else if (tnl_cfg->csum == NETDEV_TNL_CSUM_DISABLED) {
+ smap_add(args, "csum", "false");
}
if (tnl_cfg->set_seq) {
@@ -111,6 +111,13 @@ enum netdev_srv6_flowlabel {
SRV6_FLOWLABEL_COMPUTE,
};
+enum netdev_tnl_csum {
+ NETDEV_TNL_CSUM_DEFAULT,
+ NETDEV_TNL_CSUM_ENABLED,
+ NETDEV_TNL_CSUM_DISABLED,
+ NETDEV_TNL_CSUM_DEFAULT_GRE,
+};
+
/* Configuration specific to tunnels. */
struct netdev_tunnel_config {
ovs_be64 in_key;
@@ -139,7 +146,7 @@ struct netdev_tunnel_config {
uint8_t tos;
bool tos_inherit;
- bool csum;
+ enum netdev_tnl_csum csum;
bool dont_fragment;
enum netdev_pt_mode pt_mode;
@@ -465,9 +465,14 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
flow->tunnel.flags &= ~(FLOW_TNL_F_MASK & ~FLOW_TNL_PUB_F_MASK);
flow->tunnel.flags |= (cfg->dont_fragment ? FLOW_TNL_F_DONT_FRAGMENT : 0)
- | (cfg->csum ? FLOW_TNL_F_CSUM : 0)
| (cfg->out_key_present ? FLOW_TNL_F_KEY : 0);
+ if (cfg->csum == NETDEV_TNL_CSUM_ENABLED) {
+ flow->tunnel.flags |= FLOW_TNL_F_CSUM;
+ } else if (cfg->csum == NETDEV_TNL_CSUM_DEFAULT && !flow->tunnel.ip_dst) {
+ flow->tunnel.flags |= FLOW_TNL_F_CSUM;
+ }
+
if (cfg->set_egress_pkt_mark) {
flow->pkt_mark = cfg->egress_pkt_mark;
wc->masks.pkt_mark = UINT32_MAX;
@@ -706,8 +711,10 @@ tnl_port_format(const struct tnl_port *tnl_port, struct ds *ds)
ds_put_cstr(ds, ", df=false");
}
- if (cfg->csum) {
+ if (cfg->csum == NETDEV_TNL_CSUM_ENABLED) {
ds_put_cstr(ds, ", csum=true");
+ } else if (cfg->csum == NETDEV_TNL_CSUM_DISABLED) {
+ ds_put_cstr(ds, ", csum=false");
}
ds_put_cstr(ds, ")\n");
@@ -1037,7 +1037,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0,src=1.1.1.1,dst=1.1.1.2,ttl=64),in_port(4789)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
- [Datapath actions: set(tunnel(ipv6_dst=2001:cafe::1,ttl=64,tp_dst=4789,flags(df))),4789
+ [Datapath actions: set(tunnel(ipv6_dst=2001:cafe::1,ttl=64,tp_dst=4789,flags(df|csum))),4789
])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(tun_id=0x0,ipv6_src=2001:cafe::1,ipv6_dst=2001:cafe::2,ttl=64),in_port(4789)'], [0], [stdout])
@@ -1312,13 +1312,13 @@ port 6: p2 (srv6: ::->flow, key=0, legacy_l3, dp port=6, ttl=64)
dnl Encap: ipv4 inner packet
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=4,ttl=128,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
- [Datapath actions: set(tunnel(ipv6_dst=fc00::2,ttl=64,flags(df))),pop_eth,6
+ [Datapath actions: set(tunnel(ipv6_dst=fc00::2,ttl=64,flags(df|csum))),pop_eth,6
])
dnl Encap: ipv6 inner packet
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x86dd),ipv6(src=2001:cafe::92,dst=2001:cafe::88,label=0,proto=47,tclass=0x0,hlimit=64)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
- [Datapath actions: set(tunnel(ipv6_dst=fc00::2,ttl=64,flags(df))),pop_eth,6
+ [Datapath actions: set(tunnel(ipv6_dst=fc00::2,ttl=64,flags(df|csum))),pop_eth,6
])
OVS_VSWITCHD_STOP
@@ -3207,9 +3207,14 @@
<column name="options" key="csum" type='{"type": "boolean"}'>
<p>
Optional. Compute encapsulation header (either GRE or UDP)
- checksums on outgoing packets. Default is disabled, set to
- <code>true</code> to enable. Checksums present on incoming
- packets will be validated regardless of this setting.
+ checksums on outgoing packets. When unset (the default value),
+ checksum computing for outgoing packets is enabled for UDP IPv6
+ tunnels, and disabled otherwise. When set to false, no checksums
+ will be computed for outgoing tunnel encapsulation packets. When
+ true, checksums will be computed for all outgoing tunnel
+ encapsulation packets. Checksums present on incoming packets will
+ be validated regardless of this setting. Incoming packets without
+ a checksum will also be accepted regardless of this setting.
</p>
<p>
This patch adopts the proposed RFC 6935 by allowing null UDP checksums even if the tunnel protocol is IPv6. This is already supported by Linux through the udp6zerocsumtx tunnel option. It is disabled by default and IPv6 tunnels are flagged as requiring a checksum, but this patch enables the user to set csum=false on IPv6 tunnels. Signed-off-by: Mike Pattrick <mkp@redhat.com> --- v2: Changed documentation, and added a NEWS item --- NEWS | 5 ++++- lib/netdev-native-tnl.c | 2 +- lib/netdev-vport.c | 13 +++++++++++-- lib/netdev.h | 9 ++++++++- ofproto/tunnel.c | 11 +++++++++-- tests/tunnel.at | 6 +++--- vswitchd/vswitch.xml | 11 ++++++++--- 7 files changed, 44 insertions(+), 13 deletions(-)