Allow broadcast packets to be sent directly instead of via the MST.

When the "Broadcast = direct" option is used, broadcast packets are not sent
and forwarded via the Minimum Spanning Tree to all nodes, but are sent directly
to all nodes that can be reached in one hop.

One use for this is to allow running ad-hoc routing protocols, such as OLSR, on
top of tinc.
This commit is contained in:
Guus Sliepen 2012-04-16 01:57:25 +02:00
parent 535a55100b
commit 84531fb6e6
6 changed files with 97 additions and 22 deletions

View file

@ -584,24 +584,50 @@ void send_packet(const node_t *n, vpn_packet_t *packet) {
void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
avl_node_t *node;
connection_t *c;
node_t *n;
// Always give ourself a copy of the packet.
if(from != myself)
send_packet(myself, packet);
// In TunnelServer mode, do not forward broadcast packets.
// The MST might not be valid and create loops.
if(tunnelserver || broadcast_mode == BMODE_NONE)
return;
ifdebug(TRAFFIC) logger(LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)",
packet->len, from->name, from->hostname);
if(from != myself) {
send_packet(myself, packet);
switch(broadcast_mode) {
// In MST mode, broadcast packets travel via the Minimum Spanning Tree.
// This guarantees all nodes receive the broadcast packet, and
// usually distributes the sending of broadcast packets over all nodes.
case BMODE_MST:
for(node = connection_tree->head; node; node = node->next) {
c = node->data;
// In TunnelServer mode, do not forward broadcast packets.
// The MST might not be valid and create loops.
if(tunnelserver)
return;
}
if(c->status.active && c->status.mst && c != from->nexthop->connection)
send_packet(c->node, packet);
}
break;
for(node = connection_tree->head; node; node = node->next) {
c = node->data;
// In direct mode, we send copies to each node we know of.
// However, this only reaches nodes that can be reached in a single hop.
// We don't have enough information to forward broadcast packets in this case.
case BMODE_DIRECT:
if(from != myself)
break;
if(c->status.active && c->status.mst && c != from->nexthop->connection)
send_packet(c->node, packet);
for(node = node_udp_tree->head; node; node = node->next) {
n = node->data;
if(n->status.reachable && ((n->via == myself && n->nexthop == n) || n->via == n))
send_packet(c->node, packet);
}
break;
default:
break;
}
}

View file

@ -429,7 +429,19 @@ static bool setup_myself(void) {
get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);
get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl);
get_config_bool(lookup_config(config_tree, "Broadcast"), &broadcast);
if(get_config_string(lookup_config(config_tree, "Broadcast"), &mode)) {
if(!strcasecmp(mode, "no"))
broadcast_mode = BMODE_NONE;
else if(!strcasecmp(mode, "yes") || !strcasecmp(mode, "mst"))
broadcast_mode = BMODE_MST;
else if(!strcasecmp(mode, "direct"))
broadcast_mode = BMODE_DIRECT;
else {
logger(LOG_ERR, "Invalid broadcast mode!");
return false;
}
free(mode);
}
#if !defined(SOL_IP) || !defined(IP_TOS)
if(priorityinheritance)

View file

@ -34,12 +34,12 @@
rmode_t routing_mode = RMODE_ROUTER;
fmode_t forwarding_mode = FMODE_INTERNAL;
bmode_t broadcast_mode = BMODE_MST;
bool decrement_ttl = false;
bool directonly = false;
bool priorityinheritance = false;
int macexpire = 600;
bool overwrite_mac = false;
bool broadcast = true;
mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}};
/* Sizes of various headers */
@ -430,7 +430,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) {
if(!checklength(source, packet, ether_size + ip_size))
return;
if(broadcast && (((packet->data[30] & 0xf0) == 0xe0) || (
if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || (
packet->data[30] == 255 &&
packet->data[31] == 255 &&
packet->data[32] == 255 &&
@ -727,7 +727,7 @@ static void route_ipv6(node_t *source, vpn_packet_t *packet) {
return;
}
if(broadcast && packet->data[38] == 255)
if(broadcast_mode && packet->data[38] == 255)
broadcast_packet(source, packet);
else
route_ipv6_unicast(source, packet);
@ -817,8 +817,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
subnet = lookup_subnet_mac(NULL, &dest);
if(!subnet) {
if(broadcast)
broadcast_packet(source, packet);
broadcast_packet(source, packet);
return;
}

View file

@ -36,12 +36,18 @@ typedef enum fmode_t {
FMODE_KERNEL,
} fmode_t;
typedef enum bmode_t {
BMODE_NONE = 0,
BMODE_MST,
BMODE_DIRECT,
} bmode_t;
extern rmode_t routing_mode;
extern fmode_t forwarding_mode;
extern bmode_t broadcast_mode;
extern bool decrement_ttl;
extern bool directonly;
extern bool overwrite_mac;
extern bool broadcast;
extern bool priorityinheritance;
extern int macexpire;