Commit c1ea5d67 authored by Jiri Benc's avatar Jiri Benc Committed by David S. Miller
Browse files

ip_tunnels: add IPv6 addresses to ip_tunnel_key



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: default avatarJiri Benc <jbenc@redhat.com>
Acked-by: default avatarThomas Graf <tgraf@suug.ch>
Acked-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 376534a3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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;
	}

+20 −4
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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;
}
+5 −5
Original line number Diff line number Diff line
@@ -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->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;

@@ -527,8 +527,8 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)

	key = &tun_info->key;
	memset(&fl, 0, sizeof(fl));
	fl.daddr = key->ipv4_dst;
	fl.saddr = key->ipv4_src;
	fl.daddr = key->u.ipv4.dst;
	fl.saddr = key->u.ipv4.src;
	fl.flowi4_tos = RT_TOS(key->ipv4_tos);
	fl.flowi4_mark = skb->mark;
	fl.flowi4_proto = IPPROTO_GRE;
@@ -564,7 +564,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)

	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
	err = iptunnel_xmit(skb->sk, rt, skb, fl.saddr,
			    key->ipv4_dst, IPPROTO_GRE,
			    key->u.ipv4.dst, IPPROTO_GRE,
			    key->ipv4_tos, key->ipv4_ttl, df, false);
	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
	return;
+4 −4
Original line number Diff line number Diff line
@@ -227,10 +227,10 @@ static int ip_tun_build_state(struct net_device *dev, struct nlattr *attr,
		tun_info->key.tun_id = nla_get_u64(tb[LWTUNNEL_IP_ID]);

	if (tb[LWTUNNEL_IP_DST])
		tun_info->key.ipv4_dst = nla_get_be32(tb[LWTUNNEL_IP_DST]);
		tun_info->key.u.ipv4.dst = nla_get_be32(tb[LWTUNNEL_IP_DST]);

	if (tb[LWTUNNEL_IP_SRC])
		tun_info->key.ipv4_src = nla_get_be32(tb[LWTUNNEL_IP_SRC]);
		tun_info->key.u.ipv4.src = nla_get_be32(tb[LWTUNNEL_IP_SRC]);

	if (tb[LWTUNNEL_IP_TTL])
		tun_info->key.ipv4_ttl = nla_get_u8(tb[LWTUNNEL_IP_TTL]);
@@ -262,8 +262,8 @@ static int ip_tun_fill_encap_info(struct sk_buff *skb,
	struct ip_tunnel_info *tun_info = lwt_tun_info(lwtstate);

	if (nla_put_u64(skb, LWTUNNEL_IP_ID, tun_info->key.tun_id) ||
	    nla_put_be32(skb, LWTUNNEL_IP_DST, tun_info->key.ipv4_dst) ||
	    nla_put_be32(skb, LWTUNNEL_IP_SRC, tun_info->key.ipv4_src) ||
	    nla_put_be32(skb, LWTUNNEL_IP_DST, tun_info->key.u.ipv4.dst) ||
	    nla_put_be32(skb, LWTUNNEL_IP_SRC, tun_info->key.u.ipv4.src) ||
	    nla_put_u8(skb, LWTUNNEL_IP_TOS, tun_info->key.ipv4_tos) ||
	    nla_put_u8(skb, LWTUNNEL_IP_TTL, tun_info->key.ipv4_ttl) ||
	    nla_put_u16(skb, LWTUNNEL_IP_SPORT, tun_info->key.tp_src) ||
Loading