From 254f2dc8e3eb18debf4a8f238b9c87cf4d4dbd3f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 21 Jan 2011 17:01:56 -0800 Subject: [PATCH] datapath: Change dp_idx to dp_ifindex, the ifindex of the local port. 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 Acked-by: Jesse Gross --- datapath/datapath.c | 113 ++++++++-------- datapath/datapath.h | 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 8931456a..dee1b0f8 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) @@ -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//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; diff --git a/datapath/datapath.h b/datapath/datapath.h index 176282bd..befa55cb 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//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 3856bb60..d44312fc 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 1ba43c5b..083800cc 100644 --- a/include/openvswitch/datapath-protocol.h +++ b/include/openvswitch/datapath-protocol.h @@ -70,7 +70,7 @@ #include #include -/* 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 ba02d411..c51d3ed8 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 01377bda..dc59fe07 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,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); diff --git a/lib/dpif-linux.h b/lib/dpif-linux.h index 6ccd54a2..bd7b07ca 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 775ec585..00000000 --- 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 00017b8f..436be8c6 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 958b817e..12fa27bf 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 b84f8e7b..9dec805e 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 -- 2.30.2