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.c317
1 files changed, 262 insertions, 55 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 934f1f2f86c6..0ce090c9fe86 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -64,27 +64,57 @@ 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 const 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 /* Roaming phase is over: tables are in sync again. I can
95 * unset the flag */
96 orig_node->tt_poss_change = false;
97 } else {
98 /* if we missed more than one change or our tables are not
99 * in sync anymore -> request fresh tt data */
100 if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
101request_table:
102 bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
103 "Need to retrieve the correct information "
104 "(ttvn: %u last_ttvn: %u crc: %u last_crc: "
105 "%u num_changes: %u)\n", orig_node->orig, ttvn,
106 orig_ttvn, tt_crc, orig_node->tt_crc,
107 tt_num_changes);
108 send_tt_request(bat_priv, orig_node, ttvn, tt_crc,
109 full_table);
110 return;
111 }
82 } 112 }
83} 113}
84 114
85static void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node, 115static void update_route(struct bat_priv *bat_priv,
86 struct neigh_node *neigh_node, 116 struct orig_node *orig_node,
87 const unsigned char *tt_buff, int tt_buff_len) 117 struct neigh_node *neigh_node)
88{ 118{
89 struct neigh_node *curr_router; 119 struct neigh_node *curr_router;
90 120
@@ -92,11 +122,10 @@ static void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
92 122
93 /* route deleted */ 123 /* route deleted */
94 if ((curr_router) && (!neigh_node)) { 124 if ((curr_router) && (!neigh_node)) {
95
96 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", 125 bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n",
97 orig_node->orig); 126 orig_node->orig);
98 tt_global_del_orig(bat_priv, orig_node, 127 tt_global_del_orig(bat_priv, orig_node,
99 "originator timed out"); 128 "Deleted route towards originator");
100 129
101 /* route added */ 130 /* route added */
102 } else if ((!curr_router) && (neigh_node)) { 131 } else if ((!curr_router) && (neigh_node)) {
@@ -104,9 +133,6 @@ static void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
104 bat_dbg(DBG_ROUTES, bat_priv, 133 bat_dbg(DBG_ROUTES, bat_priv,
105 "Adding route towards: %pM (via %pM)\n", 134 "Adding route towards: %pM (via %pM)\n",
106 orig_node->orig, neigh_node->addr); 135 orig_node->orig, neigh_node->addr);
107 tt_global_add_orig(bat_priv, orig_node,
108 tt_buff, tt_buff_len);
109
110 /* route changed */ 136 /* route changed */
111 } else if (neigh_node && curr_router) { 137 } else if (neigh_node && curr_router) {
112 bat_dbg(DBG_ROUTES, bat_priv, 138 bat_dbg(DBG_ROUTES, bat_priv,
@@ -133,8 +159,7 @@ static void update_route(struct bat_priv *bat_priv, struct orig_node *orig_node,
133} 159}
134 160
135void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, 161void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
136 struct neigh_node *neigh_node, const unsigned char *tt_buff, 162 struct neigh_node *neigh_node)
137 int tt_buff_len)
138{ 163{
139 struct neigh_node *router = NULL; 164 struct neigh_node *router = NULL;
140 165
@@ -144,11 +169,7 @@ void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
144 router = orig_node_get_router(orig_node); 169 router = orig_node_get_router(orig_node);
145 170
146 if (router != neigh_node) 171 if (router != neigh_node)
147 update_route(bat_priv, orig_node, neigh_node, 172 update_route(bat_priv, orig_node, neigh_node);
148 tt_buff, tt_buff_len);
149 /* may be just TT changed */
150 else
151 update_TT(bat_priv, orig_node, tt_buff, tt_buff_len);
152 173
153out: 174out:
154 if (router) 175 if (router)
@@ -163,7 +184,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
163 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 184 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
164 struct neigh_node *neigh_node = NULL, *tmp_neigh_node; 185 struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
165 struct hlist_node *node; 186 struct hlist_node *node;
166 unsigned char total_count; 187 uint8_t total_count;
167 uint8_t orig_eq_count, neigh_rq_count, tq_own; 188 uint8_t orig_eq_count, neigh_rq_count, tq_own;
168 int tq_asym_penalty, ret = 0; 189 int tq_asym_penalty, ret = 0;
169 190
@@ -360,14 +381,12 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
360 const struct ethhdr *ethhdr, 381 const struct ethhdr *ethhdr,
361 const struct batman_packet *batman_packet, 382 const struct batman_packet *batman_packet,
362 struct hard_iface *if_incoming, 383 struct hard_iface *if_incoming,
363 const unsigned char *tt_buff, int tt_buff_len, 384 const unsigned char *tt_buff, int is_duplicate)
364 char is_duplicate)
365{ 385{
366 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 386 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
367 struct neigh_node *router = NULL; 387 struct neigh_node *router = NULL;
368 struct orig_node *orig_node_tmp; 388 struct orig_node *orig_node_tmp;
369 struct hlist_node *node; 389 struct hlist_node *node;
370 int tmp_tt_buff_len;
371 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; 390 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
372 391
373 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 392 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
@@ -432,9 +451,6 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
432 451
433 bonding_candidate_add(orig_node, neigh_node); 452 bonding_candidate_add(orig_node, neigh_node);
434 453
435 tmp_tt_buff_len = (tt_buff_len > batman_packet->num_tt * ETH_ALEN ?
436 batman_packet->num_tt * ETH_ALEN : tt_buff_len);
437
438 /* if this neighbor already is our next hop there is nothing 454 /* if this neighbor already is our next hop there is nothing
439 * to change */ 455 * to change */
440 router = orig_node_get_router(orig_node); 456 router = orig_node_get_router(orig_node);
@@ -464,15 +480,19 @@ static void update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
464 goto update_tt; 480 goto update_tt;
465 } 481 }
466 482
467 update_routes(bat_priv, orig_node, neigh_node, 483 update_routes(bat_priv, orig_node, neigh_node);
468 tt_buff, tmp_tt_buff_len);
469 goto update_gw;
470 484
471update_tt: 485update_tt:
472 update_routes(bat_priv, orig_node, router, 486 /* I have to check for transtable changes only if the OGM has been
473 tt_buff, tmp_tt_buff_len); 487 * sent through a primary interface */
488 if (((batman_packet->orig != ethhdr->h_source) &&
489 (batman_packet->ttl > 2)) ||
490 (batman_packet->flags & PRIMARIES_FIRST_HOP))
491 update_transtable(bat_priv, orig_node, tt_buff,
492 batman_packet->tt_num_changes,
493 batman_packet->ttvn,
494 batman_packet->tt_crc);
474 495
475update_gw:
476 if (orig_node->gw_flags != batman_packet->gw_flags) 496 if (orig_node->gw_flags != batman_packet->gw_flags)
477 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); 497 gw_node_update(bat_priv, orig_node, batman_packet->gw_flags);
478 498
@@ -528,7 +548,7 @@ static int window_protected(struct bat_priv *bat_priv,
528 * -1 the packet is old and has been received while the seqno window 548 * -1 the packet is old and has been received while the seqno window
529 * was protected. Caller should drop it. 549 * was protected. Caller should drop it.
530 */ 550 */
531static char count_real_packets(const struct ethhdr *ethhdr, 551static int count_real_packets(const struct ethhdr *ethhdr,
532 const struct batman_packet *batman_packet, 552 const struct batman_packet *batman_packet,
533 const struct hard_iface *if_incoming) 553 const struct hard_iface *if_incoming)
534{ 554{
@@ -536,7 +556,7 @@ static char count_real_packets(const struct ethhdr *ethhdr,
536 struct orig_node *orig_node; 556 struct orig_node *orig_node;
537 struct neigh_node *tmp_neigh_node; 557 struct neigh_node *tmp_neigh_node;
538 struct hlist_node *node; 558 struct hlist_node *node;
539 char is_duplicate = 0; 559 int is_duplicate = 0;
540 int32_t seq_diff; 560 int32_t seq_diff;
541 int need_update = 0; 561 int need_update = 0;
542 int set_mark, ret = -1; 562 int set_mark, ret = -1;
@@ -594,7 +614,7 @@ out:
594 614
595void receive_bat_packet(const struct ethhdr *ethhdr, 615void receive_bat_packet(const struct ethhdr *ethhdr,
596 struct batman_packet *batman_packet, 616 struct batman_packet *batman_packet,
597 const unsigned char *tt_buff, int tt_buff_len, 617 const unsigned char *tt_buff,
598 struct hard_iface *if_incoming) 618 struct hard_iface *if_incoming)
599{ 619{
600 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 620 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
@@ -602,10 +622,10 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
602 struct orig_node *orig_neigh_node, *orig_node; 622 struct orig_node *orig_neigh_node, *orig_node;
603 struct neigh_node *router = NULL, *router_router = NULL; 623 struct neigh_node *router = NULL, *router_router = NULL;
604 struct neigh_node *orig_neigh_router = NULL; 624 struct neigh_node *orig_neigh_router = NULL;
605 char has_directlink_flag; 625 int has_directlink_flag;
606 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; 626 int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
607 char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; 627 int is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
608 char is_duplicate; 628 int is_duplicate;
609 uint32_t if_incoming_seqno; 629 uint32_t if_incoming_seqno;
610 630
611 /* Silently drop when the batman packet is actually not a 631 /* Silently drop when the batman packet is actually not a
@@ -633,12 +653,14 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
633 653
634 bat_dbg(DBG_BATMAN, bat_priv, 654 bat_dbg(DBG_BATMAN, bat_priv,
635 "Received BATMAN packet via NB: %pM, IF: %s [%pM] " 655 "Received BATMAN packet via NB: %pM, IF: %s [%pM] "
636 "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " 656 "(from OG: %pM, via prev OG: %pM, seqno %d, ttvn %u, "
637 "TTL %d, V %d, IDF %d)\n", 657 "crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
638 ethhdr->h_source, if_incoming->net_dev->name, 658 ethhdr->h_source, if_incoming->net_dev->name,
639 if_incoming->net_dev->dev_addr, batman_packet->orig, 659 if_incoming->net_dev->dev_addr, batman_packet->orig,
640 batman_packet->prev_sender, batman_packet->seqno, 660 batman_packet->prev_sender, batman_packet->seqno,
641 batman_packet->tq, batman_packet->ttl, batman_packet->version, 661 batman_packet->ttvn, batman_packet->tt_crc,
662 batman_packet->tt_num_changes, batman_packet->tq,
663 batman_packet->ttl, batman_packet->version,
642 has_directlink_flag); 664 has_directlink_flag);
643 665
644 rcu_read_lock(); 666 rcu_read_lock();
@@ -790,14 +812,14 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
790 ((orig_node->last_real_seqno == batman_packet->seqno) && 812 ((orig_node->last_real_seqno == batman_packet->seqno) &&
791 (orig_node->last_ttl - 3 <= batman_packet->ttl)))) 813 (orig_node->last_ttl - 3 <= batman_packet->ttl))))
792 update_orig(bat_priv, orig_node, ethhdr, batman_packet, 814 update_orig(bat_priv, orig_node, ethhdr, batman_packet,
793 if_incoming, tt_buff, tt_buff_len, is_duplicate); 815 if_incoming, tt_buff, is_duplicate);
794 816
795 /* is single hop (direct) neighbor */ 817 /* is single hop (direct) neighbor */
796 if (is_single_hop_neigh) { 818 if (is_single_hop_neigh) {
797 819
798 /* mark direct link on incoming interface */ 820 /* mark direct link on incoming interface */
799 schedule_forward_packet(orig_node, ethhdr, batman_packet, 821 schedule_forward_packet(orig_node, ethhdr, batman_packet,
800 1, tt_buff_len, if_incoming); 822 1, if_incoming);
801 823
802 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " 824 bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
803 "rebroadcast neighbor packet with direct link flag\n"); 825 "rebroadcast neighbor packet with direct link flag\n");
@@ -820,7 +842,7 @@ void receive_bat_packet(const struct ethhdr *ethhdr,
820 bat_dbg(DBG_BATMAN, bat_priv, 842 bat_dbg(DBG_BATMAN, bat_priv,
821 "Forwarding packet: rebroadcast originator packet\n"); 843 "Forwarding packet: rebroadcast originator packet\n");
822 schedule_forward_packet(orig_node, ethhdr, batman_packet, 844 schedule_forward_packet(orig_node, ethhdr, batman_packet,
823 0, tt_buff_len, if_incoming); 845 0, if_incoming);
824 846
825out_neigh: 847out_neigh:
826 if ((orig_neigh_node) && (!is_single_hop_neigh)) 848 if ((orig_neigh_node) && (!is_single_hop_neigh))
@@ -1167,6 +1189,118 @@ static struct neigh_node *find_ifalter_router(struct orig_node *primary_orig,
1167 return router; 1189 return router;
1168} 1190}
1169 1191
1192int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)
1193{
1194 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1195 struct tt_query_packet *tt_query;
1196 struct ethhdr *ethhdr;
1197
1198 /* drop packet if it has not necessary minimum size */
1199 if (unlikely(!pskb_may_pull(skb, sizeof(struct tt_query_packet))))
1200 goto out;
1201
1202 /* I could need to modify it */
1203 if (skb_cow(skb, sizeof(struct tt_query_packet)) < 0)
1204 goto out;
1205
1206 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1207
1208 /* packet with unicast indication but broadcast recipient */
1209 if (is_broadcast_ether_addr(ethhdr->h_dest))
1210 goto out;
1211
1212 /* packet with broadcast sender address */
1213 if (is_broadcast_ether_addr(ethhdr->h_source))
1214 goto out;
1215
1216 tt_query = (struct tt_query_packet *)skb->data;
1217
1218 tt_query->tt_data = ntohs(tt_query->tt_data);
1219
1220 switch (tt_query->flags & TT_QUERY_TYPE_MASK) {
1221 case TT_REQUEST:
1222 /* If we cannot provide an answer the tt_request is
1223 * forwarded */
1224 if (!send_tt_response(bat_priv, tt_query)) {
1225 bat_dbg(DBG_TT, bat_priv,
1226 "Routing TT_REQUEST to %pM [%c]\n",
1227 tt_query->dst,
1228 (tt_query->flags & TT_FULL_TABLE ? 'F' : '.'));
1229 tt_query->tt_data = htons(tt_query->tt_data);
1230 return route_unicast_packet(skb, recv_if);
1231 }
1232 break;
1233 case TT_RESPONSE:
1234 /* packet needs to be linearised to access the TT changes */
1235 if (skb_linearize(skb) < 0)
1236 goto out;
1237
1238 if (is_my_mac(tt_query->dst))
1239 handle_tt_response(bat_priv, tt_query);
1240 else {
1241 bat_dbg(DBG_TT, bat_priv,
1242 "Routing TT_RESPONSE to %pM [%c]\n",
1243 tt_query->dst,
1244 (tt_query->flags & TT_FULL_TABLE ? 'F' : '.'));
1245 tt_query->tt_data = htons(tt_query->tt_data);
1246 return route_unicast_packet(skb, recv_if);
1247 }
1248 break;
1249 }
1250
1251out:
1252 /* returning NET_RX_DROP will make the caller function kfree the skb */
1253 return NET_RX_DROP;
1254}
1255
1256int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
1257{
1258 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1259 struct roam_adv_packet *roam_adv_packet;
1260 struct orig_node *orig_node;
1261 struct ethhdr *ethhdr;
1262
1263 /* drop packet if it has not necessary minimum size */
1264 if (unlikely(!pskb_may_pull(skb, sizeof(struct roam_adv_packet))))
1265 goto out;
1266
1267 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1268
1269 /* packet with unicast indication but broadcast recipient */
1270 if (is_broadcast_ether_addr(ethhdr->h_dest))
1271 goto out;
1272
1273 /* packet with broadcast sender address */
1274 if (is_broadcast_ether_addr(ethhdr->h_source))
1275 goto out;
1276
1277 roam_adv_packet = (struct roam_adv_packet *)skb->data;
1278
1279 if (!is_my_mac(roam_adv_packet->dst))
1280 return route_unicast_packet(skb, recv_if);
1281
1282 orig_node = orig_hash_find(bat_priv, roam_adv_packet->src);
1283 if (!orig_node)
1284 goto out;
1285
1286 bat_dbg(DBG_TT, bat_priv, "Received ROAMING_ADV from %pM "
1287 "(client %pM)\n", roam_adv_packet->src,
1288 roam_adv_packet->client);
1289
1290 tt_global_add(bat_priv, orig_node, roam_adv_packet->client,
1291 atomic_read(&orig_node->last_ttvn) + 1, true);
1292
1293 /* Roaming phase starts: I have new information but the ttvn has not
1294 * been incremented yet. This flag will make me check all the incoming
1295 * packets for the correct destination. */
1296 bat_priv->tt_poss_change = true;
1297
1298 orig_node_free_ref(orig_node);
1299out:
1300 /* returning NET_RX_DROP will make the caller function kfree the skb */
1301 return NET_RX_DROP;
1302}
1303
1170/* find a suitable router for this originator, and use 1304/* find a suitable router for this originator, and use
1171 * bonding if possible. increases the found neighbors 1305 * bonding if possible. increases the found neighbors
1172 * refcount.*/ 1306 * refcount.*/
@@ -1353,14 +1487,84 @@ out:
1353 return ret; 1487 return ret;
1354} 1488}
1355 1489
1490static int check_unicast_ttvn(struct bat_priv *bat_priv,
1491 struct sk_buff *skb) {
1492 uint8_t curr_ttvn;
1493 struct orig_node *orig_node;
1494 struct ethhdr *ethhdr;
1495 struct hard_iface *primary_if;
1496 struct unicast_packet *unicast_packet;
1497 bool tt_poss_change;
1498
1499 /* I could need to modify it */
1500 if (skb_cow(skb, sizeof(struct unicast_packet)) < 0)
1501 return 0;
1502
1503 unicast_packet = (struct unicast_packet *)skb->data;
1504
1505 if (is_my_mac(unicast_packet->dest)) {
1506 tt_poss_change = bat_priv->tt_poss_change;
1507 curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
1508 } else {
1509 orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
1510
1511 if (!orig_node)
1512 return 0;
1513
1514 curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
1515 tt_poss_change = orig_node->tt_poss_change;
1516 orig_node_free_ref(orig_node);
1517 }
1518
1519 /* Check whether I have to reroute the packet */
1520 if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) {
1521 /* Linearize the skb before accessing it */
1522 if (skb_linearize(skb) < 0)
1523 return 0;
1524
1525 ethhdr = (struct ethhdr *)(skb->data +
1526 sizeof(struct unicast_packet));
1527 orig_node = transtable_search(bat_priv, ethhdr->h_dest);
1528
1529 if (!orig_node) {
1530 if (!is_my_client(bat_priv, ethhdr->h_dest))
1531 return 0;
1532 primary_if = primary_if_get_selected(bat_priv);
1533 if (!primary_if)
1534 return 0;
1535 memcpy(unicast_packet->dest,
1536 primary_if->net_dev->dev_addr, ETH_ALEN);
1537 hardif_free_ref(primary_if);
1538 } else {
1539 memcpy(unicast_packet->dest, orig_node->orig,
1540 ETH_ALEN);
1541 curr_ttvn = (uint8_t)
1542 atomic_read(&orig_node->last_ttvn);
1543 orig_node_free_ref(orig_node);
1544 }
1545
1546 bat_dbg(DBG_ROUTES, bat_priv, "TTVN mismatch (old_ttvn %u "
1547 "new_ttvn %u)! Rerouting unicast packet (for %pM) to "
1548 "%pM\n", unicast_packet->ttvn, curr_ttvn,
1549 ethhdr->h_dest, unicast_packet->dest);
1550
1551 unicast_packet->ttvn = curr_ttvn;
1552 }
1553 return 1;
1554}
1555
1356int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if) 1556int recv_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1357{ 1557{
1558 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1358 struct unicast_packet *unicast_packet; 1559 struct unicast_packet *unicast_packet;
1359 int hdr_size = sizeof(*unicast_packet); 1560 int hdr_size = sizeof(*unicast_packet);
1360 1561
1361 if (check_unicast_packet(skb, hdr_size) < 0) 1562 if (check_unicast_packet(skb, hdr_size) < 0)
1362 return NET_RX_DROP; 1563 return NET_RX_DROP;
1363 1564
1565 if (!check_unicast_ttvn(bat_priv, skb))
1566 return NET_RX_DROP;
1567
1364 unicast_packet = (struct unicast_packet *)skb->data; 1568 unicast_packet = (struct unicast_packet *)skb->data;
1365 1569
1366 /* packet for me */ 1570 /* packet for me */
@@ -1383,6 +1587,9 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if)
1383 if (check_unicast_packet(skb, hdr_size) < 0) 1587 if (check_unicast_packet(skb, hdr_size) < 0)
1384 return NET_RX_DROP; 1588 return NET_RX_DROP;
1385 1589
1590 if (!check_unicast_ttvn(bat_priv, skb))
1591 return NET_RX_DROP;
1592
1386 unicast_packet = (struct unicast_frag_packet *)skb->data; 1593 unicast_packet = (struct unicast_frag_packet *)skb->data;
1387 1594
1388 /* packet for me */ 1595 /* packet for me */