summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-02-19 17:58:52 +0100
committerLennart Poettering <lennart@poettering.net>2016-02-21 20:40:56 +0100
commit34437b4f9c9c51b0a6f93788bdb9a105b8e46b66 (patch)
tree4c5069ae6356036a4f347ca7acd8df8d0332d97c /src/network
parent1b4cd0cf11feb7d41f2eff17f86fa55b31bb6841 (diff)
sd-lldp: rework sd-lldp API
This reworks the sd-lldp substantially, simplifying things on one hand, and extending the logic a bit on the other. Specifically: - Besides the sd_lldp object only one other object is maintained now, sd_lldp_neighbor. It's used both as storage for literal LLDP packets, and for maintainging info about peers in the database. Separation between packet, TLV and chassis data is not maintained anymore. This should be a major simplification. - The sd-lldp API has been extended so that a couple of per-neighbor fields may be queried directly, without iterating through the object. Other fields that may appear multiple times, OTOH have to be iterated through. - The maximum number of entries in the neighbor database is now configurable during runtime. - The generation of callbacks from sd_lldp objects is more restricted: callbacks are only invoked when actual data changed. - The TTL information is now hooked with a timer event, so that removals from the neighbor database due to TTLs now result in a callback event. - Querying LLDP neighbor database will now return a strictly ordered array, to guarantee stability. - A "capabilities" mask may now be configured, that selects what type of LLDP neighbor data is collected. This may be used to restrict collection of LLDP info about routers instead of all neighbors. This is now exposed via networkd's LLDP= setting. - sd-lldp's API to serialize the collected data to text files has been removed. Instead, there's now an API to extract the raw binary data from LLDP neighbor objects, as well as one to convert this raw binary data back to an LLDP neighbor object. networkd will save this raw binary data to /run now, and the client side can simply parse the information. - support for parsing the more exotic TLVs has been removed, since we are not using that. Instead there are now APIs to extract the raw data from TLVs. Given how easy it is to parse the TLVs clients should do so now directly instead of relying on our APIs for that. - A lot of the APIs that parse out LLDP strings have been simplified so that they actually return strings, instead of char arrays with a length. To deal with possibly dangerous characters the strings are escaped if needed. - APIs to extract and format the chassis and port IDs as strings has been added. - lldp.h has been simplified a lot. The enums are anonymous now, since they were never used as enums, but simply as constants. Most definitions we don't actually use ourselves have eben removed.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkctl.c293
-rw-r--r--src/network/networkd-link.c124
-rw-r--r--src/network/networkd-network-gperf.gperf2
-rw-r--r--src/network/networkd-network.c10
-rw-r--r--src/network/networkd-network.h14
5 files changed, 192 insertions, 251 deletions
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 185bdaf293..eecdebd25d 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -23,6 +23,7 @@
#include "sd-device.h"
#include "sd-hwdb.h"
+#include "sd-lldp.h"
#include "sd-netlink.h"
#include "sd-network.h"
@@ -30,6 +31,7 @@
#include "arphrd-list.h"
#include "device-util.h"
#include "ether-addr-util.h"
+#include "fd-util.h"
#include "hwdb-util.h"
#include "lldp.h"
#include "local-addresses.h"
@@ -38,6 +40,7 @@
#include "pager.h"
#include "parse-util.h"
#include "socket-util.h"
+#include "sparse-endian.h"
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
@@ -745,162 +748,29 @@ static int link_status(int argc, char *argv[], void *userdata) {
return 0;
}
-const char *lldp_system_capability_to_string(LLDPSystemCapabilities d) _const_;
-LLDPSystemCapabilities lldp_system_capability_from_string(const char *d) _pure_;
-
-static const char* const lldp_system_capability_table[_LLDP_SYSTEM_CAPABILITIES_MAX + 1] = {
- [LLDP_SYSTEM_CAPABILITIES_OTHER] = "O",
- [LLDP_SYSTEM_CAPABILITIES_REPEATER] = "P",
- [LLDP_SYSTEM_CAPABILITIES_BRIDGE] = "B",
- [LLDP_SYSTEM_CAPABILITIES_WLAN_AP] = "W",
- [LLDP_SYSTEM_CAPABILITIES_ROUTER] = "R",
- [LLDP_SYSTEM_CAPABILITIES_PHONE] = "T",
- [LLDP_SYSTEM_CAPABILITIES_DOCSIS] = "D",
- [LLDP_SYSTEM_CAPABILITIES_STATION] = "A",
- [LLDP_SYSTEM_CAPABILITIES_CVLAN] = "C",
- [LLDP_SYSTEM_CAPABILITIES_SVLAN] = "S",
- [LLDP_SYSTEM_CAPABILITIES_TPMR] = "M",
- [_LLDP_SYSTEM_CAPABILITIES_MAX] = "N/A",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(lldp_system_capability, LLDPSystemCapabilities);
-
-static char *lldp_system_caps(uint16_t cap) {
- _cleanup_free_ char *s = NULL, *t = NULL;
- char *capability;
-
- t = strdup("[ ");
- if (!t)
- return NULL;
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_OTHER) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_OTHER), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_REPEATER) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_REPEATER), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_BRIDGE) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_BRIDGE), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_WLAN_AP) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_WLAN_AP), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_ROUTER) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_ROUTER), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_PHONE) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_PHONE), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_DOCSIS) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_DOCSIS), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_STATION) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_STATION), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_CVLAN) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_CVLAN), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_SVLAN) {
- s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_SVLAN), " ", NULL);
- if (!s)
- return NULL;
-
- free(t);
- t = s;
- }
-
- if (cap & LLDP_SYSTEM_CAPABILITIES_TPMR) {
- s = strappend(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_TPMR));
- if (!s)
- return NULL;
-
- free(t);
- }
-
- if (!s) {
- s = strappend(t, lldp_system_capability_to_string(_LLDP_SYSTEM_CAPABILITIES_MAX));
- if (!s)
- return NULL;
-
- free(t);
- }
+static char *lldp_capabilities_to_string(uint16_t x) {
+ static const char characters[] = {
+ 'o', 'p', 'b', 'w', 'r', 't', 'd', 'a', 'c', 's', 'm',
+ };
+ char *ret;
+ unsigned i;
- t = strappend(s, "]");
- if (!t)
+ ret = new(char, ELEMENTSOF(characters) + 1);
+ if (!ret)
return NULL;
- free(s);
- capability = t;
+ for (i = 0; i < ELEMENTSOF(characters); i++)
+ ret[i] = (x & (1U << i)) ? characters[i] : '.';
- s = NULL;
- t = NULL;
-
- return capability;
+ ret[i] = 0;
+ return ret;
}
static int link_lldp_status(int argc, char *argv[], void *userdata) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_free_ LinkInfo *links = NULL;
- double ttl = -1;
- uint32_t capability;
int i, r, c, j;
- const char *p;
- char **s;
pager_open_if_enabled();
@@ -925,88 +795,85 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
return rtnl_log_parse_error(c);
if (arg_legend)
- printf("%s %16s %24s %16s %16s\n", "Local Intf", "Device ID", "Port ID", "TTL", "Capability");
+ printf("%-16s %-17s %-16s %-11s %-17s %-16s\n",
+ "LINK",
+ "CHASSIS ID",
+ "SYSTEM NAME",
+ "CAPS",
+ "PORT ID",
+ "PORT DESCRIPTION");
for (i = j = 0; i < c; i++) {
- _cleanup_free_ char *chassis = NULL, *port = NULL, *cap = NULL, *lldp = NULL;
- _cleanup_strv_free_ char **l = NULL;
-
- r = sd_network_link_get_lldp(links[i].ifindex, &lldp);
- if (r < 0)
- continue;
-
- l = strv_split_newlines(lldp);
- if (!l)
- return -ENOMEM;
-
- STRV_FOREACH(s, l) {
-
- p = *s;
- for (;;) {
- _cleanup_free_ char *a = NULL, *b = NULL, *word = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
- if (r < 0)
- return log_error_errno(r, "Failed to parse LLDP syntax \"%s\": %m", *s);
-
- if (r == 0)
- break;
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_free_ char *p = NULL;
- r = split_pair(word, "=", &a, &b);
- if (r < 0)
- continue;
+ if (asprintf(&p, "/run/systemd/netif/lldp/%i", links[i].ifindex) < 0)
+ return log_oom();
- if (streq(a, "_Chassis")) {
- r = free_and_strdup(&chassis, b);
- if (r < 0)
- return r;
-
- } else if (streq(a, "_Port")) {
- r = free_and_strdup(&port, b);
- if (r < 0)
- return r;
-
- } else if (streq(a, "_TTL")) {
- long long unsigned x = 0;
- usec_t time;
-
- r = safe_atollu(b, &x);
- if (r < 0 || (usec_t) x != x)
- return log_warning_errno(r < 0 ? r : ERANGE,
- "Failed to parse TTL \"%s\": %m", b);
+ f = fopen(p, "re");
+ if (!f) {
+ if (errno == ENOENT)
+ continue;
- time = now(clock_boottime_or_monotonic());
- if (x < time)
- continue;
+ log_warning_errno(errno, "Failed to open %s, ignoring: %m", p);
+ continue;
+ }
- ttl = (double) (x - time) / USEC_PER_SEC;
+ for (;;) {
+ const char *chassis_id = NULL, *port_id = NULL, *system_name = NULL, *port_description = NULL, *capabilities = NULL;
+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL;
+ _cleanup_free_ void *raw = NULL;
+ uint16_t cc;
+ le64_t u;
+ size_t l;
- } else if (streq(a, "_CAP")) {
- sscanf(b, "%x", &capability);
+ l = fread(&u, 1, sizeof(u), f);
+ if (l == 0 && feof(f)) /* EOF */
+ break;
+ if (l != sizeof(u)) {
+ log_warning("Premature end of file, ignoring.");
+ break;
+ }
- cap = lldp_system_caps(capability);
- }
+ raw = new(uint8_t, le64toh(u));
+ if (!raw)
+ return log_oom();
+ if (fread(raw, 1, le64toh(u), f) != le64toh(u)) {
+ log_warning("Premature end of file, ignoring.");
+ break;
}
- if (ttl >= 0) {
- printf("%10s %24s %16s %16f %16s\n",
- links[i].name,
- strna(chassis), strna(port),
- ttl, cap);
- j++;
+ r = sd_lldp_neighbor_from_raw(&n, raw, le64toh(u));
+ if (r < 0) {
+ log_warning_errno(r, "Failed to parse LLDP data, ignoring: %m");
+ break;
}
+
+ (void) sd_lldp_neighbor_get_chassis_id_as_string(n, &chassis_id);
+ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id);
+ (void) sd_lldp_neighbor_get_system_name(n, &system_name);
+ (void) sd_lldp_neighbor_get_port_description(n, &port_description);
+
+ if (sd_lldp_neighbor_get_enabled_capabilities(n, &cc) >= 0)
+ capabilities = lldp_capabilities_to_string(cc);
+
+ printf("%-16s %-17s %-16s %-11s %-17s %-16s\n",
+ links[i].name,
+ strna(chassis_id),
+ strna(system_name),
+ strna(capabilities),
+ strna(port_id),
+ strna(port_description));
}
}
- if (arg_legend) {
- printf("\nCapability Codes:\n"
- "(O) - Other, (P) - Repeater, (B) - Bridge , (W) - WLAN Access Point, (R) = Router,\n"
- "(T) - Telephone, (D) - Data Over Cable Service Interface Specifications, (A) - Station,\n"
- "(C) - Customer VLAN, (S) - Service VLAN, (M) - Two-port MAC Relay (TPMR)\n\n");
-
- printf("Total entries displayed: %d\n", j);
- }
+ if (arg_legend)
+ printf("\nCapabilities:\n"
+ "o - Other; p - Repeater; b - Bridge; w - WLAN Access Point; r - Router;\n"
+ "t - Telephone; d - DOCSIS cable device; a - Station; c - Customer VLAN;\n"
+ "s - Service VLAN, m - Two-port MAC Relay (TPMR)\n\n"
+ "Total entries displayed: %i\n", j);
return 0;
}
@@ -1022,7 +889,7 @@ static void help(void) {
"Commands:\n"
" list List links\n"
" status [LINK...] Show link status\n"
- " lldp Show lldp information\n"
+ " lldp Show lldp neighbors\n"
, program_invocation_short_name);
}
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index e63af3afdb..02fb04e0cb 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -26,6 +26,7 @@
#include "dhcp-lease-internal.h"
#include "fd-util.h"
#include "fileio.h"
+#include "lldp.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "networkd-link.h"
@@ -103,7 +104,7 @@ bool link_lldp_enabled(Link *link) {
if (link->network->bridge)
return false;
- return link->network->lldp;
+ return link->network->lldp_mode != LLDP_MODE_NO;
}
static bool link_ipv4_forward_enabled(Link *link) {
@@ -347,18 +348,15 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
if (r < 0)
- log_link_debug(link, "MAC address not found for new device, continuing without");
+ log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
- r = asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex);
- if (r < 0)
+ if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
return -ENOMEM;
- r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex);
- if (r < 0)
+ if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
return -ENOMEM;
- r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex);
- if (r < 0)
+ if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
return -ENOMEM;
r = hashmap_ensure_allocated(&manager->links, NULL);
@@ -409,7 +407,6 @@ static void link_free(Link *link) {
free(link->lease_file);
sd_lldp_unref(link->lldp);
-
free(link->lldp_file);
sd_ipv4ll_unref(link->ipv4ll);
@@ -1218,7 +1215,7 @@ static int link_set_bridge(Link *link) {
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
- if(link->network->cost != 0) {
+ if (link->network->cost != 0) {
r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
@@ -1237,24 +1234,83 @@ 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;
+static int link_lldp_save(Link *link) {
+ _cleanup_free_ char *temp_path = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ sd_lldp_neighbor **l = NULL;
+ int n = 0, r, i;
assert(link);
- assert(link->network);
- assert(link->manager);
+ assert(link->lldp_file);
+
+ if (!link->lldp) {
+ (void) unlink(link->lldp_file);
+ return 0;
+ }
+
+ r = sd_lldp_get_neighbors(link->lldp, &l);
+ if (r < 0)
+ goto finish;
+ if (r == 0) {
+ (void) unlink(link->lldp_file);
+ goto finish;
+ }
+
+ n = r;
+
+ r = fopen_temporary(link->lldp_file, &f, &temp_path);
+ if (r < 0)
+ goto finish;
+
+ fchmod(fileno(f), 0644);
- switch (event) {
- case SD_LLDP_EVENT_UPDATE_INFO:
- r = sd_lldp_save(link->lldp, link->lldp_file);
+ for (i = 0; i < n; i++) {
+ const void *p;
+ le64_t u;
+ size_t sz;
+
+ r = sd_lldp_neighbor_get_raw(l[i], &p, &sz);
if (r < 0)
- log_link_warning_errno(link, r, "Could not save LLDP: %m");
+ goto finish;
+
+ u = htole64(sz);
+ (void) fwrite(&u, 1, sizeof(u), f);
+ (void) fwrite(p, 1, sz, f);
+ }
- break;
- default:
- break;
+ r = fflush_and_check(f);
+ if (r < 0)
+ goto finish;
+
+ if (rename(temp_path, link->lldp_file) < 0) {
+ r = -errno;
+ goto finish;
}
+
+finish:
+ if (r < 0) {
+ (void) unlink(link->lldp_file);
+ if (temp_path)
+ (void) unlink(temp_path);
+
+ log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file);
+ }
+
+ if (l) {
+ for (i = 0; i < n; i++)
+ sd_lldp_neighbor_unref(l[i]);
+ free(l);
+ }
+
+ return r;
+}
+
+static void lldp_handler(sd_lldp *lldp, void *userdata) {
+ Link *link = userdata;
+
+ assert(link);
+
+ (void) link_lldp_save(link);
}
static int link_acquire_ipv6_conf(Link *link) {
@@ -2116,7 +2172,14 @@ static int link_configure(Link *link) {
}
if (link_lldp_enabled(link)) {
- r = sd_lldp_new(link->ifindex, &link->lldp);
+ r = sd_lldp_new(&link->lldp, link->ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_lldp_match_capabilities(link->lldp,
+ link->network->lldp_mode == LLDP_MODE_ROUTERS_ONLY ?
+ _LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS :
+ _LLDP_SYSTEM_CAPABILITIES_ALL);
if (r < 0)
return r;
@@ -2714,6 +2777,8 @@ int link_save(Link *link) {
return 0;
}
+ link_lldp_save(link);
+
admin_state = link_state_to_string(link->state);
assert(admin_state);
@@ -2953,19 +3018,6 @@ int link_save(Link *link) {
}
}
- 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;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 409df1709f..d67da5d7b6 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -40,7 +40,7 @@ Network.DHCPServer, config_parse_bool,
Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local)
Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route)
Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token)
-Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp)
+Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode)
Network.Address, config_parse_address, 0, 0
Network.Gateway, config_parse_gateway, 0, 0
Network.Domains, config_parse_domains, 0, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 4315790093..a6512d26e5 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -1013,3 +1013,13 @@ static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains, DHCPUseDomains, DHCP_USE_DOMAINS_YES);
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode, lldp_mode, LLDPMode, "Failed to parse LLDP= setting.");
+
+static const char* const lldp_mode_table[_LLDP_MODE_MAX] = {
+ [LLDP_MODE_NO] = "no",
+ [LLDP_MODE_YES] = "yes",
+ [LLDP_MODE_ROUTERS_ONLY] = "routers-only",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode, LLDPMode, LLDP_MODE_YES);
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 03c3f206c3..9dcebfbf7b 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -58,6 +58,14 @@ typedef enum DHCPUseDomains {
_DHCP_USE_DOMAINS_INVALID = -1,
} DHCPUseDomains;
+typedef enum LLDPMode {
+ LLDP_MODE_NO = 0,
+ LLDP_MODE_YES = 1,
+ LLDP_MODE_ROUTERS_ONLY = 2,
+ _LLDP_MODE_MAX,
+ _LLDP_MODE_INVALID = -1,
+} LLDPMode;
+
struct Network {
Manager *manager;
@@ -137,7 +145,7 @@ struct Network {
struct ether_addr *mac;
unsigned mtu;
- bool lldp;
+ LLDPMode lldp_mode;
LIST_HEAD(Address, static_addresses);
LIST_HEAD(Route, static_routes);
@@ -181,6 +189,7 @@ int config_parse_dhcp_server_dns(const char *unit, const char *filename, unsigne
int config_parse_dhcp_server_ntp(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_dnssec_negative_trust_anchors(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_dhcp_use_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_lldp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* Legacy IPv4LL support */
int config_parse_ipv4ll(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -197,3 +206,6 @@ IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_;
const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;
+
+const char* lldp_mode_to_string(LLDPMode m) _const_;
+LLDPMode lldp_mode_from_string(const char *s) _pure_;