From b63d267e79a54b1c1f0c3e987a28535055d5f574 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Sep 2014 15:45:22 +0200 Subject: Don't forward frames with local destination MAC address --- src/peer.c | 18 +++++++++++------- src/peer.h | 2 +- src/send.c | 14 +++++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/peer.c b/src/peer.c index 03e5716..7a05dbd 100644 --- a/src/peer.c +++ b/src/peer.c @@ -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) { 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"); 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); - 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 */ -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}; fastd_peer_eth_addr_t *peer_eth_addr = VECTOR_BSEARCH(&key, ctx.eth_addrs, peer_eth_addr_cmp); - if (peer_eth_addr) - return peer_eth_addr->peer; - else - return NULL; + if (!peer_eth_addr) + return false; + + *peer = peer_eth_addr->peer; + return true; } /** diff --git a/src/peer.h b/src/peer.h index 30c9156..ca03e2f 100644 --- a/src/peer.h +++ b/src/peer.h @@ -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); -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_maintenance(void); diff --git a/src/send.c b/src/send.c index 19f0649..8b9aae7 100644 --- a/src/send.c +++ b/src/send.c @@ -206,16 +206,24 @@ static inline bool send_data_tap_single(fastd_buffer_t buffer, fastd_peer_t *sou 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); if (!fastd_eth_addr_is_unicast(dest_addr)) 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; - if (dest == source) { + if (!dest || dest == source) { fastd_buffer_free(buffer); return true; } -- cgit v1.2.3