* 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);
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
}
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);
}
/* 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;
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,
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)
goto error;
}
- dp = get_dp(odp_header->dp_idx);
+ dp = get_dp(odp_header->dp_ifindex);
error = -ENODEV;
if (!dp)
goto error;
if (err)
return err;
- dp = get_dp(odp_header->dp_idx);
+ dp = get_dp(odp_header->dp_ifindex);
if (!dp)
return -ENODEV;
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;
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;
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));
/* 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. */
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;
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. */
goto err_destroy_table;
}
+ dp->dp_ifindex = vport_get_ifindex(vport);
dp->drop_frags = 0;
dp->stats_percpu = alloc_percpu(struct dp_stats_percpu);
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();
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);
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;
}
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));
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);
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;
u32 port_no;
int retval;
- dp = get_dp(odp_header->dp_idx);
+ dp = get_dp(odp_header->dp_ifindex);
if (!dp)
return -ENODEV;
/**
* 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.
*/
struct datapath {
struct rcu_head rcu;
- int dp_idx;
+ int dp_ifindex;
+ struct list_head list_node;
struct kobject ifobj;
int drop_frags;
#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
#include <linux/if_link.h>
#include <linux/netlink.h>
\f
-/* Datapaths. */
+/* datapaths. */
#define ODP_DATAPATH_FAMILY "odp_datapath"
#define ODP_DATAPATH_MCGROUP "odp_datapath"
/**
* 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
*/
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. */
-# 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
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 \
uint8_t cmd;
/* struct odp_header. */
- uint32_t dp_idx;
+ int dp_ifindex;
/* Attributes. */
const char *name; /* ODP_DP_ATTR_NAME. */
/* struct odp_header. */
unsigned int nlmsg_flags;
- uint32_t dp_idx;
+ int dp_ifindex;
/* Attributes.
*
/* 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;
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);
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();
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;
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;
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;
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_)
{
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);
}
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);
}
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 "
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);
}
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;
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);
}
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);
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);
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;
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,
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);
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);
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);
}
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. */
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;
}
}
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;
}
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,
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))
{
}
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]);
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);
dpif_linux_vport_init(struct dpif_linux_vport *vport)
{
memset(vport, 0, sizeof *vport);
- vport->dp_idx = UINT32_MAX;
vport->port_no = UINT32_MAX;
}
}
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
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);
dpif_linux_dp_init(struct dpif_linux_dp *dp)
{
memset(dp, 0, sizeof *dp);
- dp->dp_idx = -1;
}
static void
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);
}
}
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]) {
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);
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;
+++ /dev/null
-.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
}
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";
}
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.
.
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