geneve: allow user to specify TTL for tunnel frames
Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								ff43c28a5e
							
						
					
				
			
			
				commit
				
					
						8760ce5835
					
				
			
		
					 2 changed files with 15 additions and 4 deletions
				
			
		|  | @ -45,6 +45,7 @@ struct geneve_dev { | ||||||
| 	struct net_device  *dev;	/* netdev for geneve tunnel */ | 	struct net_device  *dev;	/* netdev for geneve tunnel */ | ||||||
| 	struct geneve_sock *sock;	/* socket used for geneve tunnel */ | 	struct geneve_sock *sock;	/* socket used for geneve tunnel */ | ||||||
| 	u8                 vni[3];	/* virtual network ID for tunnel */ | 	u8                 vni[3];	/* virtual network ID for tunnel */ | ||||||
|  | 	u8                 ttl;		/* TTL override */ | ||||||
| 	struct sockaddr_in remote;	/* IPv4 address for link partner */ | 	struct sockaddr_in remote;	/* IPv4 address for link partner */ | ||||||
| 	struct list_head   next;	/* geneve's per namespace list */ | 	struct list_head   next;	/* geneve's per namespace list */ | ||||||
| }; | }; | ||||||
|  | @ -184,7 +185,7 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) | ||||||
| 	struct flowi4 fl4; | 	struct flowi4 fl4; | ||||||
| 	int err; | 	int err; | ||||||
| 	__be16 sport; | 	__be16 sport; | ||||||
| 	__u8 tos, ttl = 0; | 	__u8 tos, ttl; | ||||||
| 
 | 
 | ||||||
| 	iip = ip_hdr(skb); | 	iip = ip_hdr(skb); | ||||||
| 
 | 
 | ||||||
|  | @ -207,11 +208,12 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev) | ||||||
| 		goto rt_tx_error; | 		goto rt_tx_error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* TODO: tos and ttl should be configurable */ | 	/* TODO: tos should be configurable */ | ||||||
| 
 | 
 | ||||||
| 	tos = ip_tunnel_ecn_encap(0, iip, skb); | 	tos = ip_tunnel_ecn_encap(0, iip, skb); | ||||||
| 
 | 
 | ||||||
| 	if (IN_MULTICAST(ntohl(fl4.daddr))) | 	ttl = geneve->ttl; | ||||||
|  | 	if (!ttl && IN_MULTICAST(ntohl(fl4.daddr))) | ||||||
| 		ttl = 1; | 		ttl = 1; | ||||||
| 
 | 
 | ||||||
| 	ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); | 	ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); | ||||||
|  | @ -297,6 +299,7 @@ static void geneve_setup(struct net_device *dev) | ||||||
| static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = { | static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = { | ||||||
| 	[IFLA_GENEVE_ID]		= { .type = NLA_U32 }, | 	[IFLA_GENEVE_ID]		= { .type = NLA_U32 }, | ||||||
| 	[IFLA_GENEVE_REMOTE]		= { .len = FIELD_SIZEOF(struct iphdr, daddr) }, | 	[IFLA_GENEVE_REMOTE]		= { .len = FIELD_SIZEOF(struct iphdr, daddr) }, | ||||||
|  | 	[IFLA_GENEVE_TTL]		= { .type = NLA_U8 }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static int geneve_validate(struct nlattr *tb[], struct nlattr *data[]) | static int geneve_validate(struct nlattr *tb[], struct nlattr *data[]) | ||||||
|  | @ -364,6 +367,9 @@ static int geneve_newlink(struct net *net, struct net_device *dev, | ||||||
| 	if (err) | 	if (err) | ||||||
| 		return err; | 		return err; | ||||||
| 
 | 
 | ||||||
|  | 	if (data[IFLA_GENEVE_TTL]) | ||||||
|  | 		geneve->ttl = nla_get_u8(data[IFLA_GENEVE_TTL]); | ||||||
|  | 
 | ||||||
| 	list_add(&geneve->next, &gn->geneve_list); | 	list_add(&geneve->next, &gn->geneve_list); | ||||||
| 
 | 
 | ||||||
| 	hlist_add_head_rcu(&geneve->hlist, &gn->vni_list[hash]); | 	hlist_add_head_rcu(&geneve->hlist, &gn->vni_list[hash]); | ||||||
|  | @ -386,6 +392,7 @@ static size_t geneve_get_size(const struct net_device *dev) | ||||||
| { | { | ||||||
| 	return nla_total_size(sizeof(__u32)) +	/* IFLA_GENEVE_ID */ | 	return nla_total_size(sizeof(__u32)) +	/* IFLA_GENEVE_ID */ | ||||||
| 		nla_total_size(sizeof(struct in_addr)) + /* IFLA_GENEVE_REMOTE */ | 		nla_total_size(sizeof(struct in_addr)) + /* IFLA_GENEVE_REMOTE */ | ||||||
|  | 		nla_total_size(sizeof(__u8)) +  /* IFLA_GENEVE_TTL */ | ||||||
| 		0; | 		0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -402,6 +409,9 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev) | ||||||
| 			    geneve->remote.sin_addr.s_addr)) | 			    geneve->remote.sin_addr.s_addr)) | ||||||
| 		goto nla_put_failure; | 		goto nla_put_failure; | ||||||
| 
 | 
 | ||||||
|  | 	if (nla_put_u8(skb, IFLA_GENEVE_TTL, geneve->ttl)) | ||||||
|  | 		goto nla_put_failure; | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 | 
 | ||||||
| nla_put_failure: | nla_put_failure: | ||||||
|  |  | ||||||
|  | @ -395,6 +395,7 @@ enum { | ||||||
| 	IFLA_GENEVE_UNSPEC, | 	IFLA_GENEVE_UNSPEC, | ||||||
| 	IFLA_GENEVE_ID, | 	IFLA_GENEVE_ID, | ||||||
| 	IFLA_GENEVE_REMOTE, | 	IFLA_GENEVE_REMOTE, | ||||||
|  | 	IFLA_GENEVE_TTL, | ||||||
| 	__IFLA_GENEVE_MAX | 	__IFLA_GENEVE_MAX | ||||||
| }; | }; | ||||||
| #define IFLA_GENEVE_MAX	(__IFLA_GENEVE_MAX - 1) | #define IFLA_GENEVE_MAX	(__IFLA_GENEVE_MAX - 1) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 John W. Linville
				John W. Linville