Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

openvswitch: add tunnel protocol to sw_flow_key

Store tunnel protocol (AF_INET or AF_INET6) in sw_flow_key. This field now
also acts as an indicator whether the flow contains tunnel data (this was
previously indicated by tun_key.u.ipv4.dst being set but with IPv6 addresses
in an union with IPv4 ones this won't work anymore).

The new field was added to a hole in sw_flow_key.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiri Benc and committed by
David S. Miller
00a93bab 4917a154

+12 -5
+2 -2
net/openvswitch/flow.c
··· 698 698 { 699 699 /* Extract metadata from packet. */ 700 700 if (tun_info) { 701 - if (ip_tunnel_info_af(tun_info) != AF_INET) 702 - return -EINVAL; 701 + key->tun_proto = ip_tunnel_info_af(tun_info); 703 702 memcpy(&key->tun_key, &tun_info->key, sizeof(key->tun_key)); 704 703 705 704 if (tun_info->options_len) { ··· 713 714 key->tun_opts_len = 0; 714 715 } 715 716 } else { 717 + key->tun_proto = 0; 716 718 key->tun_opts_len = 0; 717 719 memset(&key->tun_key, 0, sizeof(key->tun_key)); 718 720 }
+1
net/openvswitch/flow.h
··· 63 63 u32 skb_mark; /* SKB mark. */ 64 64 u16 in_port; /* Input switch port (or DP_MAX_PORTS). */ 65 65 } __packed phy; /* Safe when right after 'tun_key'. */ 66 + u8 tun_proto; /* Protocol of encapsulating tunnel. */ 66 67 u32 ovs_flow_hash; /* Datapath computed hash value. */ 67 68 u32 recirc_id; /* Recirculation ID. */ 68 69 struct {
+8 -2
net/openvswitch/flow_netlink.c
··· 643 643 } 644 644 645 645 SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask); 646 + if (is_mask) 647 + SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true); 648 + else 649 + SW_FLOW_KEY_PUT(match, tun_proto, AF_INET, false); 646 650 647 651 if (rem > 0) { 648 652 OVS_NLERR(log, "IPv4 tunnel attribute has %d unknown bytes.", ··· 1198 1194 /* The userspace does not send tunnel attributes that 1199 1195 * are 0, but we should not wildcard them nonetheless. 1200 1196 */ 1201 - if (match->key->tun_key.u.ipv4.dst) 1197 + if (match->key->tun_proto) 1202 1198 SW_FLOW_KEY_MEMSET_FIELD(match, tun_key, 1203 1199 0xff, true); 1204 1200 ··· 1371 1367 if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority)) 1372 1368 goto nla_put_failure; 1373 1369 1374 - if ((swkey->tun_key.u.ipv4.dst || is_mask)) { 1370 + if ((swkey->tun_proto || is_mask)) { 1375 1371 const void *opts = NULL; 1376 1372 1377 1373 if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT) ··· 1917 1913 1918 1914 tun_info = &tun_dst->u.tun_info; 1919 1915 tun_info->mode = IP_TUNNEL_INFO_TX; 1916 + if (key.tun_proto == AF_INET6) 1917 + tun_info->mode |= IP_TUNNEL_INFO_IPV6; 1920 1918 tun_info->key = key.tun_key; 1921 1919 1922 1920 /* We need to store the options in the action itself since
+1 -1
net/openvswitch/flow_table.c
··· 427 427 428 428 static int flow_key_start(const struct sw_flow_key *key) 429 429 { 430 - if (key->tun_key.u.ipv4.dst) 430 + if (key->tun_proto) 431 431 return 0; 432 432 else 433 433 return rounddown(offsetof(struct sw_flow_key, phy),