datapath: Remove kernel patch ports.
authorJesse Gross <jesse@nicira.com>
Fri, 25 Jan 2013 22:17:49 +0000 (14:17 -0800)
committerJesse Gross <jesse@nicira.com>
Mon, 28 Jan 2013 18:26:32 +0000 (10:26 -0800)
Now that userspace implements patch ports completely internally,
it's possible to remove the kernel implementation of them.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Kyle Mestery <kmestery@cisco.com>
datapath/Modules.mk
datapath/vport-patch.c [deleted file]
datapath/vport.c
datapath/vport.h
include/linux/openvswitch.h
lib/netdev-vport.c

index 281408b..54c6f13 100644 (file)
@@ -20,7 +20,6 @@ openvswitch_sources = \
        vport-gre.c \
        vport-internal_dev.c \
        vport-netdev.c \
-       vport-patch.c \
        vport-vxlan.c
 
 openvswitch_headers = \
diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c
deleted file mode 100644 (file)
index ca3a184..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2007-2012 Nicira, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- */
-
-#include <linux/kernel.h>
-#include <linux/jhash.h>
-#include <linux/list.h>
-#include <linux/rtnetlink.h>
-#include <net/net_namespace.h>
-
-#include "compat.h"
-#include "datapath.h"
-#include "vport.h"
-
-struct patch_config {
-       struct rcu_head rcu;
-
-       char peer_name[IFNAMSIZ];
-};
-
-struct patch_vport {
-       struct rcu_head rcu;
-
-       char name[IFNAMSIZ];
-
-       /* Protected by RTNL lock. */
-       struct hlist_node hash_node;
-
-       struct vport __rcu *peer;
-       struct patch_config __rcu *patchconf;
-};
-
-/* Protected by RTNL lock. */
-static struct hlist_head *peer_table;
-#define PEER_HASH_BUCKETS 256
-
-static void update_peers(struct net *, const char *name, struct vport *);
-
-static struct patch_vport *patch_vport_priv(const struct vport *vport)
-{
-       return vport_priv(vport);
-}
-
-/* RCU callback. */
-static void free_config(struct rcu_head *rcu)
-{
-       struct patch_config *c = container_of(rcu, struct patch_config, rcu);
-       kfree(c);
-}
-
-static void assign_config_rcu(struct vport *vport,
-                             struct patch_config *new_config)
-{
-       struct patch_vport *patch_vport = patch_vport_priv(vport);
-       struct patch_config *old_config;
-
-       old_config = rtnl_dereference(patch_vport->patchconf);
-       rcu_assign_pointer(patch_vport->patchconf, new_config);
-       call_rcu(&old_config->rcu, free_config);
-}
-
-static struct hlist_head *hash_bucket(struct net *net, const char *name)
-{
-       unsigned int hash = jhash(name, strlen(name), (unsigned long) net);
-       return &peer_table[hash & (PEER_HASH_BUCKETS - 1)];
-}
-
-static int patch_init(void)
-{
-       peer_table = kzalloc(PEER_HASH_BUCKETS * sizeof(struct hlist_head),
-                           GFP_KERNEL);
-       if (!peer_table)
-               return -ENOMEM;
-
-       return 0;
-}
-
-static void patch_exit(void)
-{
-       kfree(peer_table);
-}
-
-static const struct nla_policy patch_policy[OVS_PATCH_ATTR_MAX + 1] = {
-#ifdef HAVE_NLA_NUL_STRING
-       [OVS_PATCH_ATTR_PEER] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
-#endif
-};
-
-static int patch_set_config(struct vport *vport, const struct nlattr *options,
-                           struct patch_config *patchconf)
-{
-       struct patch_vport *patch_vport = patch_vport_priv(vport);
-       struct nlattr *a[OVS_PATCH_ATTR_MAX + 1];
-       const char *peer_name;
-       int err;
-
-       if (!options)
-               return -EINVAL;
-
-       err = nla_parse_nested(a, OVS_PATCH_ATTR_MAX, options, patch_policy);
-       if (err)
-               return err;
-
-       if (!a[OVS_PATCH_ATTR_PEER] ||
-           CHECK_NUL_STRING(a[OVS_PATCH_ATTR_PEER], IFNAMSIZ - 1))
-               return -EINVAL;
-
-       peer_name = nla_data(a[OVS_PATCH_ATTR_PEER]);
-       if (!strcmp(patch_vport->name, peer_name))
-               return -EINVAL;
-
-       strcpy(patchconf->peer_name, peer_name);
-
-       return 0;
-}
-
-static struct vport *patch_create(const struct vport_parms *parms)
-{
-       struct vport *vport;
-       struct patch_vport *patch_vport;
-       const char *peer_name;
-       struct patch_config *patchconf;
-       struct net *net = ovs_dp_get_net(parms->dp);
-       int err;
-
-       vport = ovs_vport_alloc(sizeof(struct patch_vport),
-                               &ovs_patch_vport_ops, parms);
-       if (IS_ERR(vport)) {
-               err = PTR_ERR(vport);
-               goto error;
-       }
-
-       patch_vport = patch_vport_priv(vport);
-
-       strcpy(patch_vport->name, parms->name);
-
-       patchconf = kmalloc(sizeof(struct patch_config), GFP_KERNEL);
-       if (!patchconf) {
-               err = -ENOMEM;
-               goto error_free_vport;
-       }
-
-       err = patch_set_config(vport, parms->options, patchconf);
-       if (err)
-               goto error_free_patchconf;
-
-       rcu_assign_pointer(patch_vport->patchconf, patchconf);
-
-       peer_name = patchconf->peer_name;
-       hlist_add_head(&patch_vport->hash_node, hash_bucket(net, peer_name));
-       rcu_assign_pointer(patch_vport->peer, ovs_vport_locate(net, peer_name));
-       update_peers(net, patch_vport->name, vport);
-
-       return vport;
-
-error_free_patchconf:
-       kfree(patchconf);
-error_free_vport:
-       ovs_vport_free(vport);
-error:
-       return ERR_PTR(err);
-}
-
-static void free_port_rcu(struct rcu_head *rcu)
-{
-       struct patch_vport *patch_vport = container_of(rcu,
-                                         struct patch_vport, rcu);
-
-       kfree((struct patch_config __force *)patch_vport->patchconf);
-       ovs_vport_free(vport_from_priv(patch_vport));
-}
-
-static void patch_destroy(struct vport *vport)
-{
-       struct patch_vport *patch_vport = patch_vport_priv(vport);
-
-       update_peers(ovs_dp_get_net(vport->dp), patch_vport->name, NULL);
-       hlist_del(&patch_vport->hash_node);
-       call_rcu(&patch_vport->rcu, free_port_rcu);
-}
-
-static int patch_set_options(struct vport *vport, struct nlattr *options)
-{
-       struct patch_vport *patch_vport = patch_vport_priv(vport);
-       struct patch_config *patchconf;
-       int err;
-
-       patchconf = kmemdup(rtnl_dereference(patch_vport->patchconf),
-                         sizeof(struct patch_config), GFP_KERNEL);
-       if (!patchconf) {
-               err = -ENOMEM;
-               goto error;
-       }
-
-       err = patch_set_config(vport, options, patchconf);
-       if (err)
-               goto error_free;
-
-       assign_config_rcu(vport, patchconf);
-
-       hlist_del(&patch_vport->hash_node);
-
-       rcu_assign_pointer(patch_vport->peer,
-               ovs_vport_locate(ovs_dp_get_net(vport->dp), patchconf->peer_name));
-
-       hlist_add_head(&patch_vport->hash_node,
-                      hash_bucket(ovs_dp_get_net(vport->dp), patchconf->peer_name));
-
-       return 0;
-error_free:
-       kfree(patchconf);
-error:
-       return err;
-}
-
-static void update_peers(struct net *net, const char *name, struct vport *vport)
-{
-       struct hlist_head *bucket = hash_bucket(net, name);
-       struct patch_vport *peer_vport;
-       struct hlist_node *node;
-
-       hlist_for_each_entry(peer_vport, node, bucket, hash_node) {
-               struct vport *curr_vport = vport_from_priv(peer_vport);
-               const char *peer_name;
-
-               peer_name = rtnl_dereference(peer_vport->patchconf)->peer_name;
-               if (!strcmp(peer_name, name) && net_eq(ovs_dp_get_net(curr_vport->dp), net))
-                       rcu_assign_pointer(peer_vport->peer, vport);
-       }
-}
-
-static const char *patch_get_name(const struct vport *vport)
-{
-       const struct patch_vport *patch_vport = patch_vport_priv(vport);
-       return patch_vport->name;
-}
-
-static int patch_get_options(const struct vport *vport, struct sk_buff *skb)
-{
-       struct patch_vport *patch_vport = patch_vport_priv(vport);
-       struct patch_config *patchconf = rcu_dereference_rtnl(patch_vport->patchconf);
-
-       return nla_put_string(skb, OVS_PATCH_ATTR_PEER, patchconf->peer_name);
-}
-
-static int patch_send(struct vport *vport, struct sk_buff *skb)
-{
-       struct patch_vport *patch_vport = patch_vport_priv(vport);
-       struct vport *peer = rcu_dereference(patch_vport->peer);
-       int skb_len = skb->len;
-
-       if (!peer) {
-               kfree_skb(skb);
-               ovs_vport_record_error(vport, VPORT_E_TX_DROPPED);
-
-               return 0;
-       }
-
-       ovs_vport_receive(peer, skb);
-       return skb_len;
-}
-
-const struct vport_ops ovs_patch_vport_ops = {
-       .type           = OVS_VPORT_TYPE_PATCH,
-       .init           = patch_init,
-       .exit           = patch_exit,
-       .create         = patch_create,
-       .destroy        = patch_destroy,
-       .get_name       = patch_get_name,
-       .get_options    = patch_get_options,
-       .set_options    = patch_set_options,
-       .send           = patch_send,
-};
index eb87c99..9c0942b 100644 (file)
@@ -39,7 +39,6 @@
 static const struct vport_ops *base_vport_ops_list[] = {
        &ovs_netdev_vport_ops,
        &ovs_internal_vport_ops,
-       &ovs_patch_vport_ops,
        &ovs_gre_vport_ops,
        &ovs_gre64_vport_ops,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
index e4de41d..ed089a9 100644 (file)
@@ -228,7 +228,6 @@ void ovs_vport_record_error(struct vport *, enum vport_err_type err_type);
  * add yours to the list at the top of vport.c. */
 extern const struct vport_ops ovs_netdev_vport_ops;
 extern const struct vport_ops ovs_internal_vport_ops;
-extern const struct vport_ops ovs_patch_vport_ops;
 extern const struct vport_ops ovs_gre_vport_ops;
 extern const struct vport_ops ovs_gre64_vport_ops;
 extern const struct vport_ops ovs_capwap_vport_ops;
index 5ad0bc0..b12bf0c 100644 (file)
@@ -184,7 +184,6 @@ enum ovs_vport_type {
        OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */
        OVS_VPORT_TYPE_GRE,      /* GRE tunnel. */
        OVS_VPORT_TYPE_VXLAN,    /* VXLAN tunnel */
-       OVS_VPORT_TYPE_PATCH = 100, /* virtual tunnel connecting two vports */
        OVS_VPORT_TYPE_CAPWAP = 102,  /* CAPWAP tunnel */
        OVS_VPORT_TYPE_GRE64 = 104, /* GRE tunnel with 64-bit keys */
        __OVS_VPORT_TYPE_MAX
index 98ef186..94f1110 100644 (file)
@@ -78,6 +78,7 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
 
 static int netdev_vport_create(const struct netdev_class *, const char *,
                                struct netdev_dev **);
+static int get_patch_config(struct netdev_dev *, struct smap *args);
 static void netdev_vport_poll_notify(const struct netdev *);
 static int tnl_port_config_from_nlattr(const struct nlattr *options,
                                        size_t options_len,
@@ -144,7 +145,10 @@ netdev_vport_get_vport_type(const struct netdev *netdev)
 bool
 netdev_vport_is_patch(const struct netdev *netdev)
 {
-    return netdev_vport_get_vport_type(netdev) == OVS_VPORT_TYPE_PATCH;
+    const struct netdev_dev *dev = netdev_get_dev(netdev);
+    const struct netdev_class *class = netdev_dev_get_class(dev);
+
+    return class->get_config == get_patch_config; 
 }
 
 static uint32_t
@@ -168,9 +172,6 @@ netdev_vport_get_netdev_type(const struct dpif_linux_vport *vport)
     case OVS_VPORT_TYPE_INTERNAL:
         return "internal";
 
-    case OVS_VPORT_TYPE_PATCH:
-        return "patch";
-
     case OVS_VPORT_TYPE_GRE:
         if (tnl_port_config_from_nlattr(vport->options, vport->options_len,
                                         a)) {
@@ -915,7 +916,7 @@ netdev_vport_register(void)
         TUNNEL_CLASS("capwap", OVS_VPORT_TYPE_CAPWAP),
         TUNNEL_CLASS("vxlan", OVS_VPORT_TYPE_VXLAN),
 
-        { OVS_VPORT_TYPE_PATCH,
+        { OVS_VPORT_TYPE_UNSPEC,
           { "patch", VPORT_FUNCTIONS(get_patch_config,
                                      set_patch_config,
                                      NULL,