forked from mirrors/linux
		
	openvswitch: netlink attributes for IPv6 tunneling
Add netlink attributes for IPv6 tunnel addresses. This enables IPv6 support for tunnels. 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>
This commit is contained in:
		
							parent
							
								
									00a93babd0
								
							
						
					
					
						commit
						6b26ba3a7d
					
				
					 2 changed files with 86 additions and 37 deletions
				
			
		| 
						 | 
					@ -349,6 +349,8 @@ enum ovs_tunnel_key_attr {
 | 
				
			||||||
	OVS_TUNNEL_KEY_ATTR_TP_SRC,		/* be16 src Transport Port. */
 | 
						OVS_TUNNEL_KEY_ATTR_TP_SRC,		/* be16 src Transport Port. */
 | 
				
			||||||
	OVS_TUNNEL_KEY_ATTR_TP_DST,		/* be16 dst Transport Port. */
 | 
						OVS_TUNNEL_KEY_ATTR_TP_DST,		/* be16 dst Transport Port. */
 | 
				
			||||||
	OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS,		/* Nested OVS_VXLAN_EXT_* */
 | 
						OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS,		/* Nested OVS_VXLAN_EXT_* */
 | 
				
			||||||
 | 
						OVS_TUNNEL_KEY_ATTR_IPV6_SRC,		/* struct in6_addr src IPv6 address. */
 | 
				
			||||||
 | 
						OVS_TUNNEL_KEY_ATTR_IPV6_DST,		/* struct in6_addr dst IPv6 address. */
 | 
				
			||||||
	__OVS_TUNNEL_KEY_ATTR_MAX
 | 
						__OVS_TUNNEL_KEY_ATTR_MAX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,8 +262,8 @@ size_t ovs_tun_key_attr_size(void)
 | 
				
			||||||
	 * updating this function.
 | 
						 * updating this function.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	return    nla_total_size(8)    /* OVS_TUNNEL_KEY_ATTR_ID */
 | 
						return    nla_total_size(8)    /* OVS_TUNNEL_KEY_ATTR_ID */
 | 
				
			||||||
		+ nla_total_size(4)    /* OVS_TUNNEL_KEY_ATTR_IPV4_SRC */
 | 
							+ nla_total_size(16)   /* OVS_TUNNEL_KEY_ATTR_IPV[46]_SRC */
 | 
				
			||||||
		+ nla_total_size(4)    /* OVS_TUNNEL_KEY_ATTR_IPV4_DST */
 | 
							+ nla_total_size(16)   /* OVS_TUNNEL_KEY_ATTR_IPV[46]_DST */
 | 
				
			||||||
		+ nla_total_size(1)    /* OVS_TUNNEL_KEY_ATTR_TOS */
 | 
							+ nla_total_size(1)    /* OVS_TUNNEL_KEY_ATTR_TOS */
 | 
				
			||||||
		+ nla_total_size(1)    /* OVS_TUNNEL_KEY_ATTR_TTL */
 | 
							+ nla_total_size(1)    /* OVS_TUNNEL_KEY_ATTR_TTL */
 | 
				
			||||||
		+ nla_total_size(0)    /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
 | 
							+ nla_total_size(0)    /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
 | 
				
			||||||
| 
						 | 
					@ -323,6 +323,8 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
 | 
				
			||||||
	[OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS]   = { .len = OVS_ATTR_VARIABLE },
 | 
						[OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS]   = { .len = OVS_ATTR_VARIABLE },
 | 
				
			||||||
	[OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS]    = { .len = OVS_ATTR_NESTED,
 | 
						[OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS]    = { .len = OVS_ATTR_NESTED,
 | 
				
			||||||
						.next = ovs_vxlan_ext_key_lens },
 | 
											.next = ovs_vxlan_ext_key_lens },
 | 
				
			||||||
 | 
						[OVS_TUNNEL_KEY_ATTR_IPV6_SRC]      = { .len = sizeof(struct in6_addr) },
 | 
				
			||||||
 | 
						[OVS_TUNNEL_KEY_ATTR_IPV6_DST]      = { .len = sizeof(struct in6_addr) },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute.  */
 | 
					/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute.  */
 | 
				
			||||||
| 
						 | 
					@ -542,14 +544,14 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 | 
					static int ip_tun_from_nlattr(const struct nlattr *attr,
 | 
				
			||||||
			      struct sw_flow_match *match, bool is_mask,
 | 
								      struct sw_flow_match *match, bool is_mask,
 | 
				
			||||||
			      bool log)
 | 
								      bool log)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nlattr *a;
 | 
						struct nlattr *a;
 | 
				
			||||||
	int rem;
 | 
						int rem;
 | 
				
			||||||
	bool ttl = false;
 | 
						bool ttl = false;
 | 
				
			||||||
	__be16 tun_flags = 0;
 | 
						__be16 tun_flags = 0, ipv4 = false, ipv6 = false;
 | 
				
			||||||
	int opts_type = 0;
 | 
						int opts_type = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nla_for_each_nested(a, attr, rem) {
 | 
						nla_for_each_nested(a, attr, rem) {
 | 
				
			||||||
| 
						 | 
					@ -578,10 +580,22 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 | 
				
			||||||
		case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
 | 
							case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
 | 
				
			||||||
			SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.src,
 | 
								SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.src,
 | 
				
			||||||
					nla_get_in_addr(a), is_mask);
 | 
										nla_get_in_addr(a), is_mask);
 | 
				
			||||||
 | 
								ipv4 = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
 | 
							case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
 | 
				
			||||||
			SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.dst,
 | 
								SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.dst,
 | 
				
			||||||
					nla_get_in_addr(a), is_mask);
 | 
										nla_get_in_addr(a), is_mask);
 | 
				
			||||||
 | 
								ipv4 = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
 | 
				
			||||||
 | 
								SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
 | 
				
			||||||
 | 
										nla_get_in6_addr(a), is_mask);
 | 
				
			||||||
 | 
								ipv6 = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case OVS_TUNNEL_KEY_ATTR_IPV6_DST:
 | 
				
			||||||
 | 
								SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
 | 
				
			||||||
 | 
										nla_get_in6_addr(a), is_mask);
 | 
				
			||||||
 | 
								ipv6 = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case OVS_TUNNEL_KEY_ATTR_TOS:
 | 
							case OVS_TUNNEL_KEY_ATTR_TOS:
 | 
				
			||||||
			SW_FLOW_KEY_PUT(match, tun_key.tos,
 | 
								SW_FLOW_KEY_PUT(match, tun_key.tos,
 | 
				
			||||||
| 
						 | 
					@ -636,7 +650,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 | 
				
			||||||
			opts_type = type;
 | 
								opts_type = type;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			OVS_NLERR(log, "Unknown IPv4 tunnel attribute %d",
 | 
								OVS_NLERR(log, "Unknown IP tunnel attribute %d",
 | 
				
			||||||
				  type);
 | 
									  type);
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -646,22 +660,36 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
 | 
				
			||||||
	if (is_mask)
 | 
						if (is_mask)
 | 
				
			||||||
		SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true);
 | 
							SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		SW_FLOW_KEY_PUT(match, tun_proto, AF_INET, false);
 | 
							SW_FLOW_KEY_PUT(match, tun_proto, ipv6 ? AF_INET6 : AF_INET,
 | 
				
			||||||
 | 
									false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rem > 0) {
 | 
						if (rem > 0) {
 | 
				
			||||||
		OVS_NLERR(log, "IPv4 tunnel attribute has %d unknown bytes.",
 | 
							OVS_NLERR(log, "IP tunnel attribute has %d unknown bytes.",
 | 
				
			||||||
			  rem);
 | 
								  rem);
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ipv4 && ipv6) {
 | 
				
			||||||
 | 
							OVS_NLERR(log, "Mixed IPv4 and IPv6 tunnel attributes");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!is_mask) {
 | 
						if (!is_mask) {
 | 
				
			||||||
		if (!match->key->tun_key.u.ipv4.dst) {
 | 
							if (!ipv4 && !ipv6) {
 | 
				
			||||||
 | 
								OVS_NLERR(log, "IP tunnel dst address not specified");
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ipv4 && !match->key->tun_key.u.ipv4.dst) {
 | 
				
			||||||
			OVS_NLERR(log, "IPv4 tunnel dst address is zero");
 | 
								OVS_NLERR(log, "IPv4 tunnel dst address is zero");
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) {
 | 
				
			||||||
 | 
								OVS_NLERR(log, "IPv6 tunnel dst address is zero");
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!ttl) {
 | 
							if (!ttl) {
 | 
				
			||||||
			OVS_NLERR(log, "IPv4 tunnel TTL not specified.");
 | 
								OVS_NLERR(log, "IP tunnel TTL not specified.");
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -686,13 +714,16 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
 | 
					static int __ip_tun_to_nlattr(struct sk_buff *skb,
 | 
				
			||||||
			      const struct ip_tunnel_key *output,
 | 
								      const struct ip_tunnel_key *output,
 | 
				
			||||||
				const void *tun_opts, int swkey_tun_opts_len)
 | 
								      const void *tun_opts, int swkey_tun_opts_len,
 | 
				
			||||||
 | 
								      unsigned short tun_proto)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (output->tun_flags & TUNNEL_KEY &&
 | 
						if (output->tun_flags & TUNNEL_KEY &&
 | 
				
			||||||
	    nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id))
 | 
						    nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id))
 | 
				
			||||||
		return -EMSGSIZE;
 | 
							return -EMSGSIZE;
 | 
				
			||||||
 | 
						switch (tun_proto) {
 | 
				
			||||||
 | 
						case AF_INET:
 | 
				
			||||||
		if (output->u.ipv4.src &&
 | 
							if (output->u.ipv4.src &&
 | 
				
			||||||
		    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
 | 
							    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
 | 
				
			||||||
				    output->u.ipv4.src))
 | 
									    output->u.ipv4.src))
 | 
				
			||||||
| 
						 | 
					@ -701,6 +732,18 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
 | 
				
			||||||
		    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
 | 
							    nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
 | 
				
			||||||
				    output->u.ipv4.dst))
 | 
									    output->u.ipv4.dst))
 | 
				
			||||||
			return -EMSGSIZE;
 | 
								return -EMSGSIZE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case AF_INET6:
 | 
				
			||||||
 | 
							if (!ipv6_addr_any(&output->u.ipv6.src) &&
 | 
				
			||||||
 | 
							    nla_put_in6_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
 | 
				
			||||||
 | 
									     &output->u.ipv6.src))
 | 
				
			||||||
 | 
								return -EMSGSIZE;
 | 
				
			||||||
 | 
							if (!ipv6_addr_any(&output->u.ipv6.dst) &&
 | 
				
			||||||
 | 
							    nla_put_in6_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
 | 
				
			||||||
 | 
									     &output->u.ipv6.dst))
 | 
				
			||||||
 | 
								return -EMSGSIZE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (output->tos &&
 | 
						if (output->tos &&
 | 
				
			||||||
	    nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TOS, output->tos))
 | 
						    nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TOS, output->tos))
 | 
				
			||||||
		return -EMSGSIZE;
 | 
							return -EMSGSIZE;
 | 
				
			||||||
| 
						 | 
					@ -734,9 +777,10 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ipv4_tun_to_nlattr(struct sk_buff *skb,
 | 
					static int ip_tun_to_nlattr(struct sk_buff *skb,
 | 
				
			||||||
			    const struct ip_tunnel_key *output,
 | 
								    const struct ip_tunnel_key *output,
 | 
				
			||||||
			      const void *tun_opts, int swkey_tun_opts_len)
 | 
								    const void *tun_opts, int swkey_tun_opts_len,
 | 
				
			||||||
 | 
								    unsigned short tun_proto)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nlattr *nla;
 | 
						struct nlattr *nla;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
| 
						 | 
					@ -745,7 +789,8 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
 | 
				
			||||||
	if (!nla)
 | 
						if (!nla)
 | 
				
			||||||
		return -EMSGSIZE;
 | 
							return -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = __ipv4_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len);
 | 
						err = __ip_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len,
 | 
				
			||||||
 | 
									 tun_proto);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -757,9 +802,10 @@ int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb,
 | 
				
			||||||
				  const struct ip_tunnel_info *egress_tun_info,
 | 
									  const struct ip_tunnel_info *egress_tun_info,
 | 
				
			||||||
				  const void *egress_tun_opts)
 | 
									  const void *egress_tun_opts)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __ipv4_tun_to_nlattr(skb, &egress_tun_info->key,
 | 
						return __ip_tun_to_nlattr(skb, &egress_tun_info->key,
 | 
				
			||||||
				  egress_tun_opts,
 | 
									  egress_tun_opts,
 | 
				
			||||||
				    egress_tun_info->options_len);
 | 
									  egress_tun_info->options_len,
 | 
				
			||||||
 | 
									  ip_tunnel_info_af(egress_tun_info));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 | 
					static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 | 
				
			||||||
| 
						 | 
					@ -810,7 +856,7 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
 | 
				
			||||||
		*attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
 | 
							*attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) {
 | 
						if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) {
 | 
				
			||||||
		if (ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match,
 | 
							if (ip_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match,
 | 
				
			||||||
				       is_mask, log) < 0)
 | 
									       is_mask, log) < 0)
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		*attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL);
 | 
							*attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL);
 | 
				
			||||||
| 
						 | 
					@ -1377,8 +1423,8 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
 | 
				
			||||||
		if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
 | 
							if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
 | 
				
			||||||
			opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
 | 
								opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ipv4_tun_to_nlattr(skb, &output->tun_key, opts,
 | 
							if (ip_tun_to_nlattr(skb, &output->tun_key, opts,
 | 
				
			||||||
				       swkey->tun_opts_len))
 | 
									     swkey->tun_opts_len, swkey->tun_proto))
 | 
				
			||||||
			goto nla_put_failure;
 | 
								goto nla_put_failure;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1881,7 +1927,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
 | 
				
			||||||
	int err = 0, start, opts_type;
 | 
						int err = 0, start, opts_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ovs_match_init(&match, &key, NULL);
 | 
						ovs_match_init(&match, &key, NULL);
 | 
				
			||||||
	opts_type = ipv4_tun_from_nlattr(nla_data(attr), &match, false, log);
 | 
						opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log);
 | 
				
			||||||
	if (opts_type < 0)
 | 
						if (opts_type < 0)
 | 
				
			||||||
		return opts_type;
 | 
							return opts_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2380,10 +2426,11 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
 | 
				
			||||||
		if (!start)
 | 
							if (!start)
 | 
				
			||||||
			return -EMSGSIZE;
 | 
								return -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = ipv4_tun_to_nlattr(skb, &tun_info->key,
 | 
							err = ip_tun_to_nlattr(skb, &tun_info->key,
 | 
				
			||||||
				       tun_info->options_len ?
 | 
									       tun_info->options_len ?
 | 
				
			||||||
					     ip_tunnel_info_opts(tun_info) : NULL,
 | 
										     ip_tunnel_info_opts(tun_info) : NULL,
 | 
				
			||||||
					 tun_info->options_len);
 | 
									       tun_info->options_len,
 | 
				
			||||||
 | 
									       ip_tunnel_info_af(tun_info));
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
		nla_nest_end(skb, start);
 | 
							nla_nest_end(skb, start);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue