ip_tunnel: add support for setting flow label via collect metadata
This patch extends udp_tunnel6_xmit_skb() to pass in the IPv6 flow label from call sites. Currently, there's no such option and it's always set to zero when writing ip6_flow_hdr(). Add a label member to ip_tunnel_key, so that flow-based tunnels via collect metadata frontends can make use of it. vxlan and geneve will be converted to add flow label support separately. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e327f4e193
commit
134611446d
|
@ -1054,7 +1054,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||||
ttl = ttl ? : ip6_dst_hoplimit(dst);
|
ttl = ttl ? : ip6_dst_hoplimit(dst);
|
||||||
}
|
}
|
||||||
udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
|
udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
|
||||||
&fl6.saddr, &fl6.daddr, prio, ttl,
|
&fl6.saddr, &fl6.daddr, prio, ttl, 0,
|
||||||
sport, geneve->dst_port,
|
sport, geneve->dst_port,
|
||||||
!!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
|
!!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
|
|
|
@ -2066,7 +2066,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
|
udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
|
||||||
&saddr, &dst->sin6.sin6_addr, tos, ttl,
|
&saddr, &dst->sin6.sin6_addr, tos, ttl, 0,
|
||||||
src_port, dst_port, !udp_sum);
|
src_port, dst_port, !udp_sum);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
|
||||||
|
|
||||||
ip_tunnel_key_init(&tun_dst->u.tun_info.key,
|
ip_tunnel_key_init(&tun_dst->u.tun_info.key,
|
||||||
iph->saddr, iph->daddr, iph->tos, iph->ttl,
|
iph->saddr, iph->daddr, iph->tos, iph->ttl,
|
||||||
0, 0, tunnel_id, flags);
|
0, 0, 0, tunnel_id, flags);
|
||||||
return tun_dst;
|
return tun_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +152,11 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
|
||||||
|
|
||||||
info->key.u.ipv6.src = ip6h->saddr;
|
info->key.u.ipv6.src = ip6h->saddr;
|
||||||
info->key.u.ipv6.dst = ip6h->daddr;
|
info->key.u.ipv6.dst = ip6h->daddr;
|
||||||
|
|
||||||
info->key.tos = ipv6_get_dsfield(ip6h);
|
info->key.tos = ipv6_get_dsfield(ip6h);
|
||||||
info->key.ttl = ip6h->hop_limit;
|
info->key.ttl = ip6h->hop_limit;
|
||||||
|
info->key.label = ip6_flowlabel(ip6h);
|
||||||
|
|
||||||
return tun_dst;
|
return tun_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct ip_tunnel_key {
|
||||||
__be16 tun_flags;
|
__be16 tun_flags;
|
||||||
u8 tos; /* TOS for IPv4, TC for IPv6 */
|
u8 tos; /* TOS for IPv4, TC for IPv6 */
|
||||||
u8 ttl; /* TTL for IPv4, HL for IPv6 */
|
u8 ttl; /* TTL for IPv4, HL for IPv6 */
|
||||||
|
__be32 label; /* Flow Label for IPv6 */
|
||||||
__be16 tp_src;
|
__be16 tp_src;
|
||||||
__be16 tp_dst;
|
__be16 tp_dst;
|
||||||
};
|
};
|
||||||
|
@ -181,7 +182,7 @@ int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *op,
|
||||||
|
|
||||||
static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
|
static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
|
||||||
__be32 saddr, __be32 daddr,
|
__be32 saddr, __be32 daddr,
|
||||||
u8 tos, u8 ttl,
|
u8 tos, u8 ttl, __be32 label,
|
||||||
__be16 tp_src, __be16 tp_dst,
|
__be16 tp_src, __be16 tp_dst,
|
||||||
__be64 tun_id, __be16 tun_flags)
|
__be64 tun_id, __be16 tun_flags)
|
||||||
{
|
{
|
||||||
|
@ -192,6 +193,7 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
|
||||||
0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
|
0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
|
||||||
key->tos = tos;
|
key->tos = tos;
|
||||||
key->ttl = ttl;
|
key->ttl = ttl;
|
||||||
|
key->label = label;
|
||||||
key->tun_flags = tun_flags;
|
key->tun_flags = tun_flags;
|
||||||
|
|
||||||
/* For the tunnel types on the top of IPsec, the tp_src and tp_dst of
|
/* For the tunnel types on the top of IPsec, the tp_src and tp_dst of
|
||||||
|
|
|
@ -88,8 +88,8 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct net_device *dev, struct in6_addr *saddr,
|
struct net_device *dev, struct in6_addr *saddr,
|
||||||
struct in6_addr *daddr,
|
struct in6_addr *daddr,
|
||||||
__u8 prio, __u8 ttl, __be16 src_port,
|
__u8 prio, __u8 ttl, __be32 label,
|
||||||
__be16 dst_port, bool nocheck);
|
__be16 src_port, __be16 dst_port, bool nocheck);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void udp_tunnel_sock_release(struct socket *sock);
|
void udp_tunnel_sock_release(struct socket *sock);
|
||||||
|
|
|
@ -73,8 +73,8 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct net_device *dev, struct in6_addr *saddr,
|
struct net_device *dev, struct in6_addr *saddr,
|
||||||
struct in6_addr *daddr,
|
struct in6_addr *daddr,
|
||||||
__u8 prio, __u8 ttl, __be16 src_port,
|
__u8 prio, __u8 ttl, __be32 label,
|
||||||
__be16 dst_port, bool nocheck)
|
__be16 src_port, __be16 dst_port, bool nocheck)
|
||||||
{
|
{
|
||||||
struct udphdr *uh;
|
struct udphdr *uh;
|
||||||
struct ipv6hdr *ip6h;
|
struct ipv6hdr *ip6h;
|
||||||
|
@ -98,7 +98,7 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
|
||||||
__skb_push(skb, sizeof(*ip6h));
|
__skb_push(skb, sizeof(*ip6h));
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
ip6h = ipv6_hdr(skb);
|
ip6h = ipv6_hdr(skb);
|
||||||
ip6_flow_hdr(ip6h, prio, htonl(0));
|
ip6_flow_hdr(ip6h, prio, label);
|
||||||
ip6h->payload_len = htons(skb->len);
|
ip6h->payload_len = htons(skb->len);
|
||||||
ip6h->nexthdr = IPPROTO_UDP;
|
ip6h->nexthdr = IPPROTO_UDP;
|
||||||
ip6h->hop_limit = ttl;
|
ip6h->hop_limit = ttl;
|
||||||
|
|
|
@ -196,7 +196,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
|
||||||
ttl = ip6_dst_hoplimit(ndst);
|
ttl = ip6_dst_hoplimit(ndst);
|
||||||
err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
|
err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
|
||||||
ndst->dev, &src->ipv6,
|
ndst->dev, &src->ipv6,
|
||||||
&dst->ipv6, 0, ttl, src->udp_port,
|
&dst->ipv6, 0, ttl, 0, src->udp_port,
|
||||||
dst->udp_port, false);
|
dst->udp_port, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue