mirror of
https://github.com/systemd/systemd
synced 2024-10-07 08:40:44 +00:00
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:
parent
33859a6bf5
commit
b553a6b13c
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue