On 2/21/24 19:06, Mike Pattrick wrote: > 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.
Hi, Mike. That's an interesting feature. Thanks! Though the patch subject states 'userspace: ' the code seem to affect tunnels in general, since it modifies tunnel flags for all tunnels. More on that below. > > Signed-off-by: Mike Pattrick <m...@redhat.com> > --- > v2: Changed documentation, and added a NEWS item > v3: NEWS file merge conflict > --- > NEWS | 3 +++ > 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, 43 insertions(+), 12 deletions(-) > > diff --git a/NEWS b/NEWS > index c9e4064e6..3a75d3850 100644 > --- a/NEWS > +++ b/NEWS > @@ -4,6 +4,9 @@ Post-v3.3.0 > * Conntrack now supports 'random' flag for selecting ports in a range > while natting and 'persistent' flag for selection of the IP address > from a range. > + * IPv6 UDP tunnels will now honour the csum option. Configuring the All IPv6 UDP tunnels? Also, double spaces between sentences. > + interface with "options:csum=false" now has the same effect in OVS s/in OVS// > + as the udp6zerocsumtx option has with kernel UDP tunnels. s/kernel/Linux kenrel/ > > > v3.3.0 - 16 Feb 2024 > diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c > index dee9ab344..e8258bc4e 100644 > --- a/lib/netdev-native-tnl.c > +++ b/lib/netdev-native-tnl.c > @@ -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) { Please add a tunnel-push-pop test that verifies that cehcksums are skipped. > /* Write a value in now to mark that we should compute the checksum > * later. 0xffff is handy because it is transparent to the > * calculation. */ > diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c > index 60caa02fb..f9a778988 100644 > --- a/lib/netdev-vport.c > +++ b/lib/netdev-vport.c > @@ -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. */ Please explain what does it mean in the comment. And in the enum comment. > + if (tnl_cfg.csum == NETDEV_TNL_CSUM_DEFAULT && strstr(type, "gre")) { The tnl_cfg is initialized with memset, but the enum is not guaranteed to start with a zero value. > + 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) { > diff --git a/lib/netdev.h b/lib/netdev.h > index 67a8486bd..a79531e6d 100644 > --- a/lib/netdev.h > +++ b/lib/netdev.h > @@ -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, > +}; Some comments for the values would be nice to have. > + > /* 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; > > diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c > index 80ddee78a..6f462874e 100644 > --- a/ofproto/tunnel.c > +++ b/ofproto/tunnel.c > @@ -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; This enables csum flag for tunnels that do not support it, see the 'has_csum' check in set_tunnel_config(). That's the reason this change is causing csum flag to appear in SRv6 tests, while it is not supposed to support it. SRv6 is not even a UDP or GRE tunne, so the flag will not have any effect, but may create some confusion. > + } > + > 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"); > diff --git a/tests/tunnel.at b/tests/tunnel.at > index 282651ac7..e68be8b04 100644 > --- a/tests/tunnel.at > +++ b/tests/tunnel.at > @@ -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 SRv6 is an IPv6-IPv46 tunnel. 'csum' flag doesn't make any sense for it. > ]) > > OVS_VSWITCHD_STOP > diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml > index 612ba41e3..f802ea32d 100644 > --- a/vswitchd/vswitch.xml > +++ b/vswitchd/vswitch.xml > @@ -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. What is the defualt behavior for GRE ? > When set to false, no checksums Enclose 'true' and 'false' with <code> tags. Also below. > + will be computed for outgoing tunnel encapsulation packets. s/packets/headers/ ? > When > + true, checksums will be computed for all outgoing tunnel > + encapsulation packets. *headers > 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. And, please, double spaces between sentences. Best regards, Ilya Maximets. _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev