Add the IPv6 addresses as an union with IPv4 ones. When using IPv4, the
newly introduced padding after the IPv4 addresses needs to be zeroed out.
Signed-off-by: Jiri Benc
---
v1->v2: Fix incorrect IP_TUNNEL_KEY_IPV4_PAD_LEN calculation, thanks to
Alexei.
---
drivers/net/vxlan.c| 6 +++---
include/net/ip_tunnels.h | 24
net/core/filter.c | 4 ++--
net/ipv4/ip_gre.c | 10 +-
net/ipv4/ip_tunnel_core.c | 8
net/openvswitch/flow_netlink.c | 18 +-
net/openvswitch/flow_table.c | 2 +-
net/openvswitch/vport-geneve.c | 2 +-
net/openvswitch/vport.c| 2 +-
net/openvswitch/vport.h| 4 ++--
10 files changed, 48 insertions(+), 32 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index ad51dac88d19..30a7abcf2c09 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1276,8 +1276,8 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct
sk_buff *skb)
goto drop;
info = &tun_dst->u.tun_info;
- info->key.ipv4_src = iph->saddr;
- info->key.ipv4_dst = iph->daddr;
+ info->key.u.ipv4.src = iph->saddr;
+ info->key.u.ipv4.dst = iph->daddr;
info->key.ipv4_tos = iph->tos;
info->key.ipv4_ttl = iph->ttl;
info->key.tp_src = udp_hdr(skb)->source;
@@ -1925,7 +1925,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct
net_device *dev,
dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
vni = be64_to_cpu(info->key.tun_id);
remote_ip.sin.sin_family = AF_INET;
- remote_ip.sin.sin_addr.s_addr = info->key.ipv4_dst;
+ remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
dst = &remote_ip;
}
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index cc3b39e9010b..6a51371dad00 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -25,10 +25,24 @@
/* Used to memset ip_tunnel padding. */
#define IP_TUNNEL_KEY_SIZE offsetofend(struct ip_tunnel_key, tp_dst)
+/* Used to memset ipv4 address padding. */
+#define IP_TUNNEL_KEY_IPV4_PAD offsetofend(struct ip_tunnel_key, u.ipv4.dst)
+#define IP_TUNNEL_KEY_IPV4_PAD_LEN \
+ (FIELD_SIZEOF(struct ip_tunnel_key, u) -\
+FIELD_SIZEOF(struct ip_tunnel_key, u.ipv4))
+
struct ip_tunnel_key {
__be64 tun_id;
- __be32 ipv4_src;
- __be32 ipv4_dst;
+ union {
+ struct {
+ __be32 src;
+ __be32 dst;
+ } ipv4;
+ struct {
+ struct in6_addr src;
+ struct in6_addr dst;
+ } ipv6;
+ } u;
__be16 tun_flags;
u8 ipv4_tos;
u8 ipv4_ttl;
@@ -177,8 +191,10 @@ static inline void __ip_tunnel_info_init(struct
ip_tunnel_info *tun_info,
const void *opts, u8 opts_len)
{
tun_info->key.tun_id = tun_id;
- tun_info->key.ipv4_src = saddr;
- tun_info->key.ipv4_dst = daddr;
+ tun_info->key.u.ipv4.src = saddr;
+ tun_info->key.u.ipv4.dst = daddr;
+ memset((unsigned char *)&tun_info->key + IP_TUNNEL_KEY_IPV4_PAD,
+ 0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
tun_info->key.ipv4_tos = tos;
tun_info->key.ipv4_ttl = ttl;
tun_info->key.tun_flags = tun_flags;
diff --git a/net/core/filter.c b/net/core/filter.c
index 83f08cefeab7..379568562ffb 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1495,7 +1495,7 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64
size, u64 flags, u64 r5)
return -EINVAL;
to->tunnel_id = be64_to_cpu(info->key.tun_id);
- to->remote_ipv4 = be32_to_cpu(info->key.ipv4_src);
+ to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src);
return 0;
}
@@ -1529,7 +1529,7 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64
size, u64 flags, u64 r5)
info = &md->u.tun_info;
info->mode = IP_TUNNEL_INFO_TX;
info->key.tun_id = cpu_to_be64(from->tunnel_id);
- info->key.ipv4_dst = cpu_to_be32(from->remote_ipv4);
+ info->key.u.ipv4.dst = cpu_to_be32(from->remote_ipv4);
return 0;
}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index fb44d693796e..b7bb7d6aa7a8 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -407,8 +407,8 @@ static int ipgre_rcv(struct sk_buff *skb, const struct
tnl_ptk_info *tpi)
return PACKET_REJECT;
info = &tun_dst->u.tun_info;
- info->key.ipv4_src = iph->saddr;
- info->key.ipv4_dst = iph->dad