2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

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 <jpettit@nicira.com>
This commit is contained in:
Justin Pettit
2012-07-27 23:58:24 -07:00
parent 8a77bb2ec8
commit 232dfa4aa3
5 changed files with 38 additions and 12 deletions

View File

@@ -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); 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 { do {
uint32_t upcall_pid; 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); upcall_pid = dpif_linux_port_get_pid(dpif_, request.port_no);
request.upcall_pid = &upcall_pid; request.upcall_pid = &upcall_pid;
error = dpif_linux_vport_transact(&request, &reply, &buf); 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. */ /* Older datapath has lower limit. */
max_ports = dpif->alloc_port_no; max_ports = dpif->alloc_port_no;
dpif->alloc_port_no = 0; 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); ofpbuf_delete(buf);
} while ((i++ < max_ports) } while ((*port_nop == UINT16_MAX) && (i++ < max_ports)
&& (error == EBUSY || error == EFBIG)); && (error == EBUSY || error == EFBIG));
return error; return error;

View File

@@ -407,7 +407,16 @@ dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev,
struct dp_netdev *dp = get_dp_netdev(dpif); struct dp_netdev *dp = get_dp_netdev(dpif);
int port_no; 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) { if (port_no >= 0) {
*port_nop = port_no; *port_nop = port_no;
return do_add_port(dp, netdev_get_name(netdev), return do_add_port(dp, netdev_get_name(netdev),

View File

@@ -110,8 +110,12 @@ struct dpif_class {
/* Retrieves statistics for 'dpif' into 'stats'. */ /* Retrieves statistics for 'dpif' into 'stats'. */
int (*get_stats)(const struct dpif *dpif, struct dpif_dp_stats *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' /* Adds 'netdev' as a new port in 'dpif'. If '*port_no' is not
* to the new port's port number. */ * 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, int (*port_add)(struct dpif *dpif, struct netdev *netdev,
uint16_t *port_no); uint16_t *port_no);

View File

@@ -410,19 +410,27 @@ dpif_get_dp_stats(const struct dpif *dpif, struct dpif_dp_stats *stats)
return error; return error;
} }
/* Attempts to add 'netdev' as a port on 'dpif'. If successful, returns 0 and /* Attempts to add 'netdev' as a port on 'dpif'. If 'port_nop' is
* sets '*port_nop' to the new port's port number (if 'port_nop' is non-null). * non-null and its value is not UINT16_MAX, then attempts to use the
* On failure, returns a positive errno value and sets '*port_nop' to * value as the port number.
* UINT16_MAX (if 'port_nop' is non-null). */ *
* 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 int
dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint16_t *port_nop) dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint16_t *port_nop)
{ {
const char *netdev_name = netdev_get_name(netdev); const char *netdev_name = netdev_get_name(netdev);
uint16_t port_no; uint16_t port_no = UINT16_MAX;
int error; int error;
COVERAGE_INC(dpif_port_add); COVERAGE_INC(dpif_port_add);
if (port_nop) {
port_no = *port_nop;
}
error = dpif->dpif_class->port_add(dpif, netdev, &port_no); error = dpif->dpif_class->port_add(dpif, netdev, &port_no);
if (!error) { if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16, VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16,

View File

@@ -2514,7 +2514,7 @@ static int
port_add(struct ofproto *ofproto_, struct netdev *netdev, uint16_t *ofp_portp) port_add(struct ofproto *ofproto_, struct netdev *netdev, uint16_t *ofp_portp)
{ {
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
uint16_t odp_port; uint16_t odp_port = UINT16_MAX;
int error; int error;
error = dpif_port_add(ofproto->dpif, netdev, &odp_port); error = dpif_port_add(ofproto->dpif, netdev, &odp_port);