[ovs-dev] [netlink v5 59/61] datapath: Change dp_idx to dp_ifindex, the ifindex of the local port.

Ben Pfaff blp at nicira.com
Thu Jan 27 00:23:42 UTC 2011


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 at nicira.com>
---
 datapath/datapath.c                                |  113 ++++++++----------
 datapath/datapath.h                                |    6 +-
 .../linux-2.6/compat-2.6/include/linux/netdevice.h |   14 +++
 include/openvswitch/datapath-protocol.h            |   17 ++--
 lib/automake.mk                                    |    3 +-
 lib/dpif-linux.c                                   |  123 ++++++--------------
 lib/dpif-linux.h                                   |    2 +-
 lib/dpif.man                                       |   14 ---
 lib/netdev-vport.c                                 |    2 +-
 utilities/ovs-dpctl.8.in                           |   21 ++--
 utilities/ovs-openflowd.8.in                       |   10 +-
 11 files changed, 133 insertions(+), 192 deletions(-)
 delete mode 100644 lib/dpif.man

diff --git a/datapath/datapath.c b/datapath/datapath.c
index b2354d7..d5d6a18 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -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)
@@ -935,7 +944,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;
@@ -1059,7 +1068,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;
 
@@ -1089,12 +1098,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;
 
@@ -1127,7 +1136,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;
 
@@ -1210,7 +1219,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));
@@ -1278,24 +1287,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. */
@@ -1310,12 +1314,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;
@@ -1331,28 +1333,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. */
@@ -1379,6 +1364,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);
@@ -1394,7 +1380,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();
@@ -1444,7 +1430,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);
@@ -1512,19 +1498,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;
 }
 
@@ -1593,7 +1582,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));
@@ -1672,7 +1661,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);
 
@@ -1717,7 +1706,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;
@@ -1901,7 +1890,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;
 
diff --git a/datapath/datapath.h b/datapath/datapath.h
index 176282b..befa55c 100644
--- a/datapath/datapath.h
+++ b/datapath/datapath.h
@@ -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;
diff --git a/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h b/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
index 3856bb6..d44312f 100644
--- a/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
+++ b/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
@@ -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
diff --git a/include/openvswitch/datapath-protocol.h b/include/openvswitch/datapath-protocol.h
index 1ba43c5..083800c 100644
--- a/include/openvswitch/datapath-protocol.h
+++ b/include/openvswitch/datapath-protocol.h
@@ -70,7 +70,7 @@
 #include <linux/if_link.h>
 #include <linux/netlink.h>
 
-/* 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;
 };
 
 /**
  * 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. */
diff --git a/lib/automake.mk b/lib/automake.mk
index ba02d41..c51d3ed 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -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 \
diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index 01377bd..dc59fe0 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -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,21 +247,10 @@ 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_)
 {
     struct dpif_linux *dpif = dpif_linux_cast(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);
diff --git a/lib/dpif-linux.h b/lib/dpif-linux.h
index 6ccd54a..bd7b07c 100644
--- a/lib/dpif-linux.h
+++ b/lib/dpif-linux.h
@@ -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
index 775ec58..0000000
--- a/lib/dpif.man
+++ /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
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 00017b8..436be8c 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -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";
 }
 
diff --git a/utilities/ovs-dpctl.8.in b/utilities/ovs-dpctl.8.in
index 958b817..12fa27b 100644
--- a/utilities/ovs-dpctl.8.in
+++ b/utilities/ovs-dpctl.8.in
@@ -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.
 .
diff --git a/utilities/ovs-openflowd.8.in b/utilities/ovs-openflowd.8.in
index b84f8e7..9dec805 100644
--- a/utilities/ovs-openflowd.8.in
+++ b/utilities/ovs-openflowd.8.in
@@ -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
-- 
1.7.1





More information about the dev mailing list