Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c222798 authored by Pravin B Shelar's avatar Pravin B Shelar Committed by David S. Miller
Browse files

ip-tunnel: Use API to access tunnel metadata options.



Currently tun-info options pointer is used in few cases to
pass options around. But tunnel options can be accessed using
ip_tunnel_info_opts() API without using the pointer. Following
patch removes the redundant pointer and consistently make use
of API.

Signed-off-by: default avatarPravin B Shelar <pshelar@nicira.com>
Acked-by: default avatarThomas Graf <tgraf@suug.ch>
Reviewed-by: default avatarJesse Gross <jesse@nicira.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d1bfc625
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -143,7 +143,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)

	if (ip_tunnel_collect_metadata() || gs->collect_md) {
		__be16 flags;
		void *opts;

		flags = TUNNEL_KEY | TUNNEL_GENEVE_OPT |
			(gnvh->oam ? TUNNEL_OAM : 0) |
@@ -154,11 +153,9 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
					 gnvh->opt_len * 4);
		if (!tun_dst)
			goto drop;

		/* Update tunnel dst according to Geneve options. */
		opts = ip_tunnel_info_opts(&tun_dst->u.tun_info,
					   gnvh->opt_len * 4);
		memcpy(opts, gnvh->options, gnvh->opt_len * 4);
		ip_tunnel_info_opts_set(&tun_dst->u.tun_info,
					gnvh->options, gnvh->opt_len * 4);
	} else {
		/* Drop packets w/ critical options,
		 * since we don't support any...
@@ -663,7 +660,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)

		tunnel_id_to_vni(key->tun_id, vni);
		if (key->tun_flags & TUNNEL_GENEVE_OPT)
			opts = ip_tunnel_info_opts(info, info->options_len);
			opts = ip_tunnel_info_opts(info);

		udp_csum = !!(key->tun_flags & TUNNEL_CSUM);
		err = geneve_build_skb(rt, skb, key->tun_flags, vni,
+2 −2
Original line number Diff line number Diff line
@@ -1271,7 +1271,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
			goto drop;

		info = &tun_dst->u.tun_info;
		md = ip_tunnel_info_opts(info, sizeof(*md));
		md = ip_tunnel_info_opts(info);
	} else {
		memset(md, 0, sizeof(*md));
	}
@@ -1948,7 +1948,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
		tos = info->key.tos;

		if (info->options_len)
			md = ip_tunnel_info_opts(info, sizeof(*md));
			md = ip_tunnel_info_opts(info);
	} else {
		md->gbp = skb->mark;
	}
+14 −17
Original line number Diff line number Diff line
@@ -48,21 +48,16 @@ static inline bool skb_valid_dst(const struct sk_buff *skb)
struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);

static inline struct metadata_dst *tun_rx_dst(__be16 flags,
					      __be64 tunnel_id, int md_size)
static inline struct metadata_dst *tun_rx_dst(int md_size)
{
	struct metadata_dst *tun_dst;
	struct ip_tunnel_info *info;

	tun_dst = metadata_dst_alloc(md_size, GFP_ATOMIC);
	if (!tun_dst)
		return NULL;

	info = &tun_dst->u.tun_info;
	info->key.tun_flags = flags;
	info->key.tun_id = tunnel_id;
	info->key.tp_src = 0;
	info->key.tp_dst = 0;
	tun_dst->u.tun_info.options_len = 0;
	tun_dst->u.tun_info.mode = 0;
	return tun_dst;
}

@@ -73,17 +68,14 @@ static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
{
	const struct iphdr *iph = ip_hdr(skb);
	struct metadata_dst *tun_dst;
	struct ip_tunnel_info *info;

	tun_dst = tun_rx_dst(flags, tunnel_id, md_size);
	tun_dst = tun_rx_dst(md_size);
	if (!tun_dst)
		return NULL;

	info = &tun_dst->u.tun_info;
	info->key.u.ipv4.src = iph->saddr;
	info->key.u.ipv4.dst = iph->daddr;
	info->key.tos = iph->tos;
	info->key.ttl = iph->ttl;
	ip_tunnel_key_init(&tun_dst->u.tun_info.key,
			   iph->saddr, iph->daddr, iph->tos, iph->ttl,
			   0, 0, tunnel_id, flags);
	return tun_dst;
}

@@ -96,16 +88,21 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
	struct metadata_dst *tun_dst;
	struct ip_tunnel_info *info;

	tun_dst = tun_rx_dst(flags, tunnel_id, md_size);
	tun_dst = tun_rx_dst(md_size);
	if (!tun_dst)
		return NULL;

	info = &tun_dst->u.tun_info;
	info->mode = IP_TUNNEL_INFO_IPV6;
	info->key.tun_flags = flags;
	info->key.tun_id = tunnel_id;
	info->key.tp_src = 0;
	info->key.tp_dst = 0;

	info->key.u.ipv6.src = ip6h->saddr;
	info->key.u.ipv6.dst = ip6h->daddr;
	info->key.tos = ipv6_get_dsfield(ip6h);
	info->key.ttl = ip6h->hop_limit;
	info->mode = IP_TUNNEL_INFO_IPV6;
	return tun_dst;
}

+31 −36
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ struct ip_tunnel_key {

struct ip_tunnel_info {
	struct ip_tunnel_key	key;
	const void		*options;
	u8			options_len;
	u8			mode;
};
@@ -180,49 +179,32 @@ int ip_tunnel_encap_add_ops(const struct ip_tunnel_encap_ops *op,
int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *op,
			    unsigned int num);

static inline void __ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
				      __be32 saddr, __be32 daddr,
				      u8 tos, u8 ttl,
				      __be16 tp_src, __be16 tp_dst,
					 __be64 tun_id, __be16 tun_flags,
					 const void *opts, u8 opts_len)
				      __be64 tun_id, __be16 tun_flags)
{
	tun_info->key.tun_id = tun_id;
	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,
	key->tun_id = tun_id;
	key->u.ipv4.src = saddr;
	key->u.ipv4.dst = daddr;
	memset((unsigned char *)key + IP_TUNNEL_KEY_IPV4_PAD,
	       0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
	tun_info->key.tos = tos;
	tun_info->key.ttl = ttl;
	tun_info->key.tun_flags = tun_flags;
	key->tos = tos;
	key->ttl = ttl;
	key->tun_flags = tun_flags;

	/* For the tunnel types on the top of IPsec, the tp_src and tp_dst of
	 * the upper tunnel are used.
	 * E.g: GRE over IPSEC, the tp_src and tp_port are zero.
	 */
	tun_info->key.tp_src = tp_src;
	tun_info->key.tp_dst = tp_dst;
	key->tp_src = tp_src;
	key->tp_dst = tp_dst;

	/* Clear struct padding. */
	if (sizeof(tun_info->key) != IP_TUNNEL_KEY_SIZE)
		memset((unsigned char *)&tun_info->key + IP_TUNNEL_KEY_SIZE,
		       0, sizeof(tun_info->key) - IP_TUNNEL_KEY_SIZE);

	tun_info->options = opts;
	tun_info->options_len = opts_len;

	tun_info->mode = 0;
}

