From: Justin Pettit Date: Sat, 28 Jul 2012 06:58:24 +0000 (-0700) Subject: dpif: Allow the port number to be requested when adding an interface. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=232dfa4aa32a1a5ba99f671a6fd7de58b2bd8b3c;p=openvswitch dpif: Allow the port number to be requested when adding an interface. The datapath allows requesting a specific port number for a port, but the dpif interface didn't expose it. This commit adds that support. Signed-off-by: Justin Pettit --- diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index fcf6899c..97850f5b 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -424,11 +424,13 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, netdev_linux_ethtool_set_flag(netdev, ETH_FLAG_LRO, "LRO", false); } - /* Loop until we find a port that isn't used. */ + /* Unless a specific port was requested, loop until we find a port + * that isn't used. */ do { uint32_t upcall_pid; - request.port_no = ++dpif->alloc_port_no; + request.port_no = *port_nop != UINT16_MAX ? *port_nop + : ++dpif->alloc_port_no; upcall_pid = dpif_linux_port_get_pid(dpif_, request.port_no); request.upcall_pid = &upcall_pid; error = dpif_linux_vport_transact(&request, &reply, &buf); @@ -441,10 +443,13 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, /* Older datapath has lower limit. */ max_ports = dpif->alloc_port_no; dpif->alloc_port_no = 0; + } else if (error == EBUSY && *port_nop != UINT16_MAX) { + VLOG_INFO("%s: requested port %"PRIu16" is in use", + dpif_name(dpif_), *port_nop); } ofpbuf_delete(buf); - } while ((i++ < max_ports) + } while ((*port_nop == UINT16_MAX) && (i++ < max_ports) && (error == EBUSY || error == EFBIG)); return error; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 5f7ce8ff..60fae5fa 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -407,7 +407,16 @@ dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev, struct dp_netdev *dp = get_dp_netdev(dpif); int port_no; - port_no = choose_port(dpif, netdev); + if (*port_nop != UINT16_MAX) { + if (*port_nop >= MAX_PORTS) { + return EFBIG; + } else if (dp->ports[*port_nop]) { + return EBUSY; + } + port_no = *port_nop; + } else { + port_no = choose_port(dpif, netdev); + } if (port_no >= 0) { *port_nop = port_no; return do_add_port(dp, netdev_get_name(netdev), diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 0641d306..317e6170 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -110,8 +110,12 @@ struct dpif_class { /* Retrieves statistics for 'dpif' into 'stats'. */ int (*get_stats)(const struct dpif *dpif, struct dpif_dp_stats *stats); - /* Adds 'netdev' as a new port in 'dpif'. If successful, sets '*port_no' - * to the new port's port number. */ + /* Adds 'netdev' as a new port in 'dpif'. If '*port_no' is not + * UINT16_MAX, attempts to use that as the port's port number. + * + * If port is successfully added, sets '*port_no' to the new port's + * port number. Returns EBUSY if caller attempted to choose a port + * number, and it was in use. */ int (*port_add)(struct dpif *dpif, struct netdev *netdev, uint16_t *port_no); diff --git a/lib/dpif.c b/lib/dpif.c index ce7c5801..667e07ce 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -410,19 +410,27 @@ dpif_get_dp_stats(const struct dpif *dpif, struct dpif_dp_stats *stats) return error; } -/* Attempts to add 'netdev' as a port on 'dpif'. If successful, returns 0 and - * sets '*port_nop' to the new port's port number (if 'port_nop' is non-null). - * On failure, returns a positive errno value and sets '*port_nop' to - * UINT16_MAX (if 'port_nop' is non-null). */ +/* Attempts to add 'netdev' as a port on 'dpif'. If 'port_nop' is + * non-null and its value is not UINT16_MAX, then attempts to use the + * value as the port number. + * + * If successful, returns 0 and sets '*port_nop' to the new port's port + * number (if 'port_nop' is non-null). On failure, returns a positive + * errno value and sets '*port_nop' to UINT16_MAX (if 'port_nop' is + * non-null). */ int dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint16_t *port_nop) { const char *netdev_name = netdev_get_name(netdev); - uint16_t port_no; + uint16_t port_no = UINT16_MAX; int error; COVERAGE_INC(dpif_port_add); + if (port_nop) { + port_no = *port_nop; + } + error = dpif->dpif_class->port_add(dpif, netdev, &port_no); if (!error) { VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c25c513c..76addfb4 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -2514,7 +2514,7 @@ static int port_add(struct ofproto *ofproto_, struct netdev *netdev, uint16_t *ofp_portp) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); - uint16_t odp_port; + uint16_t odp_port = UINT16_MAX; int error; error = dpif_port_add(ofproto->dpif, netdev, &odp_port);