Handle weighted Subnets in switch and hub modes.

We now handle MAC Subnets in exactly the same way as IPv4 and IPv6 Subnets.
This also fixes a problem that causes unncessary broadcasting of unicast
packets in VPNs where some daemons run 1.0.10 and some run other versions.
This commit is contained in:
Guus Sliepen 2009-10-20 22:33:16 +02:00
parent 3a925479c2
commit 43a6e78664
2 changed files with 41 additions and 3 deletions

View file

@ -117,6 +117,7 @@ static void learn_mac(mac_t *address) {
subnet->type = SUBNET_MAC;
subnet->expires = now + macexpire;
subnet->net.mac.address = *address;
subnet->weight = 10;
subnet_add(myself, subnet);
/* And tell all other tinc daemons it's our MAC */

View file

@ -47,9 +47,15 @@ static subnet_t *cache_ipv6_subnet[2];
static bool cache_ipv6_valid[2];
static int cache_ipv6_slot;
static mac_t cache_mac_address[2];
static subnet_t *cache_mac_subnet[2];
static bool cache_mac_valid[2];
static int cache_mac_slot;
void subnet_cache_flush() {
cache_ipv4_valid[0] = cache_ipv4_valid[1] = false;
cache_ipv6_valid[0] = cache_ipv6_valid[1] = false;
cache_mac_valid[0] = cache_mac_valid[1] = false;
}
/* Subnet comparison */
@ -324,15 +330,46 @@ subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) {
}
subnet_t *lookup_subnet_mac(const mac_t *address) {
subnet_t *p, subnet = {0};
subnet_t *p, *r = NULL, subnet = {0};
avl_node_t *n;
int i;
// Check if this address is cached
for(i = 0; i < 2; i++) {
if(!cache_mac_valid[i])
continue;
if(!memcmp(address, &cache_mac_address[i], sizeof *address))
return cache_mac_subnet[i];
}
// Search all subnets for a matching one
subnet.type = SUBNET_MAC;
subnet.net.mac.address = *address;
subnet.owner = NULL;
p = avl_search(subnet_tree, &subnet);
for(n = subnet_tree->head; n; n = n->next) {
p = n->data;
if(!p || p->type != subnet.type)
continue;
return p;
if(!memcmp(address, &p->net.mac.address, sizeof *address)) {
r = p;
if(p->owner->status.reachable)
break;
}
}
// Cache the result
cache_mac_slot = !cache_mac_slot;
memcpy(&cache_mac_address[cache_mac_slot], address, sizeof *address);
cache_mac_subnet[cache_mac_slot] = r;
cache_mac_valid[cache_mac_slot] = true;
return r;
}
subnet_t *lookup_subnet_ipv4(const ipv4_t *address) {