Don't forward frames with local destination MAC address

This commit is contained in:
Matthias Schiffer 2014-09-26 15:45:22 +02:00
parent d90524202c
commit b63d267e79
3 changed files with 23 additions and 11 deletions

View file

@ -862,7 +862,7 @@ static int peer_eth_addr_cmp(const fastd_peer_eth_addr_t *addr1, const fastd_pee
void fastd_peer_eth_addr_add(fastd_peer_t *peer, fastd_eth_addr_t addr) { void fastd_peer_eth_addr_add(fastd_peer_t *peer, fastd_eth_addr_t addr) {
int min = 0, max = VECTOR_LEN(ctx.eth_addrs); int min = 0, max = VECTOR_LEN(ctx.eth_addrs);
if (!fastd_peer_is_established(peer)) if (peer && !fastd_peer_is_established(peer))
exit_bug("tried to learn ethernet address on non-established peer"); exit_bug("tried to learn ethernet address on non-established peer");
while (max > min) { while (max > min) {
@ -884,18 +884,22 @@ void fastd_peer_eth_addr_add(fastd_peer_t *peer, fastd_eth_addr_t addr) {
VECTOR_INSERT(ctx.eth_addrs, ((fastd_peer_eth_addr_t) {addr, peer, ctx.now + ETH_ADDR_STALE_TIME}), min); VECTOR_INSERT(ctx.eth_addrs, ((fastd_peer_eth_addr_t) {addr, peer, ctx.now + ETH_ADDR_STALE_TIME}), min);
pr_debug("learned new MAC address %E on peer %P", &addr, peer); if (peer)
pr_debug("learned new MAC address %E on peer %P", &addr, peer);
else
pr_debug("learned new local MAC address %E", &addr);
} }
/** Finds the peer that is associated with a given MAC address */ /** Finds the peer that is associated with a given MAC address */
fastd_peer_t * fastd_peer_find_by_eth_addr(const fastd_eth_addr_t addr) { bool fastd_peer_find_by_eth_addr(const fastd_eth_addr_t addr, fastd_peer_t **peer) {
const fastd_peer_eth_addr_t key = {.addr = addr}; const fastd_peer_eth_addr_t key = {.addr = addr};
fastd_peer_eth_addr_t *peer_eth_addr = VECTOR_BSEARCH(&key, ctx.eth_addrs, peer_eth_addr_cmp); fastd_peer_eth_addr_t *peer_eth_addr = VECTOR_BSEARCH(&key, ctx.eth_addrs, peer_eth_addr_cmp);
if (peer_eth_addr) if (!peer_eth_addr)
return peer_eth_addr->peer; return false;
else
return NULL; *peer = peer_eth_addr->peer;
return true;
} }
/** /**

View file

@ -271,7 +271,7 @@ static inline bool fastd_eth_addr_is_unicast(fastd_eth_addr_t addr) {
} }
void fastd_peer_eth_addr_add(fastd_peer_t *peer, fastd_eth_addr_t addr); void fastd_peer_eth_addr_add(fastd_peer_t *peer, fastd_eth_addr_t addr);
fastd_peer_t * fastd_peer_find_by_eth_addr(fastd_eth_addr_t addr); bool fastd_peer_find_by_eth_addr(const fastd_eth_addr_t addr, fastd_peer_t **peer);
void fastd_peer_handle_handshake_queue(void); void fastd_peer_handle_handshake_queue(void);
void fastd_peer_maintenance(void); void fastd_peer_maintenance(void);

View file

@ -206,16 +206,24 @@ static inline bool send_data_tap_single(fastd_buffer_t buffer, fastd_peer_t *sou
return true; return true;
} }
if (!source) {
fastd_eth_addr_t src_addr = fastd_buffer_source_address(buffer);
if (fastd_eth_addr_is_unicast(src_addr))
fastd_peer_eth_addr_add(NULL, src_addr);
}
fastd_eth_addr_t dest_addr = fastd_buffer_dest_address(buffer); fastd_eth_addr_t dest_addr = fastd_buffer_dest_address(buffer);
if (!fastd_eth_addr_is_unicast(dest_addr)) if (!fastd_eth_addr_is_unicast(dest_addr))
return false; return false;
fastd_peer_t *dest = fastd_peer_find_by_eth_addr(dest_addr); fastd_peer_t *dest;
bool found = fastd_peer_find_by_eth_addr(dest_addr, &dest);
if (!dest) if (!found)
return false; return false;
if (dest == source) { if (!dest || dest == source) {
fastd_buffer_free(buffer); fastd_buffer_free(buffer);
return true; return true;
} }