dpif-netlink: add GENEVE creation support
[cascardo/ovs.git] / datapath / vport.c
index 1e22c6d..44b9dfb 100644 (file)
@@ -33,8 +33,9 @@
 #include <net/lisp.h>
 #include <net/gre.h>
 #include <net/geneve.h>
-#include <net/vxlan.h>
+#include <net/route.h>
 #include <net/stt.h>
+#include <net/vxlan.h>
 
 #include "datapath.h"
 #include "gso.h"
@@ -113,7 +114,7 @@ static struct hlist_head *hash_bucket(const struct net *net, const char *name)
        return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)];
 }
 
-int ovs_vport_ops_register(struct vport_ops *ops)
+int __ovs_vport_ops_register(struct vport_ops *ops)
 {
        int err = -EEXIST;
        struct vport_ops *o;
@@ -129,7 +130,7 @@ errout:
        ovs_unlock();
        return err;
 }
-EXPORT_SYMBOL_GPL(ovs_vport_ops_register);
+EXPORT_SYMBOL_GPL(__ovs_vport_ops_register);
 
 void ovs_vport_ops_unregister(struct vport_ops *ops)
 {
@@ -298,8 +299,8 @@ int ovs_vport_set_options(struct vport *vport, struct nlattr *options)
  *
  * @vport: vport to delete.
  *
- * Detaches @vport from its datapath and destroys it.  It is possible to fail
- * for reasons such as lack of memory.  ovs_mutex must be held.
+ * Detaches @vport from its datapath and destroys it.  ovs_mutex must be
+ * held.
  */
 void ovs_vport_del(struct vport *vport)
 {
@@ -375,14 +376,6 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
        return 0;
 }
 
-static void vport_portids_destroy_rcu_cb(struct rcu_head *rcu)
-{
-       struct vport_portids *ids = container_of(rcu, struct vport_portids,
-                                                rcu);
-
-       kfree(ids);
-}
-
 /**
  *     ovs_vport_set_upcall_portids - set upcall portids of @vport.
  *
@@ -417,7 +410,7 @@ int ovs_vport_set_upcall_portids(struct vport *vport, const struct nlattr *ids)
        rcu_assign_pointer(vport->upcall_portids, vport_portids);
 
        if (old)
-               call_rcu(&old->rcu, vport_portids_destroy_rcu_cb);
+               kfree_rcu(old, rcu);
        return 0;
 }
 
@@ -493,6 +486,16 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
        int error;
 
        OVS_CB(skb)->input_vport = vport;
+       OVS_CB(skb)->mru = 0;
+       if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
+               u32 mark;
+
+               mark = skb->mark;
+               skb_scrub_packet(skb, true);
+               skb->mark = mark;
+               tun_info = NULL;
+       }
+
        ovs_skb_init_inner_protocol(skb);
        skb_clear_ovs_gso_cb(skb);
        /* Extract flow from 'skb' into 'key'. */
@@ -522,6 +525,25 @@ void ovs_vport_deferred_free(struct vport *vport)
 }
 EXPORT_SYMBOL_GPL(ovs_vport_deferred_free);
 
+static struct rtable *ovs_tunnel_route_lookup(struct net *net,
+                                             const struct ip_tunnel_key *key,
+                                             u32 mark,
+                                             struct flowi4 *fl,
+                                             u8 protocol)
+{
+       struct rtable *rt;
+
+       memset(fl, 0, sizeof(*fl));
+       fl->daddr = key->u.ipv4.dst;
+       fl->saddr = key->u.ipv4.src;
+       fl->flowi4_tos = RT_TOS(key->tos);
+       fl->flowi4_mark = mark;
+       fl->flowi4_proto = protocol;
+
+       rt = ip_route_output_key(net, fl);
+       return rt;
+}
+
 int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
                               struct net *net,
                               struct sk_buff *skb,