aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2012-03-10 17:17:53 -0500
committerAntonio Quartulli <ordex@autistici.org>2012-05-11 07:56:05 -0400
commit13b2541b11b1df346805f0869c843635ceb0229f (patch)
treebc1c44eaedb0083dac3cb880b8b01e126d57aab7 /net/batman-adv
parent9d853f624691776232a675768bcdb239d7b837ea (diff)
batman-adv: avoid temporary routing loops by being strict on forwarded OGMs
batman-adv would forward OGMs from non-besthops while replacing the the TQ and TTL values with the values from the best hop. In certain corner cases this leads to a temporary routing loop. This patch changes this behavior: Only packets from best next hops are forwarded - TQ and TTL values won't be replaced anymore. However, the protocol needs to rebroadcast OGMs from single hop neighbors regardless of whether or not they are the best hop. To handle this case a new flag is introduced to alert neighboring nodes about the forwarded OGM that is not from my best next hop. It is to be discarded by all nodes except for the one originating the OGM. Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Acked-by: Daniele Furlan <daniele.furlan@gmail.com> Tested-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/bat_iv_ogm.c60
-rw-r--r--net/batman-adv/packet.h1
2 files changed, 32 insertions, 29 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 9074e743ad61..bafb47370b4c 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -507,11 +507,10 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node,
507 const struct ethhdr *ethhdr, 507 const struct ethhdr *ethhdr,
508 struct batman_ogm_packet *batman_ogm_packet, 508 struct batman_ogm_packet *batman_ogm_packet,
509 bool is_single_hop_neigh, 509 bool is_single_hop_neigh,
510 bool is_from_best_next_hop,
510 struct hard_iface *if_incoming) 511 struct hard_iface *if_incoming)
511{ 512{
512 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 513 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
513 struct neigh_node *router;
514 uint8_t in_tq, in_ttl, tq_avg = 0;
515 uint8_t tt_num_changes; 514 uint8_t tt_num_changes;
516 515
517 if (batman_ogm_packet->header.ttl <= 1) { 516 if (batman_ogm_packet->header.ttl <= 1) {
@@ -519,41 +518,30 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node,
519 return; 518 return;
520 } 519 }
521 520
522 router = orig_node_get_router(orig_node); 521 if (!is_from_best_next_hop) {
522 /* Mark the forwarded packet when it is not coming from our
523 * best next hop. We still need to forward the packet for our
524 * neighbor link quality detection to work in case the packet
525 * originated from a single hop neighbor. Otherwise we can
526 * simply drop the ogm.
527 */
528 if (is_single_hop_neigh)
529 batman_ogm_packet->flags |= NOT_BEST_NEXT_HOP;
530 else
531 return;
532 }
523 533
524 in_tq = batman_ogm_packet->tq;
525 in_ttl = batman_ogm_packet->header.ttl;
526 tt_num_changes = batman_ogm_packet->tt_num_changes; 534 tt_num_changes = batman_ogm_packet->tt_num_changes;
527 535
528 batman_ogm_packet->header.ttl--; 536 batman_ogm_packet->header.ttl--;
529 memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN); 537 memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
530 538
531 /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
532 * of our best tq value */
533 if (router && router->tq_avg != 0) {
534
535 /* rebroadcast ogm of best ranking neighbor as is */
536 if (!compare_eth(router->addr, ethhdr->h_source)) {
537 batman_ogm_packet->tq = router->tq_avg;
538
539 if (router->last_ttl)
540 batman_ogm_packet->header.ttl =
541 router->last_ttl - 1;
542 }
543
544 tq_avg = router->tq_avg;
545 }
546
547 if (router)
548 neigh_node_free_ref(router);
549
550 /* apply hop penalty */ 539 /* apply hop penalty */
551 batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv); 540 batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv);
552 541
553 bat_dbg(DBG_BATMAN, bat_priv, 542 bat_dbg(DBG_BATMAN, bat_priv,
554 "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", 543 "Forwarding packet: tq: %i, ttl: %i\n",
555 in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1, 544 batman_ogm_packet->tq, batman_ogm_packet->header.ttl);
556 batman_ogm_packet->header.ttl);
557 545
558 batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno); 546 batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
559 batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc); 547 batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);
@@ -949,6 +937,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
949 int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 937 int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
950 int is_broadcast = 0, is_bidirectional; 938 int is_broadcast = 0, is_bidirectional;
951 bool is_single_hop_neigh = false; 939 bool is_single_hop_neigh = false;
940 bool is_from_best_next_hop = false;
952 int is_duplicate; 941 int is_duplicate;
953 uint32_t if_incoming_seqno; 942 uint32_t if_incoming_seqno;
954 943
@@ -1070,6 +1059,13 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
1070 return; 1059 return;
1071 } 1060 }
1072 1061
1062 if (batman_ogm_packet->flags & NOT_BEST_NEXT_HOP) {
1063 bat_dbg(DBG_BATMAN, bat_priv,
1064 "Drop packet: ignoring all packets not forwarded from "
1065 "the best next hop (sender: %pM)\n", ethhdr->h_source);
1066 return;
1067 }
1068
1073 orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig); 1069 orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
1074 if (!orig_node) 1070 if (!orig_node)
1075 return; 1071 return;
@@ -1094,6 +1090,10 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
1094 if (router) 1090 if (router)
1095 router_router = orig_node_get_router(router->orig_node); 1091 router_router = orig_node_get_router(router->orig_node);
1096 1092
1093 if ((router && router->tq_avg != 0) &&
1094 (compare_eth(router->addr, ethhdr->h_source)))
1095 is_from_best_next_hop = true;
1096
1097 /* avoid temporary routing loops */ 1097 /* avoid temporary routing loops */
1098 if (router && router_router && 1098 if (router && router_router &&
1099 (compare_eth(router->addr, batman_ogm_packet->prev_sender)) && 1099 (compare_eth(router->addr, batman_ogm_packet->prev_sender)) &&
@@ -1144,7 +1144,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
1144 1144
1145 /* mark direct link on incoming interface */ 1145 /* mark direct link on incoming interface */
1146 bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 1146 bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
1147 is_single_hop_neigh, if_incoming); 1147 is_single_hop_neigh, is_from_best_next_hop,
1148 if_incoming);
1148 1149
1149 bat_dbg(DBG_BATMAN, bat_priv, 1150 bat_dbg(DBG_BATMAN, bat_priv,
1150 "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); 1151 "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
@@ -1167,7 +1168,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
1167 bat_dbg(DBG_BATMAN, bat_priv, 1168 bat_dbg(DBG_BATMAN, bat_priv,
1168 "Forwarding packet: rebroadcast originator packet\n"); 1169 "Forwarding packet: rebroadcast originator packet\n");
1169 bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 1170 bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
1170 is_single_hop_neigh, if_incoming); 1171 is_single_hop_neigh, is_from_best_next_hop,
1172 if_incoming);
1171 1173
1172out_neigh: 1174out_neigh:
1173 if ((orig_neigh_node) && (!is_single_hop_neigh)) 1175 if ((orig_neigh_node) && (!is_single_hop_neigh))
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index f54969c61a1e..0ee1af770798 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -39,6 +39,7 @@ enum bat_packettype {
39#define COMPAT_VERSION 14 39#define COMPAT_VERSION 14
40 40
41enum batman_iv_flags { 41enum batman_iv_flags {
42 NOT_BEST_NEXT_HOP = 1 << 3,
42 PRIMARIES_FIRST_HOP = 1 << 4, 43 PRIMARIES_FIRST_HOP = 1 << 4,
43 VIS_SERVER = 1 << 5, 44 VIS_SERVER = 1 << 5,
44 DIRECTLINK = 1 << 6 45 DIRECTLINK = 1 << 6