aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r--net/batman-adv/routing.c376
1 files changed, 297 insertions, 79 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index bb1c3ec7e3f..0f32c818874 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -64,28 +64,69 @@ void slide_own_bcast_window(struct hard_iface *hard_iface)
64 } 64 }
65} 65}
66 66
67static void update_TT(struct bat_priv *bat_priv, struct orig_node *orig_node, 67static void update_transtable(struct bat_priv *bat_priv,
68 unsigned char *tt_buff, int tt_buff_len) 68 struct orig_node *orig_node,
69 const unsigned char *tt_buff,
70 uint8_t tt_num_changes, uint8_t ttvn,
71 uint16_t tt_crc)
69{ 72{
70 if ((tt_buff_len != orig_node->tt_buff_len) || 73 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
71 ((tt_buff_len > 0) && 74 bool full_table = true;
72 (orig_node->tt_buff_len > 0) && 75
73 (memcmp(orig_node->tt_buff, tt_buff, tt_buff_len) != 0))) { 76 /* the ttvn increased by one -> we can apply the attached changes */
74 77 if (ttvn - orig_ttvn == 1) {
75 if (orig_node->tt_buff_len > 0) 78 /* the OGM could not contain the changes because they were too
76 tt_global_del_orig(bat_priv, orig_node, 79 * many to fit in one frame or because they have already been
77 "originator changed tt"); 80 * sent TT_OGM_APPEND_MAX times. In this case send a tt
78 81 * request */
79 if ((tt_buff_len > 0) && (tt_buff)) 82 if (!tt_num_changes) {
80 tt_global_add_orig(bat_priv, orig_node, 83 full_table = false;
81 tt_buff, tt_buff_len); 84 goto request_table;
85 }
86
87 tt_update_changes(bat_priv, orig_node, tt_num_changes, ttvn,
88 (struct tt_change *)tt_buff);
89
90 /* Even if we received the crc into the OGM, we prefer
91 * to recompute it to spot any possible inconsistency
92 * in the global table */
93 orig_node->tt_crc = tt_global_crc(bat_priv, orig_node);
94
95 /* The ttvn alone is not enough to guarantee consistency
96 * because a single value could repesent different states
97 * (due to the wrap around). Thus a node has to check whether
98 * the resulting table (after applying the changes) is still
99 * consistent or not. E.g. a node could disconnect while its
100 * ttvn is X and reconnect on ttvn = X + TTVN_MAX: in this case
101 * checking the CRC value is mandatory to detect the
102 * inconsistency */
103 if (orig_node->tt_crc != tt_crc)
104 goto request_table;
105
106 /* Roaming phase is over: tables are in sync again. I can
107 * unset the flag */
108 orig_node->tt_poss_change = false;
109 } else {
110 /* if we missed more than one change or our tables are not
111 * in sync anymore -> request fresh tt data */
112 if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
113request_table:
114 bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
115 "Need to retrieve the correct information "
116 "(ttvn: %u last_ttvn: %u crc: %u last_crc: "
117 "%u num_changes: %u)\n", orig_node->orig, ttvn,
118 orig_ttvn, tt_crc, orig_node->tt_crc,
119 tt_num_changes);
120 send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
121 full_table);
122 return;
123 }
82 } 124 }
83} 125}
84 126
85static void update_route(struct bat_priv *bat_priv, 127static void update_route(struct bat_priv *bat_priv,
86 struct orig_node *orig_node, 128 struct orig_node *orig_node,
87 struct neigh_node *neigh_node, 129 struct neigh_node *neigh_node)
88 unsigned char *tt_buff, int tt_buff_len)
89{ 130{
90 struct neigh_node *curr_router; 131 struct neigh_node *curr_router;
91 132
@@ -93,11 +134,10 @@ static void update_route(struct bat_priv *bat_priv,
93 134
94 /* route deleted */ 135 /* route deleted */
95 if ((curr_router) && (!neigh_node)) { 136 if ((curr_router) && (!neigh_node)) {
96
97 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", 137 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
98 orig_node->orig); 138 orig_node->orig);
99 tt_global_del_orig(bat_priv, orig_node, 139 tt_global_del_orig(bat_priv, orig_node,
100 "originator timed out"); 140 "Deleted route towards originator");
101 141
102 /* route added */ 142 /* route added */
103 } else if ((!curr_router) && (neigh_node)) { 143 } else if ((!curr_router) && (neigh_node)) {
@@ -105,11 +145,8 @@ static void update_route(struct bat_priv *bat_priv,
105 bat_dbg(DBG_ROUTES, bat_priv, 145 bat_dbg(DBG_ROUTES, bat_priv,
106 "Adding route towards: %pM (via %pM)\n", 146 "Adding route towards: %pM (via %pM)\n",
107 orig_node->orig, neigh_node->addr); 147 orig_node->orig, neigh_node->addr);
108 tt_global_add_orig(bat_priv, orig_node,
109 tt_buff, tt_buff_len);
110
111 /* route changed */ 148 /* route changed */
112 } else { 149 } else if (neigh_node && curr_router) {
113 bat_dbg(DBG_ROUTES, bat_priv, 150 bat_dbg(DBG_ROUTES, bat_priv,
114 "Changing route towards: %pM " 151 "Changing route towards: %pM "
115 "(now via %pM - was via %pM)\n", 152 "(now via %pM - was via %pM)\n",
@@ -133,10 +170,8 @@ static void update_route(struct bat_priv *bat_priv,
133 neigh_node_free_ref(curr_router); 170 neigh_node_free_ref(curr_router);
134} 171}
135 172
136
137void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 173void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
138 struct neigh_node *neigh_node, unsigned char *tt_buff, 174 struct neigh_node *neigh_node)
139 int tt_buff_len)
140{ 175{
141 struct neigh_node *router = NULL; 176 struct neigh_node *router = NULL;
142 177
@@ -146,11 +181,7 @@ void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
146 router = orig_node_get_router(orig_node); 181 router = orig_node_get_router(orig_node);
147 182
148 if (router != neigh_node) 183 if (router != neigh_node)
149 update_route(bat_priv, orig_node, neigh_node, 184 update_route(bat_priv, orig_node, neigh_node);
150 tt_buff, tt_buff_len);
151 /* may be just TT changed */
152 else
153 update_TT(bat_priv, orig_node, tt_buff, tt_buff_len);
154 185
155out: 186out:
156 if (router) 187 if (router)
@@ -165,7 +196,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
165 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 196 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
166 struct neigh_node *neigh_node = NULL, *tmp_neigh_node; 197 struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
167 struct hlist_node *node; 198 struct hlist_node *node;
168 unsigned char total_count; 199 uint8_t total_count;
169 uint8_t orig_eq_count, neigh_rq_count, tq_own; 200 uint8_t orig_eq_count, neigh_rq_count, tq_own;
170 int tq_asym_penalty, ret = 0; 201 int tq_asym_penalty, ret = 0;
171 202
@@ -348,9 +379,9 @@ out:
348} 379}
349 380
350/* copy primary address for bonding */ 381/* copy primary address for bonding */
351static void bonding_save_primary(struct orig_node *orig_node, 382static void bonding_save_primary(const struct orig_node *orig_node,
352 struct orig_node *orig_neigh_node, 383 struct orig_node *orig_neigh_node,
353 struct batman_packet *batman_packet) 384 const struct batman_packet *batman_packet)
354{ 385{
355 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) 386 if (!(batman_packet->flags & PRIMARIES_FIRST_HOP))
356 return; 387 return;
@@ -358,19 +389,16 @@ static void bonding_save_primary(struct orig_node *orig_node,
358 memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN); 389 memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN);
359} 390}
360 391
361static void update_orig(struct bat_priv *bat_priv, 392static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
362 struct orig_node *orig_node, 393 const struct ethhdr *ethhdr,
363 struct ethhdr *ethhdr, 394 const struct batman_packet *batman_packet,
364 struct batman_packet *batman_packet,
365 struct hard_iface *if_incoming, 395 struct hard_iface *if_incoming,
366 unsigned char *tt_buff, int tt_buff_len, 396 const unsigned char *tt_buff, int is_duplicate)
367 char is_duplicate)
368{ 397{
369 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 398 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
370 struct neigh_node *router = NULL; 399 struct neigh_node *router = NULL;
371 struct orig_node *orig_node_tmp; 400 struct orig_node *orig_node_tmp;
372 struct hlist_node *node; 401 struct hlist_node *node;
373 int tmp_tt_buff_len;
374 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 402 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
375 403
376 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 404 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
@@ -435,9 +463,6 @@ static void update_orig(struct bat_priv *bat_priv,
435 463
436 bonding_candidate_add(orig_node, neigh_node); 464 bonding_candidate_add(orig_node, neigh_node);
437 465
438 tmp_tt_buff_len = (tt_buff_len > batman_packet->num_tt * ETH_ALEN ?
439 batman_packet->num_tt * ETH_ALEN : tt_buff_len);
440
441 /* if this neighbor already is our next hop there is nothing 466 /* if this neighbor already is our next hop there is nothing
442 * to change */ 467 * to change */
443 router = orig_node_get_router(orig_node); 468 router = orig_node_get_router(orig_node);
@@ -467,15 +492,19 @@ static void update_orig(struct bat_priv *bat_priv,
467 goto update_tt; 492 goto update_tt;
468 } 493 }
469 494
470 update_routes(bat_priv, orig_node, neigh_node, 495 update_routes(bat_priv, orig_node, neigh_node);
471 tt_buff, tmp_tt_buff_len);
472 goto update_gw;
473 496
474update_tt: 497update_tt:
475 update_routes(bat_priv, orig_node, router, 498 /* I have to check for transtable changes only if the OGM has been
476 tt_buff, tmp_tt_buff_len); 499 * sent through a primary interface */
500 if (((batman_packet->orig != ethhdr->h_source) &&
501 (batman_packet->ttl > 2)) ||
502 (batman_packet->flags & PRIMARIES_FIRST_HOP))
503 update_transtable(bat_priv, orig_node, tt_buff,
504 batman_packet->tt_num_changes,
505 batman_packet->ttvn,
506 batman_packet->tt_crc);
477 507
478update_gw:
479 if (orig_node->gw_flags != batman_packet->gw_flags) 508 if (orig_node->gw_flags != batman_packet->gw_flags)
480 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); 509 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
481 510
@@ -531,15 +560,15 @@ static int window_protected(struct bat_priv *bat_priv,
531 * -1 the packet is old and has been received while the seqno window 560 * -1 the packet is old and has been received while the seqno window
532 * was protected. Caller should drop it. 561 * was protected. Caller should drop it.
533 */ 562 */
534static char count_real_packets(struct ethhdr *ethhdr, 563static int count_real_packets(const struct ethhdr *ethhdr,
535 struct batman_packet *batman_packet, 564 const struct batman_packet *batman_packet,
536 struct hard_iface *if_incoming) 565 const struct hard_iface *if_incoming)
537{ 566{
538 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 567 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
539 struct orig_node *orig_node; 568 struct orig_node *orig_node;
540 struct neigh_node *tmp_neigh_node; 569 struct neigh_node *tmp_neigh_node;
541 struct hlist_node *node; 570 struct hlist_node *node;
542 char is_duplicate = 0; 571 int is_duplicate = 0;
543 int32_t seq_diff; 572 int32_t seq_diff;
544 int need_update = 0; 573 int need_update = 0;
545 int set_mark, ret = -1; 574 int set_mark, ret = -1;
@@ -595,9 +624,9 @@ out:
595 return ret; 624 return ret;
596} 625}
597 626
598void receive_bat_packet(struct ethhdr *ethhdr, 627void receive_bat_packet(const struct ethhdr *ethhdr,
599 struct batman_packet *batman_packet, 628 struct batman_packet *batman_packet,
600 unsigned char *tt_buff, int tt_buff_len, 629 const unsigned char *tt_buff,
601 struct hard_iface *if_incoming) 630 struct hard_iface *if_incoming)
602{ 631{
603 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 632 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -605,10 +634,10 @@ void receive_bat_packet(struct ethhdr *ethhdr,
605 struct orig_node *orig_neigh_node, *orig_node; 634 struct orig_node *orig_neigh_node, *orig_node;
606 struct neigh_node *router = NULL, *router_router = NULL; 635 struct neigh_node *router = NULL, *router_router = NULL;
607 struct neigh_node *orig_neigh_router = NULL; 636 struct neigh_node *orig_neigh_router = NULL;
608 char has_directlink_flag; 637 int has_directlink_flag;
609 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 638 int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
610 char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; 639 int is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
611 char is_duplicate; 640 int is_duplicate;
612 uint32_t if_incoming_seqno; 641 uint32_t if_incoming_seqno;
613 642
614 /* Silently drop when the batman packet is actually not a 643 /* Silently drop when the batman packet is actually not a
@@ -636,12 +665,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
636 665
637 bat_dbg(DBG_BATMAN, bat_priv, 666 bat_dbg(DBG_BATMAN, bat_priv,
638 "Received BATMAN packet via NB: %pM, IF: %s [%pM] " 667 "Received BATMAN packet via NB: %pM, IF: %s [%pM] "
639 "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " 668 "(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, "
640 "TTL %d, V %d, IDF %d)\n", 669 "crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
641 ethhdr->h_source, if_incoming->net_dev->name, 670 ethhdr->h_source, if_incoming->net_dev->name,
642 if_incoming->net_dev->dev_addr, batman_packet->orig, 671 if_incoming->net_dev->dev_addr, batman_packet->orig,
643 batman_packet->prev_sender, batman_packet->seqno, 672 batman_packet->prev_sender, batman_packet->seqno,
644 batman_packet->tq, batman_packet->ttl, batman_packet->version, 673 batman_packet->ttvn, batman_packet->tt_crc,
674 batman_packet->tt_num_changes, batman_packet->tq,
675 batman_packet->ttl, batman_packet->version,
645 has_directlink_flag); 676 has_directlink_flag);
646 677
647 rcu_read_lock(); 678 rcu_read_lock();
@@ -664,7 +695,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
664 hard_iface->net_dev->dev_addr)) 695 hard_iface->net_dev->dev_addr))
665 is_my_oldorig = 1; 696 is_my_oldorig = 1;
666 697
667 if (compare_eth(ethhdr->h_source, broadcast_addr)) 698 if (is_broadcast_ether_addr(ethhdr->h_source))
668 is_broadcast = 1; 699 is_broadcast = 1;
669 } 700 }
670 rcu_read_unlock(); 701 rcu_read_unlock();
@@ -701,17 +732,16 @@ void receive_bat_packet(struct ethhdr *ethhdr,
701 732
702 /* neighbor has to indicate direct link and it has to 733 /* neighbor has to indicate direct link and it has to
703 * come via the corresponding interface */ 734 * come via the corresponding interface */
704 /* if received seqno equals last send seqno save new 735 /* save packet seqno for bidirectional check */
705 * seqno for bidirectional check */
706 if (has_directlink_flag && 736 if (has_directlink_flag &&
707 compare_eth(if_incoming->net_dev->dev_addr, 737 compare_eth(if_incoming->net_dev->dev_addr,
708 batman_packet->orig) && 738 batman_packet->orig)) {
709 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
710 offset = if_incoming->if_num * NUM_WORDS; 739 offset = if_incoming->if_num * NUM_WORDS;
711 740
712 spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); 741 spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
713 word = &(orig_neigh_node->bcast_own[offset]); 742 word = &(orig_neigh_node->bcast_own[offset]);
714 bit_mark(word, 0); 743 bit_mark(word,
744 if_incoming_seqno - batman_packet->seqno - 2);
715 orig_neigh_node->bcast_own_sum[if_incoming->if_num] = 745 orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
716 bit_packet_count(word); 746 bit_packet_count(word);
717 spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); 747 spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
@@ -794,14 +824,14 @@ void receive_bat_packet(struct ethhdr *ethhdr,
794 ((orig_node->last_real_seqno == batman_packet->seqno) && 824 ((orig_node->last_real_seqno == batman_packet->seqno) &&
795 (orig_node->last_ttl - 3 <= batman_packet->ttl)))) 825 (orig_node->last_ttl - 3 <= batman_packet->ttl))))
796 update_orig(bat_priv, orig_node, ethhdr, batman_packet, 826 update_orig(bat_priv, orig_node, ethhdr, batman_packet,
797 if_incoming, tt_buff, tt_buff_len, is_duplicate); 827 if_incoming, tt_buff, is_duplicate);
798 828
799 /* is single hop (direct) neighbor */ 829 /* is single hop (direct) neighbor */
800 if (is_single_hop_neigh) { 830 if (is_single_hop_neigh) {
801 831
802 /* mark direct link on incoming interface */ 832 /* mark direct link on incoming interface */
803 schedule_forward_packet(orig_node, ethhdr, batman_packet, 833 schedule_forward_packet(orig_node, ethhdr, batman_packet,
804 1, tt_buff_len, if_incoming); 834 1, if_incoming);
805 835
806 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 836 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
807 "rebroadcast neighbor packet with direct link flag\n"); 837 "rebroadcast neighbor packet with direct link flag\n");
@@ -824,7 +854,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
824 bat_dbg(DBG_BATMAN, bat_priv, 854 bat_dbg(DBG_BATMAN, bat_priv,
825 "Forwarding packet: rebroadcast originator packet\n"); 855 "Forwarding packet: rebroadcast originator packet\n");
826 schedule_forward_packet(orig_node, ethhdr, batman_packet, 856 schedule_forward_packet(orig_node, ethhdr, batman_packet,
827 0, tt_buff_len, if_incoming); 857 0, if_incoming);
828 858
829out_neigh: 859out_neigh:
830 if ((orig_neigh_node) && (!is_single_hop_neigh)) 860 if ((orig_neigh_node) && (!is_single_hop_neigh))
@@ -1077,7 +1107,7 @@ out:
1077 * This method rotates the bonding list and increases the 1107 * This method rotates the bonding list and increases the
1078 * returned router's refcount. */ 1108 * returned router's refcount. */
1079static struct neigh_node *find_bond_router(struct orig_node *primary_orig, 1109static struct neigh_node *find_bond_router(struct orig_node *primary_orig,
1080 struct hard_iface *recv_if) 1110 const struct hard_iface *recv_if)
1081{ 1111{
1082 struct neigh_node *tmp_neigh_node; 1112 struct neigh_node *tmp_neigh_node;
1083 struct neigh_node *router = NULL, *first_candidate = NULL; 1113 struct neigh_node *router = NULL, *first_candidate = NULL;
@@ -1128,7 +1158,7 @@ out:
1128 * 1158 *
1129 * Increases the returned router's refcount */ 1159 * Increases the returned router's refcount */
1130static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig, 1160static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
1131 struct hard_iface *recv_if) 1161 const struct hard_iface *recv_if)
1132{ 1162{
1133 struct neigh_node *tmp_neigh_node; 1163 struct neigh_node *tmp_neigh_node;
1134 struct neigh_node *router = NULL, *first_candidate = NULL; 1164 struct neigh_node *router = NULL, *first_candidate = NULL;
@@ -1171,12 +1201,124 @@ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
1171 return router; 1201 return router;
1172} 1202}
1173 1203
1204int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)
1205{
1206 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1207 struct tt_query_packet *tt_query;
1208 struct ethhdr *ethhdr;
1209
1210 /* drop packet if it has not necessary minimum size */
1211 if (unlikely(!pskb_may_pull(skb, sizeof(struct tt_query_packet))))
1212 goto out;
1213
1214 /* I could need to modify it */
1215 if (skb_cow(skb, sizeof(struct tt_query_packet)) < 0)
1216 goto out;
1217
1218 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1219
1220 /* packet with unicast indication but broadcast recipient */
1221 if (is_broadcast_ether_addr(ethhdr->h_dest))
1222 goto out;
1223
1224 /* packet with broadcast sender address */
1225 if (is_broadcast_ether_addr(ethhdr->h_source))
1226 goto out;
1227
1228 tt_query = (struct tt_query_packet *)skb->data;
1229
1230 tt_query->tt_data = ntohs(tt_query->tt_data);
1231
1232 switch (tt_query->flags & TT_QUERY_TYPE_MASK) {
1233 case TT_REQUEST:
1234 /* If we cannot provide an answer the tt_request is
1235 * forwarded */
1236 if (!send_tt_response(bat_priv, tt_query)) {
1237 bat_dbg(DBG_TT, bat_priv,
1238 "Routing TT_REQUEST to %pM [%c]\n",
1239 tt_query->dst,
1240 (tt_query->flags & TT_FULL_TABLE ? 'F' : '.'));
1241 tt_query->tt_data = htons(tt_query->tt_data);
1242 return route_unicast_packet(skb, recv_if);
1243 }
1244 break;
1245 case TT_RESPONSE:
1246 /* packet needs to be linearised to access the TT changes */
1247 if (skb_linearize(skb) < 0)
1248 goto out;
1249
1250 if (is_my_mac(tt_query->dst))
1251 handle_tt_response(bat_priv, tt_query);
1252 else {
1253 bat_dbg(DBG_TT, bat_priv,
1254 "Routing TT_RESPONSE to %pM [%c]\n",
1255 tt_query->dst,
1256 (tt_query->flags & TT_FULL_TABLE ? 'F' : '.'));
1257 tt_query->tt_data = htons(tt_query->tt_data);
1258 return route_unicast_packet(skb, recv_if);
1259 }
1260 break;
1261 }
1262
1263out:
1264 /* returning NET_RX_DROP will make the caller function kfree the skb */
1265 return NET_RX_DROP;
1266}
1267
1268int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
1269{
1270 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1271 struct roam_adv_packet *roam_adv_packet;
1272 struct orig_node *orig_node;
1273 struct ethhdr *ethhdr;
1274
1275 /* drop packet if it has not necessary minimum size */
1276 if (unlikely(!pskb_may_pull(skb, sizeof(struct roam_adv_packet))))
1277 goto out;
1278
1279 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1280
1281 /* packet with unicast indication but broadcast recipient */
1282 if (is_broadcast_ether_addr(ethhdr->h_dest))
1283 goto out;
1284
1285 /* packet with broadcast sender address */
1286 if (is_broadcast_ether_addr(ethhdr->h_source))
1287 goto out;
1288
1289 roam_adv_packet = (struct roam_adv_packet *)skb->data;
1290
1291 if (!is_my_mac(roam_adv_packet->dst))
1292 return route_unicast_packet(skb, recv_if);
1293
1294 orig_node = orig_hash_find(bat_priv, roam_adv_packet->src);
1295 if (!orig_node)
1296 goto out;
1297
1298 bat_dbg(DBG_TT, bat_priv, "Received ROAMING_ADV from %pM "
1299 "(client %pM)\n", roam_adv_packet->src,
1300 roam_adv_packet->client);
1301
1302 tt_global_add(bat_priv, orig_node, roam_adv_packet->client,
1303 atomic_read(&orig_node->last_ttvn) + 1, true);
1304
1305 /* Roaming phase starts: I have new information but the ttvn has not
1306 * been incremented yet. This flag will make me check all the incoming
1307 * packets for the correct destination. */
1308 bat_priv->tt_poss_change = true;
1309
1310 orig_node_free_ref(orig_node);
1311out:
1312 /* returning NET_RX_DROP will make the caller function kfree the skb */
1313 return NET_RX_DROP;
1314}
1315
1174/* find a suitable router for this originator, and use 1316/* find a suitable router for this originator, and use
1175 * bonding if possible. increases the found neighbors 1317 * bonding if possible. increases the found neighbors
1176 * refcount.*/ 1318 * refcount.*/
1177struct neigh_node *find_router(struct bat_priv *bat_priv, 1319struct neigh_node *find_router(struct bat_priv *bat_priv,
1178 struct orig_node *orig_node, 1320 struct orig_node *orig_node,
1179 struct hard_iface *recv_if) 1321 const struct hard_iface *recv_if)
1180{ 1322{
1181 struct orig_node *primary_orig_node; 1323 struct orig_node *primary_orig_node;
1182 struct orig_node *router_orig; 1324 struct orig_node *router_orig;
@@ -1240,6 +1382,9 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
1240 router = find_ifalter_router(primary_orig_node, recv_if); 1382 router = find_ifalter_router(primary_orig_node, recv_if);
1241 1383
1242return_router: 1384return_router:
1385 if (router && router->if_incoming->if_status != IF_ACTIVE)
1386 goto err_unlock;
1387
1243 rcu_read_unlock(); 1388 rcu_read_unlock();
1244 return router; 1389 return router;
1245err_unlock: 1390err_unlock:
@@ -1354,14 +1499,84 @@ out:
1354 return ret; 1499 return ret;
1355} 1500}
1356 1501
1502static int check_unicast_ttvn(struct bat_priv *bat_priv,
1503 struct sk_buff *skb) {
1504 uint8_t curr_ttvn;
1505 struct orig_node *orig_node;
1506 struct ethhdr *ethhdr;
1507 struct hard_iface *primary_if;
1508 struct unicast_packet *unicast_packet;
1509 bool tt_poss_change;
1510
1511 /* I could need to modify it */
1512 if (skb_cow(skb, sizeof(struct unicast_packet)) < 0)
1513 return 0;
1514
1515 unicast_packet = (struct unicast_packet *)skb->data;
1516
1517 if (is_my_mac(unicast_packet->dest)) {
1518 tt_poss_change = bat_priv->tt_poss_change;
1519 curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1520 } else {
1521 orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
1522
1523 if (!orig_node)
1524 return 0;
1525
1526 curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1527 tt_poss_change = orig_node->tt_poss_change;
1528 orig_node_free_ref(orig_node);
1529 }
1530
1531 /* Check whether I have to reroute the packet */
1532 if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) {
1533 /* Linearize the skb before accessing it */
1534 if (skb_linearize(skb) < 0)
1535 return 0;
1536
1537 ethhdr = (struct ethhdr *)(skb->data +
1538 sizeof(struct unicast_packet));
1539 orig_node = transtable_search(bat_priv, ethhdr->h_dest);
1540
1541 if (!orig_node) {
1542 if (!is_my_client(bat_priv, ethhdr->h_dest))
1543 return 0;
1544 primary_if = primary_if_get_selected(bat_priv);
1545 if (!primary_if)
1546 return 0;
1547 memcpy(unicast_packet->dest,
1548 primary_if->net_dev->dev_addr, ETH_ALEN);
1549 hardif_free_ref(primary_if);
1550 } else {
1551 memcpy(unicast_packet->dest, orig_node->orig,
1552 ETH_ALEN);
1553 curr_ttvn = (uint8_t)
1554 atomic_read(&orig_node->last_ttvn);
1555 orig_node_free_ref(orig_node);
1556 }
1557
1558 bat_dbg(DBG_ROUTES, bat_priv, "TTVN mismatch (old_ttvn %u "
1559 "new_ttvn %u)! Rerouting unicast packet (for %pM) to "
1560 "%pM\n", unicast_packet->ttvn, curr_ttvn,
1561 ethhdr->h_dest, unicast_packet->dest);
1562
1563 unicast_packet->ttvn = curr_ttvn;
1564 }
1565 return 1;
1566}
1567
1357int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) 1568int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1358{ 1569{
1570 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1359 struct unicast_packet *unicast_packet; 1571 struct unicast_packet *unicast_packet;
1360 int hdr_size = sizeof(struct unicast_packet); 1572 int hdr_size = sizeof(*unicast_packet);
1361 1573
1362 if (check_unicast_packet(skb, hdr_size) < 0) 1574 if (check_unicast_packet(skb, hdr_size) < 0)
1363 return NET_RX_DROP; 1575 return NET_RX_DROP;
1364 1576
1577 if (!check_unicast_ttvn(bat_priv, skb))
1578 return NET_RX_DROP;
1579
1365 unicast_packet = (struct unicast_packet *)skb->data; 1580 unicast_packet = (struct unicast_packet *)skb->data;
1366 1581
1367 /* packet for me */ 1582 /* packet for me */
@@ -1377,13 +1592,16 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1377{ 1592{
1378 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1593 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1379 struct unicast_frag_packet *unicast_packet; 1594 struct unicast_frag_packet *unicast_packet;
1380 int hdr_size = sizeof(struct unicast_frag_packet); 1595 int hdr_size = sizeof(*unicast_packet);
1381 struct sk_buff *new_skb = NULL; 1596 struct sk_buff *new_skb = NULL;
1382 int ret; 1597 int ret;
1383 1598
1384 if (check_unicast_packet(skb, hdr_size) < 0) 1599 if (check_unicast_packet(skb, hdr_size) < 0)
1385 return NET_RX_DROP; 1600 return NET_RX_DROP;
1386 1601
1602 if (!check_unicast_ttvn(bat_priv, skb))
1603 return NET_RX_DROP;
1604
1387 unicast_packet = (struct unicast_frag_packet *)skb->data; 1605 unicast_packet = (struct unicast_frag_packet *)skb->data;
1388 1606
1389 /* packet for me */ 1607 /* packet for me */
@@ -1413,7 +1631,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1413 struct orig_node *orig_node = NULL; 1631 struct orig_node *orig_node = NULL;
1414 struct bcast_packet *bcast_packet; 1632 struct bcast_packet *bcast_packet;
1415 struct ethhdr *ethhdr; 1633 struct ethhdr *ethhdr;
1416 int hdr_size = sizeof(struct bcast_packet); 1634 int hdr_size = sizeof(*bcast_packet);
1417 int ret = NET_RX_DROP; 1635 int ret = NET_RX_DROP;
1418 int32_t seq_diff; 1636 int32_t seq_diff;
1419 1637
@@ -1471,7 +1689,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1471 spin_unlock_bh(&orig_node->bcast_seqno_lock); 1689 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1472 1690
1473 /* rebroadcast packet */ 1691 /* rebroadcast packet */
1474 add_bcast_packet_to_list(bat_priv, skb); 1692 add_bcast_packet_to_list(bat_priv, skb, 1);
1475 1693
1476 /* broadcast for me */ 1694 /* broadcast for me */
1477 interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); 1695 interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
@@ -1491,7 +1709,7 @@ int recv_vis_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1491 struct vis_packet *vis_packet; 1709 struct vis_packet *vis_packet;
1492 struct ethhdr *ethhdr; 1710 struct ethhdr *ethhdr;
1493 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1711 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1494 int hdr_size = sizeof(struct vis_packet); 1712 int hdr_size = sizeof(*vis_packet);
1495 1713
1496 /* keep skb linear */ 1714 /* keep skb linear */
1497 if (skb_linearize(skb) < 0) 1715 if (skb_linearize(skb) < 0)