- /* 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;
- }