static inline void ip_tunnel_info_init(struct ip_tunnel_info *tun_info,
				       const struct iphdr *iph,
				       __be16 tp_src, __be16 tp_dst,
				       __be64 tun_id, __be16 tun_flags,
				       const void *opts, u8 opts_len)
{
	__ip_tunnel_info_init(tun_info, iph->saddr, iph->daddr,
			      iph->tos, iph->ttl, tp_src, tp_dst,
			      tun_id, tun_flags, opts, opts_len);
	if (sizeof(*key) != IP_TUNNEL_KEY_SIZE)
		memset((unsigned char *)key + IP_TUNNEL_KEY_SIZE,
		       0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
}

static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
@@ -317,11 +299,24 @@ static inline void iptunnel_xmit_stats(int err,
	}
}

static inline void *ip_tunnel_info_opts(struct ip_tunnel_info *info, size_t n)
static inline void *ip_tunnel_info_opts(struct ip_tunnel_info *info)
{
	return info + 1;
}

static inline void ip_tunnel_info_opts_get(void *to,
					   const struct ip_tunnel_info *info)
{
	memcpy(to, info + 1, info->options_len);
}

static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
					   const void *from, int len)
{
	memcpy(ip_tunnel_info_opts(info), from, len);
	info->options_len = len;
}

static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstate)
{
	return (struct ip_tunnel_info *)lwtstate->data;
+0 −2
Original line number Diff line number Diff line
@@ -249,7 +249,6 @@ static int ip_tun_build_state(struct net_device *dev, struct nlattr *attr,
		tun_info->key.tun_flags = nla_get_u16(tb[LWTUNNEL_IP_FLAGS]);

	tun_info->mode = IP_TUNNEL_INFO_TX;
	tun_info->options = NULL;
	tun_info->options_len = 0;

	*ts = new_state;
@@ -357,7 +356,6 @@ static int ip6_tun_build_state(struct net_device *dev, struct nlattr *attr,
		tun_info->key.tun_flags = nla_get_u16(tb[LWTUNNEL_IP6_FLAGS]);

	tun_info->mode = IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_IPV6;
	tun_info->options = NULL;
	tun_info->options_len = 0;

	*ts = new_state;
Loading