Commit 13461144 authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller

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: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e327f4e1
...@@ -1054,7 +1054,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment