diff options
Diffstat (limited to 'net/batman-adv')
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 60 | ||||
-rw-r--r-- | net/batman-adv/packet.h | 1 |
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 | ||
1172 | out_neigh: | 1174 | out_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 | ||
41 | enum batman_iv_flags { | 41 | enum 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 |