return nw_ports_ref(daemon->ports);
}
+int nw_daemon_ports_walk(nw_daemon* daemon, nw_ports_walk_callback callback, void* data) {
+ if (!daemon->ports)
+ return 0;
+
+ return nw_ports_walk(daemon->ports, callback, data);
+}
+
nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name) {
if (!daemon->ports)
return NULL;
Ports
*/
nw_ports* nw_daemon_ports(nw_daemon* daemon);
+int nw_daemon_ports_walk(nw_daemon* daemon, nw_ports_walk_callback callback, void* data);
nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name);
/*
}
const char* nw_link_ifname(nw_link* link) {
+ // Return NULL if name isn't set
+ if (!*link->ifname)
+ return NULL;
+
return link->ifname;
}
DEBUG("Link %d has been renamed to '%s'\n", link->ifindex, link->ifname);
+ // Assign link to ports
+ nw_daemon_ports_walk(link->daemon, __nw_port_set_link, link);
+
+ // Assign link to zones
+ nw_daemon_zones_walk(link->daemon, __nw_zone_set_link, link);
+
return 0;
}
STAILQ_REMOVE(&links->entries, entry, nw_links_entry, nodes);
links->num--;
+
+ // Drop link from all ports
+ nw_daemon_ports_walk(links->daemon, __nw_port_drop_link, link);
+
+ // Drop link from all zones
+ nw_daemon_zones_walk(links->daemon, __nw_zone_drop_link, link);
}
int nw_links_enumerate(nw_links* links) {
return nw_port_type_from_string(type);
}
+static int nw_port_set_link(nw_port* port, nw_link* link) {
+ // Do nothing if the same link is being re-assigned
+ if (port->link == link)
+ return 0;
+
+ // Dereference the former link if set
+ if (port->link)
+ nw_link_unref(port->link);
+
+ // Store the new link
+ if (link) {
+ port->link = nw_link_ref(link);
+
+ DEBUG("Port %s: Assigned link %d\n", port->name, nw_link_ifindex(port->link));
+
+ // Or clear the pointer if no link has been provided
+ } else {
+ port->link = NULL;
+
+ DEBUG("Port %s: Removed link\n", port->name);
+ }
+
+ return 0;
+}
+
static int nw_port_setup(nw_port* port) {
+ nw_link* link = NULL;
char path[PATH_MAX];
int r;
// Find the link
- port->link = nw_daemon_get_link_by_name(port->daemon, port->name);
- if (port->link) {
- DEBUG("%s: Found matching link %d\n", port->name, nw_link_ifindex(port->link));
- } else {
- DEBUG("%s: Could not find matching link\n", port->name);
+ link = nw_daemon_get_link_by_name(port->daemon, port->name);
+ if (link) {
+ r = nw_port_set_link(port, link);
+ if (r)
+ goto ERROR;
}
// Compose the path to the main configuration file
r = nw_path_join(path, PORT_CONFIG_DIR, port->name);
if (r)
- return r;
+ goto ERROR;
// Initialize the configuration
r = nw_config_create(&port->config, path);
if (r)
- return r;
+ goto ERROR;
// Determine type
port->type = nw_port_setup_type(port);
if (!port->type) {
ERROR("Could not determine type of port %s\n", port->name);
- return 0;
+ goto ERROR;
}
// Perform some common initialization
r = nw_port_setup_common(port);
if (r)
- return r;
+ goto ERROR;
// Call any custom initialization
switch (port->type) {
break;
}
- return 0;
+ERROR:
+ if (link)
+ nw_link_unref(link);
+
+ return r;
}
int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name) {
return p;
}
-static nw_link* nw_port_get_link(nw_port* port) {
- if (!port->link)
- return NULL;
+int __nw_port_set_link(nw_daemon* daemon, nw_port* port, void* data) {
+ nw_link* link = (nw_link*)data;
+
+ // Fetch the link name
+ const char* ifname = nw_link_ifname(link);
+ if (!ifname) {
+ ERROR("Link does not have a name set\n");
+ return 1;
+ }
+
+ // Set link if the name matches
+ if (strcmp(port->name, ifname) == 0)
+ return nw_port_set_link(port, link);
+
+ // If we have the link set but the name did not match, we will remove it
+ else if (port->link == link)
+ return nw_port_set_link(port, NULL);
+
+ return 0;
+}
+
+int __nw_port_drop_link(nw_daemon* daemon, nw_port* port, void* data) {
+ nw_link* link = (nw_link*)data;
- return nw_link_ref(port->link);
+ // Drop the link if it matches
+ if (port->link == link)
+ return nw_port_set_link(port, NULL);
+
+ return 0;
}
const nw_address_t* nw_port_get_address(nw_port* port) {
char* nw_port_bus_path(nw_port* port);
+int __nw_port_set_link(nw_daemon* daemon, nw_port* port, void* data);
+int __nw_port_drop_link(nw_daemon* daemon, nw_port* port, void* data);
+
const nw_address_t* nw_port_get_address(nw_port* port);
int nw_port_reconfigure(nw_port* port);
free(zone);
}
+static int nw_zone_set_link(nw_zone* zone, nw_link* link) {
+ // Do nothing if the same link is being re-assigned
+ if (zone->link == link)
+ return 0;
+
+ // Dereference the former link if set
+ if (zone->link)
+ nw_link_unref(zone->link);
+
+ // Store the new link
+ if (link) {
+ zone->link = nw_link_ref(link);
+
+ DEBUG("Zone %s: Assigned link %d\n", zone->name, nw_link_ifindex(zone->link));
+
+ // Or clear the pointer if no link has been provided
+ } else {
+ zone->link = NULL;
+
+ DEBUG("Zone %s: Removed link\n", zone->name);
+ }
+
+ return 0;
+}
+
static int nw_zone_setup(nw_zone* zone) {
+ nw_link* link = NULL;
char path[PATH_MAX];
int r;
// Find the link
- zone->link = nw_daemon_get_link_by_name(zone->daemon, zone->name);
- if (zone->link) {
- DEBUG("%s: Found matching link %d\n", zone->name, nw_link_ifindex(zone->link));
- } else {
- DEBUG("%s: Could not find matching link\n", zone->name);
+ link = nw_daemon_get_link_by_name(zone->daemon, zone->name);
+ if (link) {
+ r = nw_zone_set_link(zone, link);
+ if (r)
+ goto ERROR;
}
// Compose the path to the main configuration file
r = nw_zone_path(zone, path, "%s", "settings");
if (r)
- return r;
+ goto ERROR;
// Initialize the configuration
r = nw_config_create(&zone->config, path);
if (r)
- return r;
+ goto ERROR;
- return 0;
+ERROR:
+ if (link)
+ nw_link_unref(link);
+
+ return r;
}
int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) {
return p;
}
-static nw_link* nw_zone_get_link(nw_zone* zone) {
- if (!zone->link)
- return NULL;
+int __nw_zone_set_link(nw_daemon* daemon, nw_zone* zone, void* data) {
+ nw_link* link = (nw_link*)data;
+
+ // Fetch the link name
+ const char* ifname = nw_link_ifname(link);
+ if (!ifname) {
+ ERROR("Link does not have a name set\n");
+ return 1;
+ }
+
+ // Set link if the name matches
+ if (strcmp(zone->name, ifname) == 0)
+ return nw_zone_set_link(zone, link);
+
+ // If we have the link set but the name did not match, we will remove it
+ else if (zone->link == link)
+ return nw_zone_set_link(zone, NULL);
- return nw_link_ref(zone->link);
+ return 0;
+}
+
+int __nw_zone_drop_link(nw_daemon* daemon, nw_zone* zone, void* data) {
+ nw_link* link = (nw_link*)data;
+
+ // Drop the link if it matches
+ if (zone->link == link)
+ return nw_zone_set_link(zone, NULL);
+
+ return 0;
}
int nw_zone_reconfigure(nw_zone* zone) {
char* nw_zone_bus_path(nw_zone* zone);
+int __nw_zone_set_link(nw_daemon* daemon, nw_zone* zone, void* data);
+int __nw_zone_drop_link(nw_daemon* daemon, nw_zone* zone, void* data);
+
int nw_zone_reconfigure(nw_zone* zone);
int nw_zone_has_carrier(nw_zone* zone);