From 92aefd25bf9e8e63f199cc252218f5c427f836b7 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 28 Nov 2009 11:52:23 +0000 Subject: [PATCH 1/3] When learning MAC addresses, only check our own Subnets for previous entries. Before it would check all addresses, and not learn an address if another node already claimed that address. This caused fast roaming to fail, the code from commit 6f6f426b353596edca77829c0477268fc2fc1925 was never triggered. --- src/route.c | 4 ++-- src/subnet.c | 8 +++++--- src/subnet.h | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/route.c b/src/route.c index 5c69671a..16423892 100644 --- a/src/route.c +++ b/src/route.c @@ -104,7 +104,7 @@ static void learn_mac(mac_t *address) { avl_node_t *node; connection_t *c; - subnet = lookup_subnet_mac(address); + subnet = lookup_subnet_mac(myself, address); /* If we don't know this MAC address yet, store it */ @@ -705,7 +705,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { /* Lookup destination address */ memcpy(&dest, &packet->data[0], sizeof dest); - subnet = lookup_subnet_mac(&dest); + subnet = lookup_subnet_mac(NULL, &dest); if(!subnet) { broadcast_packet(source, packet); diff --git a/src/subnet.c b/src/subnet.c index 3d1168de..4d646a5d 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -329,7 +329,7 @@ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { return avl_search(owner->subnet_tree, subnet); } -subnet_t *lookup_subnet_mac(const mac_t *address) { +subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { subnet_t *p, *r = NULL, subnet = {0}; avl_node_t *n; int i; @@ -339,6 +339,8 @@ subnet_t *lookup_subnet_mac(const mac_t *address) { for(i = 0; i < 2; i++) { if(!cache_mac_valid[i]) continue; + if(owner && cache_mac_subnet[i] && cache_mac_subnet[i]->owner != owner) + continue; if(!memcmp(address, &cache_mac_address[i], sizeof *address)) return cache_mac_subnet[i]; } @@ -349,10 +351,10 @@ subnet_t *lookup_subnet_mac(const mac_t *address) { subnet.net.mac.address = *address; subnet.owner = NULL; - for(n = subnet_tree->head; n; n = n->next) { + for(n = owner ? owner->subnet_tree->head : subnet_tree->head; n; n = n->next) { p = n->data; - if(!p || p->type != subnet.type) + if(!p || p->type != SUBNET_MAC) continue; if(!memcmp(address, &p->net.mac.address, sizeof *address)) { diff --git a/src/subnet.h b/src/subnet.h index c9bb10e8..b2124a0e 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -77,7 +77,7 @@ extern void subnet_update(struct node_t *, subnet_t *, bool); extern bool net2str(char *, int, const subnet_t *); extern bool str2net(subnet_t *, const char *); extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *); -extern subnet_t *lookup_subnet_mac(const mac_t *); +extern subnet_t *lookup_subnet_mac(const struct node_t *, const mac_t *); extern subnet_t *lookup_subnet_ipv4(const ipv4_t *); extern subnet_t *lookup_subnet_ipv6(const ipv6_t *); extern void dump_subnets(void); From 62f235e05c54e458724f437e519ed1b3e17835b1 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 28 Nov 2009 11:56:13 +0000 Subject: [PATCH 2/3] Remove unused variable in lookup_subnet_*() functions. --- src/subnet.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/subnet.c b/src/subnet.c index 4d646a5d..bc66fecc 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -330,7 +330,7 @@ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) { } subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { - subnet_t *p, *r = NULL, subnet = {0}; + subnet_t *p, *r = NULL; avl_node_t *n; int i; @@ -347,10 +347,6 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { // Search all subnets for a matching one - subnet.type = SUBNET_MAC; - subnet.net.mac.address = *address; - subnet.owner = NULL; - for(n = owner ? owner->subnet_tree->head : subnet_tree->head; n; n = n->next) { p = n->data; @@ -375,7 +371,7 @@ subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) { } subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { - subnet_t *p, *r = NULL, subnet = {0}; + subnet_t *p, *r = NULL; avl_node_t *n; int i; @@ -390,15 +386,10 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Search all subnets for a matching one - subnet.type = SUBNET_IPV4; - subnet.net.ipv4.address = *address; - subnet.net.ipv4.prefixlength = 32; - subnet.owner = NULL; - for(n = subnet_tree->head; n; n = n->next) { p = n->data; - if(!p || p->type != subnet.type) + if(!p || p->type != SUBNET_IPV4) continue; if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { @@ -419,7 +410,7 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { } subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { - subnet_t *p, *r = NULL, subnet = {0}; + subnet_t *p, *r = NULL; avl_node_t *n; int i; @@ -434,15 +425,10 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Search all subnets for a matching one - subnet.type = SUBNET_IPV6; - subnet.net.ipv6.address = *address; - subnet.net.ipv6.prefixlength = 128; - subnet.owner = NULL; - for(n = subnet_tree->head; n; n = n->next) { p = n->data; - if(!p || p->type != subnet.type) + if(!p || p->type != SUBNET_IPV6) continue; if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { From 369fe1ab1cbfc3f8305de1faab2e30157378b044 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 8 Dec 2009 22:18:37 +0000 Subject: [PATCH 3/3] Forget addresses of unreachable nodes. We clear the cached address used for UDP connections when a node becomes unreachable. This also prevents host-up scripts from passing the old, cached address from when the host becomes reachable again from a different address. --- src/graph.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/graph.c b/src/graph.c index 148f23c4..f5aff5bf 100644 --- a/src/graph.c +++ b/src/graph.c @@ -286,6 +286,9 @@ void sssp_bfs(void) { free(envp[i]); subnet_update(n, NULL, n->status.reachable); + + if(!n->status.reachable) + update_node_udp(n, NULL); } } }