datapath: Change dp_idx to dp_ifindex, the ifindex of the local port.
authorBen Pfaff <blp@nicira.com>
Sat, 22 Jan 2011 01:01:56 +0000 (17:01 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 28 Jan 2011 23:34:40 +0000 (15:34 -0800)
I can't see any real value in maintaining a dp_idx separate from the
ifindex of the local port.  With the current implementation it also
artificially limits the number of datapaths.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
datapath/datapath.c
datapath/datapath.h
datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
include/openvswitch/datapath-protocol.h
lib/automake.mk
lib/dpif-linux.c
lib/dpif-linux.h
lib/dpif.man [deleted file]
lib/netdev-vport.c
utilities/ovs-dpctl.8.in
utilities/ovs-openflowd.8.in

index 8931456..dee1b0f 100644 (file)
@@ -73,20 +73,29 @@ EXPORT_SYMBOL(dp_ioctl_hook);
  * each other.
  */
 
-/* Protected by genl_mutex. */
-static struct datapath __rcu *dps[256];
+/* Global list of datapaths to enable dumping them all out.
+ * Protected by genl_mutex.
+ */
+static LIST_HEAD(dps);
 
 static struct vport *new_vport(const struct vport_parms *);
 
 /* Must be called with rcu_read_lock, genl_mutex, or RTNL lock. */
-struct datapath *get_dp(int dp_idx)
+struct datapath *get_dp(int dp_ifindex)
 {
-       if (dp_idx < 0 || dp_idx >= ARRAY_SIZE(dps))
-               return NULL;
+       struct datapath *dp = NULL;
+       struct net_device *dev;
 
-       return rcu_dereference_check(dps[dp_idx], rcu_read_lock_held() ||
-                                        lockdep_rtnl_is_held() ||
-                                        lockdep_genl_is_held());
+       rcu_read_lock();
+       dev = dev_get_by_index_rcu(&init_net, dp_ifindex);
+       if (dev) {
+               struct vport *vport = internal_dev_get_vport(dev);
+               if (vport)
+                       dp = vport->dp;
+       }
+       rcu_read_unlock();
+
+       return dp;
 }
 EXPORT_SYMBOL_GPL(get_dp);
 
@@ -362,7 +371,7 @@ static struct genl_family dp_packet_genl_family;
 static int packet_mc_group(struct datapath *dp, u8 cmd)
 {
        BUILD_BUG_ON_NOT_POWER_OF_2(PACKET_N_MC_GROUPS);
-       return jhash_2words(dp->dp_idx, cmd, 0) & (PACKET_N_MC_GROUPS - 1);
+       return jhash_2words(dp->dp_ifindex, cmd, 0) & (PACKET_N_MC_GROUPS - 1);
 }
 
 /* Send each packet in the 'skb' list to userspace for 'dp' as directed by
@@ -409,7 +418,7 @@ static int queue_control_packets(struct datapath *dp, struct sk_buff *skb,
                }
 
                upcall = genlmsg_put(user_skb, 0, 0, &dp_packet_genl_family, 0, upcall_info->cmd);
-               upcall->dp_idx = dp->dp_idx;
+               upcall->dp_ifindex = dp->dp_ifindex;
 
                nla = nla_nest_start(user_skb, ODP_PACKET_ATTR_KEY);
                flow_to_nlattrs(upcall_info->key, user_skb);
@@ -533,13 +542,13 @@ err:
 }
 
 /* Called with genl_mutex. */
-static int flush_flows(int dp_idx)
+static int flush_flows(int dp_ifindex)
 {
        struct tbl *old_table;
        struct tbl *new_table;
        struct datapath *dp;
 
-       dp = get_dp(dp_idx);
+       dp = get_dp(dp_ifindex);
        if (!dp)
                return -ENODEV;
 
@@ -694,7 +703,7 @@ static int odp_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
                goto exit;
 
        rcu_read_lock();
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        err = -ENODEV;
        if (dp)
                err = execute_actions(dp, packet, &key,
@@ -826,7 +835,7 @@ static int odp_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
        if (!odp_header)
                return -EMSGSIZE;
 
-       odp_header->dp_idx = dp->dp_idx;
+       odp_header->dp_ifindex = dp->dp_ifindex;
 
        nla = nla_nest_start(skb, ODP_FLOW_ATTR_KEY);
        if (!nla)
@@ -941,7 +950,7 @@ static int odp_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                goto error;
        }
 
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        error = -ENODEV;
        if (!dp)
                goto error;
@@ -1065,7 +1074,7 @@ static int odp_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
        if (err)
                return err;
 
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
@@ -1095,12 +1104,12 @@ static int odp_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
        int err;
 
        if (!a[ODP_FLOW_ATTR_KEY])
-               return flush_flows(odp_header->dp_idx);
+               return flush_flows(odp_header->dp_ifindex);
        err = flow_from_nlattrs(&key, a[ODP_FLOW_ATTR_KEY]);
        if (err)
                return err;
 
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
@@ -1136,7 +1145,7 @@ static int odp_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
        struct odp_header *odp_header = genlmsg_data(nlmsg_data(cb->nlh));
        struct datapath *dp;
 
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
@@ -1219,7 +1228,7 @@ static int odp_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
        if (!odp_header)
                goto error;
 
-       odp_header->dp_idx = dp->dp_idx;
+       odp_header->dp_ifindex = dp->dp_ifindex;
 
        rcu_read_lock();
        err = nla_put_string(skb, ODP_DP_ATTR_NAME, dp_name(dp));
@@ -1287,24 +1296,19 @@ static int odp_dp_cmd_validate(struct nlattr *a[ODP_DP_ATTR_MAX + 1])
 /* Called with genl_mutex and optionally with RTNL lock also. */
 static struct datapath *lookup_datapath(struct odp_header *odp_header, struct nlattr *a[ODP_DP_ATTR_MAX + 1])
 {
-       if (!a[ODP_DP_ATTR_NAME]) {
-               struct datapath *dp = get_dp(odp_header->dp_idx);
-               if (!dp)
-                       return ERR_PTR(-ENODEV);
-               return dp;
-       } else {
+       struct datapath *dp;
+
+       if (!a[ODP_DP_ATTR_NAME])
+               dp = get_dp(odp_header->dp_ifindex);
+       else {
                struct vport *vport;
-               int dp_idx;
 
                rcu_read_lock();
                vport = vport_locate(nla_data(a[ODP_DP_ATTR_NAME]));
-               dp_idx = vport && vport->port_no == ODPP_LOCAL ? vport->dp->dp_idx : -1;
+               dp = vport && vport->port_no == ODPP_LOCAL ? vport->dp : NULL;
                rcu_read_unlock();
-
-               if (dp_idx < 0)
-                       return ERR_PTR(-ENODEV);
-               return vport->dp;
        }
+       return dp ? dp : ERR_PTR(-ENODEV);
 }
 
 /* Called with genl_mutex. */
@@ -1319,12 +1323,10 @@ static void change_datapath(struct datapath *dp, struct nlattr *a[ODP_DP_ATTR_MA
 static int odp_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 {
        struct nlattr **a = info->attrs;
-       struct odp_header *odp_header = info->userhdr;
        struct vport_parms parms;
        struct sk_buff *reply;
        struct datapath *dp;
        struct vport *vport;
-       int dp_idx;
        int err;
 
        err = -EINVAL;
@@ -1340,28 +1342,11 @@ static int odp_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
        if (!try_module_get(THIS_MODULE))
                goto err_unlock_rtnl;
 
-       dp_idx = odp_header->dp_idx;
-       if (dp_idx < 0) {
-               err = -EFBIG;
-               for (dp_idx = 0; dp_idx < ARRAY_SIZE(dps); dp_idx++) {
-                       if (get_dp(dp_idx))
-                               continue;
-                       err = 0;
-                       break;
-               }
-       } else if (dp_idx < ARRAY_SIZE(dps))
-               err = get_dp(dp_idx) ? -EBUSY : 0;
-       else
-               err = -EINVAL;
-       if (err)
-               goto err_put_module;
-
        err = -ENOMEM;
        dp = kzalloc(sizeof(*dp), GFP_KERNEL);
        if (dp == NULL)
                goto err_put_module;
        INIT_LIST_HEAD(&dp->port_list);
-       dp->dp_idx = dp_idx;
 
        /* Initialize kobject for bridge.  This will be added as
         * /sys/class/net/<devname>/brif later, if sysfs is enabled. */
@@ -1388,6 +1373,7 @@ static int odp_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 
                goto err_destroy_table;
        }
+       dp->dp_ifindex = vport_get_ifindex(vport);
 
        dp->drop_frags = 0;
        dp->stats_percpu = alloc_percpu(struct dp_stats_percpu);
@@ -1403,7 +1389,7 @@ static int odp_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
        if (IS_ERR(reply))
                goto err_destroy_local_port;
 
-       rcu_assign_pointer(dps[dp_idx], dp);
+       list_add_tail(&dp->list_node, &dps);
        dp_sysfs_add_dp(dp);
 
        rtnl_unlock();
@@ -1453,7 +1439,7 @@ static int odp_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
                        dp_detach_port(vport);
 
        dp_sysfs_del_dp(dp);
-       rcu_assign_pointer(dps[dp->dp_idx], NULL);
+       list_del(&dp->list_node);
        dp_detach_port(get_vport_protected(dp, ODPP_LOCAL));
 
        call_rcu(&dp->rcu, destroy_dp_rcu);
@@ -1521,19 +1507,22 @@ static int odp_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
 
 static int odp_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
-       u32 dp_idx;
+       struct datapath *dp;
+       int skip = cb->args[0];
+       int i = 0;
 
-       for (dp_idx = cb->args[0]; dp_idx < ARRAY_SIZE(dps); dp_idx++) {
-               struct datapath *dp = get_dp(dp_idx);
-               if (!dp)
+       list_for_each_entry (dp, &dps, list_node) {
+               if (i < skip)
                        continue;
                if (odp_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).pid,
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                         ODP_DP_CMD_NEW) < 0)
                        break;
+               i++;
        }
 
-       cb->args[0] = dp_idx;
+       cb->args[0] = i;
+
        return skb->len;
 }
 
@@ -1602,7 +1591,7 @@ static int odp_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
        if (!odp_header)
                return -EMSGSIZE;
 
-       odp_header->dp_idx = vport->dp->dp_idx;
+       odp_header->dp_ifindex = vport->dp->dp_ifindex;
 
        NLA_PUT_U32(skb, ODP_VPORT_ATTR_PORT_NO, vport->port_no);
        NLA_PUT_U32(skb, ODP_VPORT_ATTR_TYPE, vport_get_type(vport));
@@ -1681,7 +1670,7 @@ static struct vport *lookup_vport(struct odp_header *odp_header,
                if (port_no >= DP_MAX_PORTS)
                        return ERR_PTR(-EFBIG);
 
-               dp = get_dp(odp_header->dp_idx);
+               dp = get_dp(odp_header->dp_ifindex);
                if (!dp)
                        return ERR_PTR(-ENODEV);
 
@@ -1726,7 +1715,7 @@ static int odp_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
                goto exit;
 
        rtnl_lock();
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        err = -ENODEV;
        if (!dp)
                goto exit_unlock;
@@ -1908,7 +1897,7 @@ static int odp_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
        u32 port_no;
        int retval;
 
-       dp = get_dp(odp_header->dp_idx);
+       dp = get_dp(odp_header->dp_ifindex);
        if (!dp)
                return -ENODEV;
 
index 176282b..befa55c 100644 (file)
@@ -56,7 +56,8 @@ struct dp_stats_percpu {
 /**
  * struct datapath - datapath for flow-based packet switching
  * @rcu: RCU callback head for deferred destruction.
- * @dp_idx: Datapath number (index into the dps[] array in datapath.c).
+ * @dp_ifindex: ifindex of local port.
+ * @list_node: Element in global 'dps' list.
  * @ifobj: Represents /sys/class/net/<devname>/brif.  Protected by RTNL.
  * @drop_frags: Drop all IP fragments if nonzero.
  * @n_flows: Number of flows currently in flow table.
@@ -75,7 +76,8 @@ struct dp_stats_percpu {
  */
 struct datapath {
        struct rcu_head rcu;
-       int dp_idx;
+       int dp_ifindex;
+       struct list_head list_node;
        struct kobject ifobj;
 
        int drop_frags;
index 3856bb6..d44312f 100644 (file)
@@ -121,6 +121,20 @@ static inline void netdev_rx_handler_unregister(struct net_device *dev)
 #define dev_get_by_index(net, ifindex) dev_get_by_index(ifindex)
 #define __dev_get_by_name(net, name) __dev_get_by_name(name)
 #define __dev_get_by_index(net, ifindex) __dev_get_by_index(ifindex)
+#define dev_get_by_index_rcu(net, ifindex) dev_get_by_index_rcu(ifindex)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
+static inline struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
+{
+       struct net_device *dev;
+
+       read_lock(&dev_base_lock);
+       dev = __dev_get_by_index(net, ifindex);
+       read_unlock(&dev_base_lock);
+
+       return dev;
+}
 #endif
 
 #endif
index 1ba43c5..083800c 100644 (file)
@@ -70,7 +70,7 @@
 #include <linux/if_link.h>
 #include <linux/netlink.h>
 \f
-/* Datapaths. */
+/* datapaths. */
 
 #define ODP_DATAPATH_FAMILY  "odp_datapath"
 #define ODP_DATAPATH_MCGROUP "odp_datapath"
@@ -85,22 +85,23 @@ enum odp_datapath_cmd {
 
 /**
  * struct odp_header - header for ODP Generic Netlink messages.
- * @dp_idx: Number of datapath to which the packet belongs.
+ * @dp_ifindex: ifindex of local port for datapath (0 to make a request not
+ * specific to a datapath).
  *
  * Attributes following the header are specific to a particular ODP Generic
  * Netlink family, but all of the ODP families use this header.
  */
 struct odp_header {
-       uint32_t dp_idx;
+       int dp_ifindex;
 };
 \f
 /**
  * enum odp_datapath_attr - attributes for %ODP_DP_* commands.
  * @ODP_DP_ATTR_NAME: Name of the network device that serves as the "local
- * port".  This is the name of the network device whose dp_idx is given in the
- * &struct odp_header.  Always present in notifications.  Required in
- * %ODP_DP_NEW requests.  May be used as an alternative to specifying dp_idx on
- * other requests (with a dp_idx of %UINT32_MAX).
+ * port".  This is the name of the network device whose dp_ifindex is given in
+ * the &struct odp_header.  Always present in notifications.  Required in
+ * %ODP_DP_NEW requests.  May be used as an alternative to specifying
+ * dp_ifindex in other requests (with a dp_ifindex of 0).
  * @ODP_DP_ATTR_STATS: Statistics about packets that have passed through the
  * datapath.  Always present in notifications.
  * @ODP_DP_ATTR_IPV4_FRAGS: One of %ODP_DP_FRAG_*.  Always present in
@@ -120,7 +121,7 @@ struct odp_header {
  */
 enum odp_datapath_attr {
        ODP_DP_ATTR_UNSPEC,
-       ODP_DP_ATTR_NAME,       /* name of dp_ifidx netdev */
+       ODP_DP_ATTR_NAME,       /* name of dp_ifindex netdev */
        ODP_DP_ATTR_STATS,      /* struct odp_stats */
        ODP_DP_ATTR_IPV4_FRAGS, /* 32-bit enum odp_frag_handling */
        ODP_DP_ATTR_SAMPLING,   /* 32-bit fraction of packets to sample. */
index ba02d41..c51d3ed 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2010 Nicira Networks, Inc.
+# Copyright (C) 2009, 2010, 2011 Nicira Networks, Inc.
 #
 # Copying and distribution of this file, with or without modification,
 # are permitted in any medium without royalty provided the copyright
@@ -222,7 +222,6 @@ EXTRA_DIST += \
        lib/common-syn.man \
        lib/daemon.man \
        lib/daemon-syn.man \
-       lib/dpif.man \
        lib/leak-checker.man \
        lib/ssl-bootstrap.man \
        lib/ssl-bootstrap-syn.man \
index 01377bd..dc59fe0 100644 (file)
@@ -57,7 +57,7 @@ struct dpif_linux_dp {
     uint8_t cmd;
 
     /* struct odp_header. */
-    uint32_t dp_idx;
+    int dp_ifindex;
 
     /* Attributes. */
     const char *name;                  /* ODP_DP_ATTR_NAME. */
@@ -83,7 +83,7 @@ struct dpif_linux_flow {
 
     /* struct odp_header. */
     unsigned int nlmsg_flags;
-    uint32_t dp_idx;
+    int dp_ifindex;
 
     /* Attributes.
      *
@@ -114,18 +114,14 @@ static void dpif_linux_flow_get_stats(const struct dpif_linux_flow *,
 /* Datapath interface for the openvswitch Linux kernel module. */
 struct dpif_linux {
     struct dpif dpif;
+    int dp_ifindex;
 
     /* Multicast group messages. */
     struct nl_sock *mc_sock;
     uint32_t mcgroups[DPIF_N_UC_TYPES];
     unsigned int listen_mask;
 
-    /* Used by dpif_linux_get_all_names(). */
-    char *local_ifname;
-    int dp_idx;
-
     /* Change notification. */
-    int local_ifindex;          /* Ifindex of local port. */
     struct shash changed_ports;  /* Ports that have changed. */
     struct rtnetlink_notifier port_notifier;
     bool change_error;
@@ -143,9 +139,7 @@ static int odp_packet_family;
 static struct nl_sock *genl_sock;
 
 static int dpif_linux_init(void);
-static int open_dpif(const struct dpif_linux_dp *,
-                     const struct dpif_linux_vport *local_vport,
-                     struct dpif **);
+static int open_dpif(const struct dpif_linux_dp *, struct dpif **);
 static void dpif_linux_port_changed(const struct rtnetlink_link_change *,
                                     void *dpif);
 
@@ -188,10 +182,8 @@ static int
 dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name,
                 bool create, struct dpif **dpifp)
 {
-    struct dpif_linux_vport vport_request, vport;
     struct dpif_linux_dp dp_request, dp;
     struct ofpbuf *buf;
-    int dp_idx;
     int error;
 
     error = dpif_linux_init();
@@ -199,47 +191,23 @@ dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name,
         return error;
     }
 
-    dp_idx = (!strncmp(name, "dp", 2)
-              && isdigit((unsigned char)name[2]) ? atoi(name + 2) : -1);
-
     /* Create or look up datapath. */
     dpif_linux_dp_init(&dp_request);
     dp_request.cmd = create ? ODP_DP_CMD_NEW : ODP_DP_CMD_GET;
-    dp_request.dp_idx = dp_idx;
-    dp_request.name = dp_idx < 0 ? name : NULL;
+    dp_request.name = name;
     error = dpif_linux_dp_transact(&dp_request, &dp, &buf);
     if (error) {
         return error;
     }
-    ofpbuf_delete(buf);         /* Pointers inside 'dp' are now invalid! */
-
-    /* Look up local port. */
-    dpif_linux_vport_init(&vport_request);
-    vport_request.cmd = ODP_VPORT_CMD_GET;
-    vport_request.dp_idx = dp.dp_idx;
-    vport_request.port_no = ODPP_LOCAL;
-    vport_request.name = dp_idx < 0 ? name : NULL;
-    error = dpif_linux_vport_transact(&vport_request, &vport, &buf);
-    if (error) {
-        return error;
-    } else if (vport.port_no != ODPP_LOCAL) {
-        /* This is an Open vSwitch device but not the local port.  We
-         * intentionally support only using the name of the local port as the
-         * name of a datapath; otherwise, it would be too difficult to
-         * enumerate all the names of a datapath. */
-        error = EOPNOTSUPP;
-    } else {
-        error = open_dpif(&dp, &vport, dpifp);
-    }
+    error = open_dpif(&dp, dpifp);
     ofpbuf_delete(buf);
+
     return error;
 }
 
 static int
-open_dpif(const struct dpif_linux_dp *dp,
-          const struct dpif_linux_vport *local_vport, struct dpif **dpifp)
+open_dpif(const struct dpif_linux_dp *dp, struct dpif **dpifp)
 {
-    int dp_idx = local_vport->dp_idx;
     struct dpif_linux *dpif;
     char *name;
     int error;
@@ -252,8 +220,8 @@ open_dpif(const struct dpif_linux_dp *dp,
         goto error_free;
     }
 
-    name = xasprintf("dp%d", dp_idx);
-    dpif_init(&dpif->dpif, &dpif_linux_class, name, dp_idx, dp_idx);
+    dpif_init(&dpif->dpif, &dpif_linux_class, dp->name,
+              dp->dp_ifindex, dp->dp_ifindex);
     free(name);
 
     dpif->mc_sock = NULL;
@@ -261,9 +229,7 @@ open_dpif(const struct dpif_linux_dp *dp,
         dpif->mcgroups[i] = dp->mcgroups[i];
     }
     dpif->listen_mask = 0;
-    dpif->local_ifname = xstrdup(local_vport->name);
-    dpif->local_ifindex = local_vport->ifindex;
-    dpif->dp_idx = dp_idx;
+    dpif->dp_ifindex = dp->dp_ifindex;
     shash_init(&dpif->changed_ports);
     dpif->change_error = false;
     *dpifp = &dpif->dpif;
@@ -281,20 +247,9 @@ dpif_linux_close(struct dpif *dpif_)
     struct dpif_linux *dpif = dpif_linux_cast(dpif_);
     rtnetlink_link_notifier_unregister(&dpif->port_notifier);
     shash_destroy(&dpif->changed_ports);
-    free(dpif->local_ifname);
     free(dpif);
 }
 
-static int
-dpif_linux_get_all_names(const struct dpif *dpif_, struct svec *all_names)
-{
-    struct dpif_linux *dpif = dpif_linux_cast(dpif_);
-
-    svec_add_nocopy(all_names, xasprintf("dp%d", dpif->dp_idx));
-    svec_add(all_names, dpif->local_ifname);
-    return 0;
-}
-
 static int
 dpif_linux_destroy(struct dpif *dpif_)
 {
@@ -303,7 +258,7 @@ dpif_linux_destroy(struct dpif *dpif_)
 
     dpif_linux_dp_init(&dp);
     dp.cmd = ODP_DP_CMD_DEL;
-    dp.dp_idx = dpif->dp_idx;
+    dp.dp_ifindex = dpif->dp_ifindex;
     return dpif_linux_dp_transact(&dp, NULL, NULL);
 }
 
@@ -345,7 +300,7 @@ dpif_linux_set_drop_frags(struct dpif *dpif_, bool drop_frags)
 
     dpif_linux_dp_init(&dp);
     dp.cmd = ODP_DP_CMD_SET;
-    dp.dp_idx = dpif->dp_idx;
+    dp.dp_ifindex = dpif->dp_ifindex;
     dp.ipv4_frags = drop_frags ? ODP_DP_FRAG_DROP : ODP_DP_FRAG_ZERO;
     return dpif_linux_dp_transact(&dp, NULL, NULL);
 }
@@ -364,7 +319,7 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
 
     dpif_linux_vport_init(&request);
     request.cmd = ODP_VPORT_CMD_NEW;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
     request.type = netdev_vport_get_vport_type(netdev);
     if (request.type == ODP_VPORT_TYPE_UNSPEC) {
         VLOG_WARN_RL(&error_rl, "%s: cannot create port `%s' because it has "
@@ -397,7 +352,7 @@ dpif_linux_port_del(struct dpif *dpif_, uint16_t port_no)
 
     dpif_linux_vport_init(&vport);
     vport.cmd = ODP_VPORT_CMD_DEL;
-    vport.dp_idx = dpif->dp_idx;
+    vport.dp_ifindex = dpif->dp_ifindex;
     vport.port_no = port_no;
     return dpif_linux_vport_transact(&vport, NULL, NULL);
 }
@@ -413,7 +368,7 @@ dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no,
 
     dpif_linux_vport_init(&request);
     request.cmd = ODP_VPORT_CMD_GET;
-    request.dp_idx = dpif_linux_cast(dpif)->dp_idx;
+    request.dp_ifindex = dpif_linux_cast(dpif)->dp_ifindex;
     request.port_no = port_no;
     request.name = port_name;
 
@@ -457,7 +412,7 @@ dpif_linux_flow_flush(struct dpif *dpif_)
 
     dpif_linux_flow_init(&flow);
     flow.cmd = ODP_FLOW_CMD_DEL;
-    flow.dp_idx = dpif->dp_idx;
+    flow.dp_ifindex = dpif->dp_ifindex;
     return dpif_linux_flow_transact(&flow, NULL, NULL);
 }
 
@@ -477,7 +432,7 @@ dpif_linux_port_dump_start(const struct dpif *dpif_, void **statep)
 
     dpif_linux_vport_init(&request);
     request.cmd = ODP_DP_CMD_GET;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
 
     buf = ofpbuf_new(1024);
     dpif_linux_vport_to_ofpbuf(&request, buf);
@@ -561,7 +516,7 @@ dpif_linux_flow_get(const struct dpif *dpif_,
 
     dpif_linux_flow_init(&request);
     request.cmd = ODP_FLOW_CMD_GET;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
     request.key = key;
     request.key_len = key_len;
     error = dpif_linux_flow_transact(&request, &reply, &buf);
@@ -593,7 +548,7 @@ dpif_linux_flow_put(struct dpif *dpif_, enum dpif_flow_put_flags flags,
 
     dpif_linux_flow_init(&request);
     request.cmd = flags & DPIF_FP_CREATE ? ODP_FLOW_CMD_NEW : ODP_FLOW_CMD_SET;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
     request.key = key;
     request.key_len = key_len;
     request.actions = actions;
@@ -624,7 +579,7 @@ dpif_linux_flow_del(struct dpif *dpif_,
 
     dpif_linux_flow_init(&request);
     request.cmd = ODP_FLOW_CMD_DEL;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
     request.key = key;
     request.key_len = key_len;
     error = dpif_linux_flow_transact(&request,
@@ -655,7 +610,7 @@ dpif_linux_flow_dump_start(const struct dpif *dpif_, void **statep)
 
     dpif_linux_flow_init(&request);
     request.cmd = ODP_DP_CMD_GET;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
 
     buf = ofpbuf_new(1024);
     dpif_linux_flow_to_ofpbuf(&request, buf);
@@ -722,7 +677,7 @@ dpif_linux_execute(struct dpif *dpif_,
                           ODP_PACKET_CMD_EXECUTE, 1);
 
     execute = ofpbuf_put_uninit(buf, sizeof *execute);
-    execute->dp_idx = dpif->dp_idx;
+    execute->dp_ifindex = dpif->dp_ifindex;
 
     nl_msg_put_unspec(buf, ODP_PACKET_ATTR_PACKET, packet->data, packet->size);
     nl_msg_put_unspec(buf, ODP_PACKET_ATTR_ACTIONS, actions, actions_len);
@@ -810,7 +765,7 @@ dpif_linux_set_sflow_probability(struct dpif *dpif_, uint32_t probability)
 
     dpif_linux_dp_init(&dp);
     dp.cmd = ODP_DP_CMD_SET;
-    dp.dp_idx = dpif->dp_idx;
+    dp.dp_ifindex = dpif->dp_ifindex;
     dp.sampling = &probability;
     return dpif_linux_dp_transact(&dp, NULL, NULL);
 }
@@ -829,7 +784,7 @@ dpif_linux_queue_to_priority(const struct dpif *dpif OVS_UNUSED,
 
 static int
 parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
-                 uint32_t *dp_idx)
+                 int *dp_ifindex)
 {
     static const struct nl_policy odp_packet_policy[] = {
         /* Always present. */
@@ -890,7 +845,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
         upcall->actions_len = nl_attr_get_size(a[ODP_PACKET_ATTR_ACTIONS]);
     }
 
-    *dp_idx = odp_header->dp_idx;
+    *dp_ifindex = odp_header->dp_ifindex;
 
     return 0;
 }
@@ -908,16 +863,16 @@ dpif_linux_recv(struct dpif *dpif_, struct dpif_upcall *upcall)
     }
 
     for (i = 0; i < 50; i++) {
-        uint32_t dp_idx;
+        int dp_ifindex;
 
         error = nl_sock_recv(dpif->mc_sock, &buf, false);
         if (error) {
             return error;
         }
 
-        error = parse_odp_packet(buf, upcall, &dp_idx);
+        error = parse_odp_packet(buf, upcall, &dp_ifindex);
         if (!error
-            && dp_idx == dpif->dp_idx
+            && dp_ifindex == dpif->dp_ifindex
             && dpif->listen_mask & (1u << upcall->type)) {
             return 0;
         }
@@ -957,7 +912,7 @@ const struct dpif_class dpif_linux_class = {
     dpif_linux_enumerate,
     dpif_linux_open,
     dpif_linux_close,
-    dpif_linux_get_all_names,
+    NULL,                       /* get_all_names */
     dpif_linux_destroy,
     dpif_linux_get_stats,
     dpif_linux_get_drop_frags,
@@ -1046,7 +1001,7 @@ dpif_linux_port_changed(const struct rtnetlink_link_change *change,
     struct dpif_linux *dpif = dpif_;
 
     if (change) {
-        if (change->master_ifindex == dpif->local_ifindex
+        if (change->master_ifindex == dpif->dp_ifindex
             && (change->nlmsg_type == RTM_NEWLINK
                 || change->nlmsg_type == RTM_DELLINK))
         {
@@ -1107,7 +1062,7 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport,
     }
 
     vport->cmd = genl->cmd;
-    vport->dp_idx = odp_header->dp_idx;
+    vport->dp_ifindex = odp_header->dp_ifindex;
     vport->port_no = nl_attr_get_u32(a[ODP_VPORT_ATTR_PORT_NO]);
     vport->type = nl_attr_get_u32(a[ODP_VPORT_ATTR_TYPE]);
     vport->name = nl_attr_get_string(a[ODP_VPORT_ATTR_NAME]);
@@ -1145,7 +1100,7 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport,
                           vport->cmd, 1);
 
     odp_header = ofpbuf_put_uninit(buf, sizeof *odp_header);
-    odp_header->dp_idx = vport->dp_idx;
+    odp_header->dp_ifindex = vport->dp_ifindex;
 
     if (vport->port_no != UINT32_MAX) {
         nl_msg_put_u32(buf, ODP_VPORT_ATTR_PORT_NO, vport->port_no);
@@ -1192,7 +1147,6 @@ void
 dpif_linux_vport_init(struct dpif_linux_vport *vport)
 {
     memset(vport, 0, sizeof *vport);
-    vport->dp_idx = UINT32_MAX;
     vport->port_no = UINT32_MAX;
 }
 
@@ -1286,7 +1240,7 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf)
     }
 
     dp->cmd = genl->cmd;
-    dp->dp_idx = odp_header->dp_idx;
+    dp->dp_ifindex = odp_header->dp_ifindex;
     dp->name = nl_attr_get_string(a[ODP_DP_ATTR_NAME]);
     if (a[ODP_DP_ATTR_STATS]) {
         /* Can't use structure assignment because Netlink doesn't ensure
@@ -1342,7 +1296,7 @@ dpif_linux_dp_to_ofpbuf(const struct dpif_linux_dp *dp, struct ofpbuf *buf)
                           NLM_F_REQUEST | NLM_F_ECHO, dp->cmd, 1);
 
     odp_header = ofpbuf_put_uninit(buf, sizeof *odp_header);
-    odp_header->dp_idx = dp->dp_idx;
+    odp_header->dp_ifindex = dp->dp_ifindex;
 
     if (dp->name) {
         nl_msg_put_string(buf, ODP_DP_ATTR_NAME, dp->name);
@@ -1364,7 +1318,6 @@ void
 dpif_linux_dp_init(struct dpif_linux_dp *dp)
 {
     memset(dp, 0, sizeof *dp);
-    dp->dp_idx = -1;
 }
 
 static void
@@ -1427,7 +1380,7 @@ dpif_linux_dp_get(const struct dpif *dpif_, struct dpif_linux_dp *reply,
 
     dpif_linux_dp_init(&request);
     request.cmd = ODP_DP_CMD_GET;
-    request.dp_idx = dpif->dp_idx;
+    request.dp_ifindex = dpif->dp_ifindex;
 
     return dpif_linux_dp_transact(&request, reply, bufp);
 }
@@ -1474,7 +1427,7 @@ dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow *flow,
     }
 
     flow->nlmsg_flags = nlmsg->nlmsg_flags;
-    flow->dp_idx = odp_header->dp_idx;
+    flow->dp_ifindex = odp_header->dp_ifindex;
     flow->key = nl_attr_get(a[ODP_FLOW_ATTR_KEY]);
     flow->key_len = nl_attr_get_size(a[ODP_FLOW_ATTR_KEY]);
     if (a[ODP_FLOW_ATTR_ACTIONS]) {
@@ -1502,7 +1455,7 @@ dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *flow,
                           NLM_F_REQUEST | flow->nlmsg_flags, flow->cmd, 1);
 
     odp_header = ofpbuf_put_uninit(buf, sizeof *odp_header);
-    odp_header->dp_idx = flow->dp_idx;
+    odp_header->dp_ifindex = flow->dp_ifindex;
 
     if (flow->key_len) {
         nl_msg_put_unspec(buf, ODP_FLOW_ATTR_KEY, flow->key, flow->key_len);
index 6ccd54a..bd7b07c 100644 (file)
@@ -28,7 +28,7 @@ struct dpif_linux_vport {
     uint8_t cmd;
 
     /* odp_vport header. */
-    uint32_t dp_idx;
+    int dp_ifindex;
     uint32_t port_no;                      /* UINT32_MAX if unknown. */
     enum odp_vport_type type;
 
diff --git a/lib/dpif.man b/lib/dpif.man
deleted file mode 100644 (file)
index 775ec58..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-.RS
-.TP
-[\fItype\fB@\fR]\fBdp\fIN\fR
-Datapath number \fIN\fR, where \fIN\fR is a number between 0 and 255,
-inclusive.  If \fItype\fR is given, it specifies the datapath provider of
-\fBdp\fIN\fR, otherwise the default provider \fBsystem\fR is assumed.
-.
-.TP
-[\fItype\fB@\fR]\fIname\fR
-The name of the network device associated with the datapath's local
-port.  (\fB\*(PN\fR internally converts this into a datapath number,
-as above.)  If \fItype\fR is given, it specifies the datapath provider of
-\fIname\fR, otherwise the default provider \fBsystem\fR is assumed.
-.RE
index 00017b8..436be8c 100644 (file)
@@ -185,7 +185,7 @@ netdev_vport_get_netdev_type(const struct dpif_linux_vport *vport)
     }
 
     VLOG_WARN_RL(&rl, "dp%d: port `%s' has unsupported type %u",
-                 vport->dp_idx, vport->name, (unsigned int) vport->type);
+                 vport->dp_ifindex, vport->name, (unsigned int) vport->type);
     return "unknown";
 }
 
index 958b817..12fa27b 100644 (file)
@@ -24,24 +24,19 @@ that network device to the datapath.
 If \fBovs\-vswitchd\fR(8) is in use, use \fBovs\-vsctl\fR(8) instead
 of \fBovs\-dpctl\fR.
 .PP
-Most \fBovs\-dpctl\fR commands that work with datapaths take an argument
-that specifies the name of the datapath, in one of the following
-forms:
-.so lib/dpif.man
+Most \fBovs\-dpctl\fR commands that work with datapaths take an
+argument that specifies the name of the datapath.  Datapath names take
+the form [\fItype\fB@\fR]\fIname\fR, where \fIname\fR is the network
+device associated with the datapath's local port.  If \fItype\fR is
+given, it specifies the datapath provider of \fIname\fR, otherwise the
+default provider \fBsystem\fR is assumed.
 .PP
 The following commands manage datapaths.
 .
 .TP
 \fBadd\-dp \fIdp\fR [\fInetdev\fR...]
-Creates datapath \fIdp\fR.  The name of the new datapath's local port
-depends on how \fIdp\fR is specified: if it takes the form
-\fBdp\fIN\fR, the local port will be named \fBdp\fIN\fR; otherwise,
-the local port's name will be \fIdp\fR.
-.IP
-This will fail if the host already has 256 datapaths, if a network
-device with the same name as the new datapath's local port already
-exists, or if \fIdp\fR is given in the form \fBdp\fIN\fR
-and a datapath numbered \fIN\fR already exists.
+Creates datapath \fIdp\fR, with a local port also named \fIdp\fR.
+This will fail if a network device \fIdp\fR already exists.
 .IP
 If \fInetdev\fRs are specified, \fBovs\-dpctl\fR adds them to the datapath.
 .
index b84f8e7..9dec805 100644 (file)
@@ -19,10 +19,12 @@ OpenFlow controllers over TCP or SSL.
 For a more powerful alternative to \fBovs\-openflowd\fR, see
 \fBovs\-vswitchd\fR(8).  Do not run both daemons at the same time.
 .PP
-The mandatory \fIdatapath\fR argument argument specifies the local datapath
-to relay.  It takes one of the following forms:
-.
-.so lib/dpif.man
+The mandatory \fIdatapath\fR argument argument specifies the local
+datapath to relay.  It takes the form [\fItype\fB@\fR]\fIname\fR,
+where \fIname\fR is the network device associated with the datapath's
+local port.  If \fItype\fR is given, it specifies the datapath
+provider of \fIname\fR, otherwise the default provider \fBsystem\fR is
+assumed.
 .
 .PP
 The optional \fIcontroller\fR arguments specify how to connect to the