datapath:compat: Fix build failure on old kernels.
[cascardo/ovs.git] / datapath / vport-geneve.c
index 33047f2..200cc14 100644 (file)
@@ -31,7 +31,6 @@
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/udp.h>
-#include <net/vxlan.h>
 #include <net/xfrm.h>
 
 #include "datapath.h"
@@ -117,7 +116,7 @@ static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni)
 }
 
 /* Convert 24 bit VNI to 64 bit tunnel ID. */
-static __be64 vni_to_tunnel_id(__u8 *vni)
+static __be64 vni_to_tunnel_id(const __u8 *vni)
 {
 #ifdef __BIG_ENDIAN
        return (vni[0] << 16) | (vni[1] << 8) | vni[2];
@@ -132,12 +131,13 @@ static void geneve_build_header(const struct vport *vport,
                              struct sk_buff *skb)
 {
        struct geneve_port *geneve_port = geneve_vport(vport);
+       struct net *net = ovs_dp_get_net(vport->dp);
        struct udphdr *udph = udp_hdr(skb);
        struct genevehdr *geneveh = (struct genevehdr *)(udph + 1);
-       const struct ovs_tunnel_info *tun_info = OVS_CB(skb)->tun_info;
+       const struct ovs_tunnel_info *tun_info = OVS_CB(skb)->egress_tun_info;
 
        udph->dest = inet_sport(geneve_port->sock->sk);
-       udph->source = vxlan_src_port(1, USHRT_MAX, skb);
+       udph->source = udp_flow_src_port(net, skb, 0, 0, true);
        udph->check = 0;
        udph->len = htons(skb->len - skb_transport_offset(skb));
 
@@ -189,13 +189,15 @@ static int geneve_rcv(struct sock *sk, struct sk_buff *skb)
 
        geneveh = geneve_hdr(skb);
 
-       flags = TUNNEL_KEY |
+       flags = TUNNEL_KEY | TUNNEL_OPTIONS_PRESENT |
                (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0) |
                (geneveh->oam ? TUNNEL_OAM : 0) |
                (geneveh->critical ? TUNNEL_CRIT_OPT : 0);
 
        key = vni_to_tunnel_id(geneveh->vni);
-       ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), key, flags,
+       ovs_flow_tun_info_init(&tun_info, ip_hdr(skb),
+                               udp_hdr(skb)->source, udp_hdr(skb)->dest,
+                               key, flags,
                                geneveh->options, opts_len);
 
        ovs_vport_receive(vport_from_priv(geneve_port), skb, &tun_info);
@@ -324,17 +326,25 @@ static void geneve_fix_segment(struct sk_buff *skb)
 
 static int handle_offloads(struct sk_buff *skb)
 {
-       if (skb_is_gso(skb))
+       if (skb_is_gso(skb)) {
+               if (skb_is_encapsulated(skb))
+                       return -ENOSYS;
                OVS_GSO_CB(skb)->fix_segment = geneve_fix_segment;
-       else if (skb->ip_summed != CHECKSUM_PARTIAL)
+       } else if (skb->ip_summed != CHECKSUM_PARTIAL) {
                skb->ip_summed = CHECKSUM_NONE;
+       }
        return 0;
 }
 #else
 static int handle_offloads(struct sk_buff *skb)
 {
        if (skb_is_gso(skb)) {
-               int err = skb_unclone(skb, GFP_ATOMIC);
+               int err;
+
+               if (skb_is_encapsulated(skb))
+                       return -ENOSYS;
+
+               err = skb_unclone(skb, GFP_ATOMIC);
                if (unlikely(err))
                        return err;
 
@@ -358,10 +368,10 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
        int sent_len;
        int err;
 
-       if (unlikely(!OVS_CB(skb)->tun_info))
+       if (unlikely(!OVS_CB(skb)->egress_tun_info))
                return -EINVAL;
 
-       tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
 
        /* Route lookup */
        saddr = tun_key->ipv4_src;
@@ -375,7 +385,8 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
        }
 
        min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
-                       + GENEVE_BASE_HLEN + OVS_CB(skb)->tun_info->options_len
+                       + GENEVE_BASE_HLEN
+                       + OVS_CB(skb)->egress_tun_info->options_len
                        + sizeof(struct iphdr)
                        + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
 
@@ -402,7 +413,8 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
 
        skb_reset_inner_headers(skb);
 
-       __skb_push(skb, GENEVE_BASE_HLEN + OVS_CB(skb)->tun_info->options_len);
+       __skb_push(skb, GENEVE_BASE_HLEN +
+                       OVS_CB(skb)->egress_tun_info->options_len);
        skb_reset_transport_header(skb);
 
        geneve_build_header(vport, skb);
@@ -414,7 +426,7 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
 
        df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
 
-       sent_len = iptunnel_xmit(rt, skb,
+       sent_len = iptunnel_xmit(skb->sk, rt, skb,
                             saddr, tun_key->ipv4_dst,
                             IPPROTO_UDP, tun_key->ipv4_tos,
                             tun_key->ipv4_ttl,
@@ -434,11 +446,30 @@ static const char *geneve_get_name(const struct vport *vport)
        return geneve_port->name;
 }
 
+static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
+                                     struct ovs_tunnel_info *egress_tun_info)
+{
+       struct geneve_port *geneve_port = geneve_vport(vport);
+       struct net *net = ovs_dp_get_net(vport->dp);
+
+       /*
+        * Get tp_src and tp_dst, refert to geneve_build_header().
+        */
+       return ovs_tunnel_get_egress_info(egress_tun_info,
+                                         ovs_dp_get_net(vport->dp),
+                                         OVS_CB(skb)->egress_tun_info,
+                                         IPPROTO_UDP, skb->mark,
+                                         udp_flow_src_port(net, skb, 0, 0, true),
+                                         inet_sport(geneve_port->sock->sk));
+
+}
+
 const struct vport_ops ovs_geneve_vport_ops = {
-       .type           = OVS_VPORT_TYPE_GENEVE,
-       .create         = geneve_tnl_create,
-       .destroy        = geneve_tnl_destroy,
-       .get_name       = geneve_get_name,
-       .get_options    = geneve_get_options,
-       .send           = geneve_send,
+       .type                   = OVS_VPORT_TYPE_GENEVE,
+       .create                 = geneve_tnl_create,
+       .destroy                = geneve_tnl_destroy,
+       .get_name               = geneve_get_name,
+       .get_options            = geneve_get_options,
+       .send                   = geneve_send,
+       .get_egress_tun_info    = geneve_get_egress_tun_info,
 };