]> git.ipfire.org Git - people/ms/network.git/commitdiff
networkd: Implement deleting links
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 14 Apr 2023 13:33:13 +0000 (13:33 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 14 Apr 2023 13:33:13 +0000 (13:33 +0000)
This is a little bit rough but generally does work.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/networkd/link.c
src/networkd/link.h
src/networkd/port.c

index 0fb388b9a416d270c754dff3aa707342c4b509fd..949d0d8d228d33f962445cb25497533509f25f9e 100644 (file)
@@ -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;
+}
index 779621b0ce21b104650871e00d1ff97e39db6fbc..58a825a179cd94dfff5b8f04bb1d88ace50ee543 100644 (file)
@@ -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 */
index ec40830fe11405b8585e4de652a6e5024704971a..7d023050d2053611f6bda46019b1490f1253ed35 100644 (file)
@@ -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) {