From: Michael Tremer Date: Fri, 14 Apr 2023 13:33:13 +0000 (+0000) Subject: networkd: Implement deleting links X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=371b836adc35d69cdd7a4a71144ec5e0f7ef42e1;p=network.git networkd: Implement deleting links This is a little bit rough but generally does work. Signed-off-by: Michael Tremer --- diff --git a/src/networkd/link.c b/src/networkd/link.c index 0fb388b9..949d0d8d 100644 --- a/src/networkd/link.c +++ b/src/networkd/link.c @@ -41,6 +41,11 @@ struct nw_link { // Interface Name char ifname[IFNAMSIZ]; + enum nw_link_state { + NW_LINK_UNKNOWN = 0, + NW_LINK_DESTROYED, + } state; + // MTU uint32_t mtu; uint32_t min_mtu; @@ -94,6 +99,16 @@ nw_link* nw_link_unref(nw_link* link) { return NULL; } +/* + This is a helper function for when we pass a reference to the event loop + it will have to dereference the link instance later. +*/ +static void __nw_link_unref(void* data) { + nw_link* link = (nw_link*)data; + + nw_link_unref(link); +} + int nw_link_ifindex(nw_link* link) { return link->ifindex; } @@ -370,3 +385,54 @@ ERROR: return r; } + +static int __nw_link_destroy(sd_netlink* rtnl, sd_netlink_message* m, void* data) { + nw_link* link = (nw_link*)data; + int r; + + // Check if the operation was successful + r = sd_netlink_message_get_errno(m); + if (r < 0) { + ERROR("Could not remove link %d: %m\n", link->ifindex); + // XXX We should extract the error message + + return 0; + } + + // Mark this link as destroyed + link->state = NW_LINK_DESTROYED; + + return 0; +} + +int nw_link_destroy(nw_link* link) { + sd_netlink_message* m = NULL; + int r; + + sd_netlink* rtnl = nw_daemon_get_rtnl(link->daemon); + if (!rtnl) + return 1; + + DEBUG("Destroying link %d\n", link->ifindex); + + // Create a new message + r = sd_rtnl_message_new_link(rtnl, &m, RTM_DELLINK, link->ifindex); + if (r < 0) { + ERROR("Could not allocate RTM_DELLINK message: %m\n"); + goto ERROR; + } + + // Send the message + r = sd_netlink_call_async(rtnl, NULL, m, __nw_link_destroy, + __nw_link_unref, nw_link_ref(link), -1, NULL); + if (r < 0) { + ERROR("Could not send rtnetlink message: %m\n"); + goto ERROR; + } + +ERROR: + if (m) + sd_netlink_message_unref(m); + + return r; +} diff --git a/src/networkd/link.h b/src/networkd/link.h index 779621b0..58a825a1 100644 --- a/src/networkd/link.h +++ b/src/networkd/link.h @@ -37,4 +37,6 @@ int nw_link_has_carrier(nw_link* link); int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); +int nw_link_destroy(nw_link* link); + #endif /* NETWORKD_LINK_H */ diff --git a/src/networkd/port.c b/src/networkd/port.c index ec40830f..7d023050 100644 --- a/src/networkd/port.c +++ b/src/networkd/port.c @@ -263,8 +263,25 @@ const nw_address_t* nw_port_get_address(nw_port* port) { return &port->address; } +static int nw_port_is_disabled(nw_port* port) { + return nw_config_get_bool(port->config, "DISABLED"); +} + int nw_port_reconfigure(nw_port* port) { - return 0; // XXX TODO + int r; + + // If the port is disabled, we will try to destroy it + if (nw_port_is_disabled(port)) { + if (port->link) { + r = nw_link_destroy(port->link); + if (r) + return r; + } + + return 0; + } + + // XXX TODO } int nw_port_has_carrier(nw_port* port) {