When learning MAC addresses, only check our own Subnets for previous entries.
authorGuus Sliepen <guus@tinc-vpn.org>
Sat, 28 Nov 2009 11:52:23 +0000 (11:52 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Sat, 28 Nov 2009 11:52:23 +0000 (11:52 +0000)
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
src/subnet.c
src/subnet.h

index 5c69671ad30a7d55602569defe55db43eb970f9d..16423892fa58c479c987d520a26fa6dae1d7afd3 100644 (file)
@@ -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);
index 3d1168dee2600c69416bf91c7ad4ca623195a3ce..4d646a5d4ae09ce4518eecaacd32b6ec57fc827f 100644 (file)
@@ -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)) {
index c9bb10e8a8fdb161221ef51f8f40148459b06312..b2124a0ef87037a00d00b9daed4cbf411c3b1270 100644 (file)
@@ -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);