From 5339e725f4e75b95bf4aecd55db125eef3d864ca Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 5 Dec 2011 19:03:30 +0100 Subject: [PATCH] Add a flag to specify which interfaces to use for chassis ID. lldpd will use the first interface matching the pattern for chassis ID. This will enable for example to always use "eth0". This closes #12. --- CHANGELOG | 1 + man/lldpd.8 | 13 +++++++++++ src/interfaces.c | 58 +++++++++++++++++++++++++++--------------------- src/lldpd.c | 7 +++++- src/lldpd.h | 1 + 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 63ea7b69..da95107e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ lldpd (0.6) * Features: + Allow lldpctl to display hidden ports. + + Add a switch to specify interfaces to use to get chassis ID. * Global changes: + Partial rewrite of the SNMP part. Less code. + Unit tests for SNMP. diff --git a/man/lldpd.8 b/man/lldpd.8 index 3952fc6d..447dd109 100644 --- a/man/lldpd.8 +++ b/man/lldpd.8 @@ -26,6 +26,7 @@ .Op Fl X Ar socket .Op Fl m Ar management .Op Fl I Ar interfaces +.Op Fl C Ar interfaces .Op Fl M Ar class .Op Fl H Ar hide .Sh DESCRIPTION @@ -133,6 +134,18 @@ with the exception of .Em eth1 and .Em eth2 . +.It Fl C Ar interfaces +Specify which interfaces to use for computing chassis ID. Without this +option, all interfaces are considered. +.Nm +will take the first MAC address from all the considered interfaces +to compute the chassis ID. The logic of this option is the same as for +.Fl I +flag: you can exclude interfaces with an exclamation mark and use +globbing to specify several interfaces. If all interfaces are +blacklisted (with +.Em !* ) , +the system name is used as a chassis ID instead. .It Fl M Ar class Enable emission of LLDP-MED frame. The class should be one of the following value: diff --git a/src/interfaces.c b/src/interfaces.c index 2a55d38c..781784b3 100644 --- a/src/interfaces.c +++ b/src/interfaces.c @@ -91,6 +91,35 @@ extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW; struct lldpd_ops eth_ops; struct lldpd_ops bond_ops; +static int +iface_match(char *iface, char *list) +{ + char *interfaces = NULL; + char *pattern; + int found = 0; + + if ((interfaces = strdup(list)) == NULL) { + LLOG_WARNX("unable to allocate memory"); + return 0; + } + + for (pattern = strtok(interfaces, ","); + pattern != NULL; + pattern = strtok(NULL, ",")) { + if ((pattern[0] == '!') && + ((fnmatch(pattern + 1, iface, 0) == 0))) { + /* Blacklisted. No need to search further. */ + found = 0; + break; + } + if (fnmatch(pattern, iface, 0) == 0) + found = 1; + } + + free(interfaces); + return found; +} + static int old_iface_is_bridge(struct lldpd *cfg, const char *name) { @@ -736,41 +765,18 @@ void lldpd_ifh_whitelist(struct lldpd *cfg, struct ifaddrs *ifap) { struct ifaddrs *ifa; - char *interfaces = NULL; - char *pattern; - int whitelisted; if (!cfg->g_interfaces) return; - if ((interfaces = strdup(cfg->g_interfaces)) == NULL) { - LLOG_WARNX("unable to allocate memory"); - return; - } for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_flags == 0) continue; /* Already handled by someone else */ - strcpy(interfaces, cfg->g_interfaces); /* Restore our list of interfaces */ - whitelisted = 0; - for (whitelisted = 0, pattern = strtok(interfaces, ","); - pattern != NULL; - pattern = strtok(NULL, ",")) { - if ((pattern[0] == '!') && - ((fnmatch(pattern + 1, ifa->ifa_name, 0) == 0))) { - /* Blacklisted. Definitive */ - whitelisted = 0; - break; - } - if (fnmatch(pattern, ifa->ifa_name, 0) == 0) - whitelisted = 1; - } - if (!whitelisted) { + if (!iface_match(ifa->ifa_name, cfg->g_interfaces)) { /* This interface was not found. We flag it. */ LLOG_DEBUG("blacklist %s", ifa->ifa_name); ifa->ifa_flags = 0; } } - - free(interfaces); } static int @@ -1089,7 +1095,9 @@ lldpd_ifh_chassis(struct lldpd *cfg, struct ifaddrs *ifap) return; /* We already have one */ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_flags) continue; /* This interface is not valid */ + if (ifa->ifa_flags) continue; + if (cfg->g_cid_pattern && + !iface_match(ifa->ifa_name, cfg->g_cid_pattern)) continue; if ((hardware = lldpd_get_hardware(cfg, ifa->ifa_name, diff --git a/src/lldpd.c b/src/lldpd.c index 6d2a3a29..5371aa80 100644 --- a/src/lldpd.c +++ b/src/lldpd.c @@ -1117,9 +1117,10 @@ lldpd_main(int argc, char *argv[]) char *agentx = NULL; /* AgentX socket */ #endif char *mgmtp = NULL; + char *cidp = NULL; char *interfaces = NULL; char *popt, opts[] = - "H:hkrdxX:m:I:p:M:S:i@ "; + "H:hkrdxX:m:I:C:p:M:S:i@ "; int i, found, advertise_version = 1; #ifdef ENABLE_LLDPMED int lldpmed = 0, noinventory = 0; @@ -1155,6 +1156,9 @@ lldpd_main(int argc, char *argv[]) case 'I': interfaces = optarg; break; + case 'C': + cidp = optarg; + break; case 'k': advertise_version = 0; break; @@ -1257,6 +1261,7 @@ lldpd_main(int argc, char *argv[]) fatal(NULL); cfg->g_mgmt_pattern = mgmtp; + cfg->g_cid_pattern = cidp; cfg->g_interfaces = interfaces; cfg->g_smart = smart; cfg->g_receiveonly = receiveonly; diff --git a/src/lldpd.h b/src/lldpd.h index 8bebd3a2..d7fed395 100644 --- a/src/lldpd.h +++ b/src/lldpd.h @@ -415,6 +415,7 @@ struct lldpd { TAILQ_HEAD(, lldpd_callback) g_callbacks; char *g_mgmt_pattern; + char *g_cid_pattern; char *g_interfaces; char *g_descr_override; -- 2.39.5