chiark / gitweb /
networkctl: fix strappend() error checking
[elogind.git] / src / network / networkd-link.c
index 08f724e1279d5902f10f82cd1d7040d0da1885bc..63c7a8bf248195f1aad1dd7298a7d6464925a4c7 100644 (file)
@@ -75,6 +75,19 @@ static bool link_ipv4ll_enabled(Link *link) {
         return link->network->ipv4ll;
 }
 
+static bool link_lldp_enabled(Link *link) {
+        if (link->flags & IFF_LOOPBACK)
+                return false;
+
+        if (!link->network)
+                return false;
+
+        if(link->network->bridge)
+                return false;
+
+        return link->network->lldp;
+}
+
 #define FLAG_STRING(string, flag, old, new) \
         (((old ^ new) & flag) \
                 ? ((old & flag) ? (" -" string) : (" +" string)) \
@@ -206,6 +219,12 @@ static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
         if (r < 0)
                 return -ENOMEM;
 
+        r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d",
+                     link->ifindex);
+        if (r < 0)
+                return -ENOMEM;
+
+
         r = hashmap_ensure_allocated(&manager->links, NULL);
         if (r < 0)
                 return r;
@@ -240,12 +259,16 @@ static void link_free(Link *link) {
                 address_free(address);
         }
 
+        sd_dhcp_server_unref(link->dhcp_server);
         sd_dhcp_client_unref(link->dhcp_client);
         sd_dhcp_lease_unref(link->dhcp_lease);
 
         unlink(link->lease_file);
         free(link->lease_file);
 
+        unlink(link->lldp_file);
+        free(link->lldp_file);
+
         sd_ipv4ll_unref(link->ipv4ll);
         sd_dhcp6_client_unref(link->dhcp6_client);
         sd_icmp6_nd_unref(link->icmp6_router_discovery);
@@ -364,6 +387,16 @@ static int link_stop_clients(Link *link) {
                 }
         }
 
+        if (link->lldp) {
+
+                k = sd_lldp_stop(link->lldp);
+                if (k < 0) {
+                        log_link_warning(link, "Could not stop LLDP : %s",
+                                         strerror(-r));
+                        r = k;
+                }
+        }
+
         return r;
 }
 
@@ -656,6 +689,21 @@ int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata)
         return 1;
 }
 
+static int link_set_bridge_fdb(const Link *const link) {
+        FdbEntry *fdb_entry;
+        int r = 0;
+
+        LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
+                r = fdb_entry_configure(link->manager->rtnl, fdb_entry, link->ifindex);
+                if(r < 0) {
+                        log_link_error(link, "Failed to add MAC entry to static MAC table: %s", strerror(-r));
+                        break;
+                }
+        }
+
+        return r;
+}
+
 static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
         _cleanup_link_unref_ Link *link = userdata;
         int r;
@@ -857,6 +905,23 @@ static int link_set_bridge(Link *link) {
         return r;
 }
 
+static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
+        Link *link = userdata;
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(link->manager);
+
+        if (event != UPDATE_INFO)
+                return;
+
+        r = sd_lldp_save(link->lldp, link->lldp_file);
+        if (r < 0)
+                log_link_warning(link, "could not save LLDP");
+
+}
+
 static int link_acquire_conf(Link *link) {
         int r;
 
@@ -904,6 +969,18 @@ static int link_acquire_conf(Link *link) {
                 }
         }
 
+        if (link_lldp_enabled(link)) {
+                assert(link->lldp);
+
+                log_link_debug(link, "Starting LLDP");
+
+                r = sd_lldp_start(link->lldp);
+                if (r < 0) {
+                        log_link_warning(link, "could not start LLDP ");
+                        return r;
+                }
+        }
+
         return 0;
 }
 
@@ -1147,6 +1224,10 @@ static int link_configure(Link *link) {
         assert(link->network);
         assert(link->state == LINK_STATE_PENDING);
 
+        r = link_set_bridge_fdb(link);
+        if (r < 0)
+                return r;
+
         if (link_ipv4ll_enabled(link)) {
                 r = ipv4ll_configure(link);
                 if (r < 0)
@@ -1175,6 +1256,21 @@ static int link_configure(Link *link) {
                         return r;
         }
 
+        if (link_lldp_enabled(link)) {
+                r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
+                if (r < 0)
+                        return r;
+
+                r = sd_lldp_attach_event(link->lldp, NULL, 0);
+                if (r < 0)
+                        return r;
+
+                r = sd_lldp_set_callback(link->lldp,
+                                         lldp_handler, link);
+                if (r < 0)
+                        return r;
+        }
+
         if (link_has_carrier(link)) {
                 r = link_acquire_conf(link);
                 if (r < 0)
@@ -1791,6 +1887,19 @@ int link_save(Link *link) {
         } else
                 unlink(link->lease_file);
 
+        if (link->lldp) {
+                assert(link->network);
+
+                r = sd_lldp_save(link->lldp, link->lldp_file);
+                if (r < 0)
+                        goto fail;
+
+                fprintf(f,
+                        "LLDP_FILE=%s\n",
+                        link->lldp_file);
+        } else
+                unlink(link->lldp_file);
+
         r = fflush_and_check(f);
         if (r < 0)
                 goto fail;