struct sset changed_ports; /* Ports that have changed. */
struct nln_notifier *port_notifier;
bool change_error;
-
- /* Port number allocation. */
- uint32_t alloc_port_no;
};
static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5);
const char *type = netdev_get_type(netdev);
struct dpif_linux_vport request, reply;
const struct ofpbuf *options;
+ uint32_t upcall_pid;
struct ofpbuf *buf;
- int error, i = 0, max_ports = MAX_PORTS;
+ int error;
dpif_linux_vport_init(&request);
request.cmd = OVS_VPORT_CMD_NEW;
netdev_linux_ethtool_set_flag(netdev, ETH_FLAG_LRO, "LRO", false);
}
- /* Unless a specific port was requested, loop until we find a port
- * that isn't used. */
- do {
- uint32_t upcall_pid;
+ request.port_no = *port_nop;
+ upcall_pid = dpif_linux_port_get_pid(dpif_, request.port_no);
+ request.upcall_pid = &upcall_pid;
- request.port_no = *port_nop != UINT32_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);
+ error = dpif_linux_vport_transact(&request, &reply, &buf);
- if (!error) {
- *port_nop = reply.port_no;
- VLOG_DBG("%s: assigning port %"PRIu32" to netlink pid %"PRIu32,
- dpif_name(dpif_), request.port_no, upcall_pid);
- } else if (error == EFBIG) {
- /* Older datapath has lower limit. */
- max_ports = dpif->alloc_port_no;
- dpif->alloc_port_no = 0;
- } else if (error == EBUSY && *port_nop != UINT32_MAX) {
- VLOG_INFO("%s: requested port %"PRIu32" is in use",
- dpif_name(dpif_), *port_nop);
- }
+ if (!error) {
+ *port_nop = reply.port_no;
+ VLOG_DBG("%s: assigning port %"PRIu32" to netlink pid %"PRIu32,
+ dpif_name(dpif_), request.port_no, upcall_pid);
+ } else if (error == EBUSY && *port_nop != UINT32_MAX) {
+ VLOG_INFO("%s: requested port %"PRIu32" is in use",
+ dpif_name(dpif_), *port_nop);
+ }
- ofpbuf_delete(buf);
- } while ((*port_nop == UINT32_MAX) && (i++ < max_ports)
- && (error == EBUSY || error == EFBIG));
+ ofpbuf_delete(buf);
return error;
}
/* A query by name reported that 'port_name' is in some datapath
* other than 'dpif', but the caller wants to know about 'dpif'. */
error = ENODEV;
- } else {
+ } else if (dpif_port) {
dpif_port->name = xstrdup(reply.name);
dpif_port->type = xstrdup(netdev_vport_get_netdev_type(&reply));
dpif_port->port_no = reply.port_no;
const struct dpif_class dpif_linux_class = {
"system",
dpif_linux_enumerate,
+ NULL,
dpif_linux_open,
dpif_linux_close,
dpif_linux_destroy,
return reply.type == OVS_VPORT_TYPE_INTERNAL;
}
-int
-dpif_linux_vport_send(int dp_ifindex, uint32_t port_no,
- const void *data, size_t size)
-{
- struct ofpbuf actions, key, packet;
- struct odputil_keybuf keybuf;
- struct dpif_execute execute;
- struct flow flow;
- uint64_t action;
-
- ofpbuf_use_const(&packet, data, size);
- flow_extract(&packet, 0, NULL, 0, &flow);
-
- ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
- odp_flow_key_from_flow(&key, &flow);
-
- ofpbuf_use_stack(&actions, &action, sizeof action);
- nl_msg_put_u32(&actions, OVS_ACTION_ATTR_OUTPUT, port_no);
-
- execute.key = key.data;
- execute.key_len = key.size;
- execute.actions = actions.data;
- execute.actions_len = actions.size;
- execute.packet = &packet;
- return dpif_linux_execute__(dp_ifindex, &execute);
-}
-
static bool
dpif_linux_nln_parse(struct ofpbuf *buf, void *vport_)
{