sd-lldp: filter out LLDP messages coming from our own MAC address

Let's not get confused should we be connected to some bridge that mirrors back
our packets.
This commit is contained in:
Lennart Poettering 2016-02-21 14:11:34 +01:00
parent 33859a6bf5
commit b553a6b13c
6 changed files with 55 additions and 1 deletions

View file

@ -42,3 +42,26 @@ char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR
return buffer;
}
bool ether_addr_is_null(const struct ether_addr *addr) {
assert(addr);
return addr->ether_addr_octet[0] == 0 &&
addr->ether_addr_octet[1] == 0 &&
addr->ether_addr_octet[2] == 0 &&
addr->ether_addr_octet[3] == 0 &&
addr->ether_addr_octet[4] == 0 &&
addr->ether_addr_octet[5] == 0;
}
bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
assert(a);
assert(b);
return a->ether_addr_octet[0] == b->ether_addr_octet[0] &&
a->ether_addr_octet[1] == b->ether_addr_octet[1] &&
a->ether_addr_octet[2] == b->ether_addr_octet[2] &&
a->ether_addr_octet[3] == b->ether_addr_octet[3] &&
a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
a->ether_addr_octet[5] == b->ether_addr_octet[5];
}

View file

@ -20,10 +20,13 @@
***/
#include <net/ethernet.h>
#include <stdbool.h>
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
#define ETHER_ADDR_TO_STRING_MAX (3*6)
char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
bool ether_addr_is_null(const struct ether_addr *addr);
bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);

View file

@ -45,6 +45,8 @@ struct sd_lldp {
void *userdata;
uint16_t capability_mask;
struct ether_addr filter_address;
};
#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)

View file

@ -28,6 +28,7 @@
#include "lldp-neighbor.h"
#include "lldp-network.h"
#include "socket-util.h"
#include "ether-addr-util.h"
#define LLDP_DEFAULT_NEIGHBORS_MAX 128U
@ -99,6 +100,11 @@ static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
if (n->ttl <= 0)
return changed;
/* Filter out the filter address */
if (!ether_addr_is_null(&lldp->filter_address) &&
ether_addr_equal(&lldp->filter_address, &n->source_address))
return changed;
/* Only add if the neighbor has a capability we are interested in. Note that we also store all neighbors with
* no caps field set. */
if (n->has_capabilities &&
@ -438,3 +444,18 @@ _public_ int sd_lldp_match_capabilities(sd_lldp *lldp, uint16_t mask) {
return 0;
}
_public_ int sd_lldp_set_filter_address(sd_lldp *lldp, const struct ether_addr *addr) {
assert_return(lldp, -EINVAL);
/* In order to deal nicely with bridges that send back our own packets, allow one address to be filtered, so
* that our own can be filtered out here. */
if (!addr) {
zero(lldp->filter_address);
return 0;
}
lldp->filter_address = *addr;
return 0;
}

View file

@ -2203,6 +2203,10 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
r = sd_lldp_set_filter_address(link->lldp, &link->mac);
if (r < 0)
return r;
r = sd_lldp_attach_event(link->lldp, NULL, 0);
if (r < 0)
return r;

View file

@ -49,6 +49,7 @@ int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata);
/* Controls how much and what to store in the neighbors database */
int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t n);
int sd_lldp_match_capabilities(sd_lldp *lldp, uint16_t mask);
int sd_lldp_set_filter_address(sd_lldp *lldp, const struct ether_addr *address);
int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***neighbors);