- /* Add and delete ports on all datapaths.
- *
- * The kernel will reject any attempt to add a given port to a datapath if
- * that port already belongs to a different datapath, so we must do all
- * port deletions before any port additions. */
- LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
- struct odp_port *dpif_ports;
- size_t n_dpif_ports;
- struct svec want_ifaces;
-
- dpif_port_list(&br->dpif, &dpif_ports, &n_dpif_ports);
- bridge_get_all_ifaces(br, &want_ifaces);
- for (i = 0; i < n_dpif_ports; i++) {
- const struct odp_port *p = &dpif_ports[i];
- if (!svec_contains(&want_ifaces, p->devname)
- && strcmp(p->devname, br->name)) {
- int retval = dpif_port_del(&br->dpif, p->port);
- if (retval) {
- VLOG_ERR("failed to remove %s interface from dp%u: %s",
- p->devname, dpif_id(&br->dpif), strerror(retval));
- }
- }
- }
- svec_destroy(&want_ifaces);
- free(dpif_ports);
- }
- LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
- struct odp_port *dpif_ports;
- size_t n_dpif_ports;
- struct svec cur_ifaces, want_ifaces, add_ifaces;
- int next_port_no;
-
- dpif_port_list(&br->dpif, &dpif_ports, &n_dpif_ports);
- svec_init(&cur_ifaces);
- for (i = 0; i < n_dpif_ports; i++) {
- svec_add(&cur_ifaces, dpif_ports[i].devname);
- }
- free(dpif_ports);
- svec_sort_unique(&cur_ifaces);
- bridge_get_all_ifaces(br, &want_ifaces);
- svec_diff(&want_ifaces, &cur_ifaces, &add_ifaces, NULL, NULL);
-
- next_port_no = 1;
- for (i = 0; i < add_ifaces.n; i++) {
- const char *if_name = add_ifaces.names[i];
- for (;;) {
- int internal = cfg_get_bool(0, "iface.%s.internal", if_name);
- int error = dpif_port_add(&br->dpif, if_name, next_port_no++,
- internal ? ODP_PORT_INTERNAL : 0);
- if (error != EEXIST) {
- if (next_port_no >= 256) {
- VLOG_ERR("ran out of valid port numbers on dp%u",
- dpif_id(&br->dpif));
- goto out;
- }
- if (error) {
- VLOG_ERR("failed to add %s interface to dp%u: %s",
- if_name, dpif_id(&br->dpif), strerror(error));
- }
- break;
- }
- }
- }
- out:
- svec_destroy(&cur_ifaces);
- svec_destroy(&want_ifaces);
- svec_destroy(&add_ifaces);
- }
- LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
- uint8_t ea[8];
- uint64_t dpid;
- struct iface *local_iface = NULL;
- const char *devname;
- uint8_t engine_type, engine_id;
- bool add_id_to_iface = false;
- struct svec nf_hosts;
-
- bridge_fetch_dp_ifaces(br);
- for (i = 0; i < br->n_ports; ) {
- struct port *port = br->ports[i];
-
- for (j = 0; j < port->n_ifaces; ) {
- struct iface *iface = port->ifaces[j];
- if (iface->dp_ifidx < 0) {
- VLOG_ERR("%s interface not in dp%u, dropping",
- iface->name, dpif_id(&br->dpif));
- iface_destroy(iface);
- } else {
- if (iface->dp_ifidx == ODPP_LOCAL) {
- local_iface = iface;
- }
- VLOG_DBG("dp%u has interface %s on port %d",
- dpif_id(&br->dpif), iface->name, iface->dp_ifidx);
- j++;
- }
- }
- if (!port->n_ifaces) {
- VLOG_ERR("%s port has no interfaces, dropping", port->name);
- port_destroy(port);
- continue;
- }
- i++;
- }