ip_tunnel: add support for setting flow label via collect metadata
authorDaniel Borkmann <daniel@iogearbox.net>
Wed, 9 Mar 2016 02:00:02 +0000 (03:00 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 11 Mar 2016 20:14:26 +0000 (15:14 -0500)
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>
drivers/net/geneve.c
drivers/net/vxlan.c
include/net/dst_metadata.h
include/net/ip_tunnels.h
include/net/udp_tunnel.h
net/ipv6/ip6_udp_tunnel.c
net/tipc/udp_media.c

index 6a0cbbe03e5de261bfe60a9d08077f4871aa2b1f..89ccff79d76ce3b0ff37a50cc5faa6d877ddf743 100644 (file)
@@ -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);
        }
        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,
                             !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
        return NETDEV_TX_OK;
index 2399099e68cf9320e55a690f8e752be15e76adf9..8bdcd5ea84240e0c1bd69080e3170fddf7312fae 100644 (file)
@@ -2066,7 +2066,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        return;
                }
                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);
 #endif
        }
index 84b833af6882c1747d01fba265c364b674ed146b..5db9f5910428f3741049c3377b1f4ed9a013bed1 100644 (file)
@@ -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,
                           iph->saddr, iph->daddr, iph->tos, iph->ttl,
-                          0, 0, tunnel_id, flags);
+                          0, 0, 0, tunnel_id, flags);
        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.dst = ip6h->daddr;
+
        info->key.tos = ipv6_get_dsfield(ip6h);
        info->key.ttl = ip6h->hop_limit;
+       info->key.label = ip6_flowlabel(ip6h);
+
        return tun_dst;
 }
 
index 0acd80fadb327737a74c9f48ee4a7b93eb1a6be4..5dc2e454f866989cd6c2eae974453ed3b3a8cd0b 100644 (file)
@@ -48,6 +48,7 @@ struct ip_tunnel_key {
        __be16                  tun_flags;
        u8                      tos;            /* TOS for IPv4, TC for IPv6 */
        u8                      ttl;            /* TTL for IPv4, HL for IPv6 */
+       __be32                  label;          /* Flow Label for IPv6 */
        __be16                  tp_src;
        __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,
                                      __be32 saddr, __be32 daddr,
-                                     u8 tos, u8 ttl,
+                                     u8 tos, u8 ttl, __be32 label,
                                      __be16 tp_src, __be16 tp_dst,
                                      __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);
        key->tos = tos;
        key->ttl = ttl;
+       key->label = label;
        key->tun_flags = tun_flags;
 
        /* For the tunnel types on the top of IPsec, the tp_src and tp_dst of
index 97f5adb121a6450fc70d77942d90bee7beb29e5a..b83114077cee33d184a2bef45da1be686f94a72f 100644 (file)
@@ -88,8 +88,8 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
                         struct sk_buff *skb,
                         struct net_device *dev, struct in6_addr *saddr,
                         struct in6_addr *daddr,
-                        __u8 prio, __u8 ttl, __be16 src_port,
-                        __be16 dst_port, bool nocheck);
+                        __u8 prio, __u8 ttl, __be32 label,
+                        __be16 src_port, __be16 dst_port, bool nocheck);
 #endif
 
 void udp_tunnel_sock_release(struct socket *sock);
index 14dacf1df529d9602cc497976db0868f68d9fbb7..a7520528ecd27fae3d8ccee03c76345f0776234a 100644 (file)
@@ -73,8 +73,8 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
                         struct sk_buff *skb,
                         struct net_device *dev, struct in6_addr *saddr,
                         struct in6_addr *daddr,
-                        __u8 prio, __u8 ttl, __be16 src_port,
-                        __be16 dst_port, bool nocheck)
+                        __u8 prio, __u8 ttl, __be32 label,
+                        __be16 src_port, __be16 dst_port, bool nocheck)
 {
        struct udphdr *uh;
        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_reset_network_header(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->nexthdr     = IPPROTO_UDP;
        ip6h->hop_limit   = ttl;
index 49b3c2ede7ab524ab9cfaa2dfa9c9093522ccf22..c94f9a15e2cd663d83d22ce205fd2a937d111228 100644 (file)
@@ -196,7 +196,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
                ttl = ip6_dst_hoplimit(ndst);
                err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
                                           ndst->dev, &src->ipv6,
-                                          &dst->ipv6, 0, ttl, src->udp_port,
+                                          &dst->ipv6, 0, ttl, 0, src->udp_port,
                                           dst->udp_port, false);
 #endif
        }