aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/batman-adv/bat_iv_ogm.c454
-rw-r--r--net/batman-adv/distributed-arp-table.c3
-rw-r--r--net/batman-adv/gateway_client.c11
-rw-r--r--net/batman-adv/icmp_socket.c3
-rw-r--r--net/batman-adv/network-coding.c25
-rw-r--r--net/batman-adv/originator.c242
-rw-r--r--net/batman-adv/originator.h12
-rw-r--r--net/batman-adv/routing.c38
-rw-r--r--net/batman-adv/routing.h1
-rw-r--r--net/batman-adv/translation-table.c3
-rw-r--r--net/batman-adv/types.h32
11 files changed, 605 insertions, 219 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 157cc1176313..1f9fe4270454 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -907,21 +907,21 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
907 * originator 907 * originator
908 * @bat_priv: the bat priv with all the soft interface information 908 * @bat_priv: the bat priv with all the soft interface information
909 * @orig_node: the orig node who originally emitted the ogm packet 909 * @orig_node: the orig node who originally emitted the ogm packet
910 * @orig_ifinfo: ifinfo for the outgoing interface of the orig_node
910 * @ethhdr: Ethernet header of the OGM 911 * @ethhdr: Ethernet header of the OGM
911 * @batadv_ogm_packet: the ogm packet 912 * @batadv_ogm_packet: the ogm packet
912 * @if_incoming: interface where the packet was received 913 * @if_incoming: interface where the packet was received
913 * @if_outgoing: interface for which the retransmission should be considered 914 * @if_outgoing: interface for which the retransmission should be considered
914 * @tt_buff: pointer to the tt buffer
915 * @dup_status: the duplicate status of this ogm packet. 915 * @dup_status: the duplicate status of this ogm packet.
916 */ 916 */
917static void 917static void
918batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, 918batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
919 struct batadv_orig_node *orig_node, 919 struct batadv_orig_node *orig_node,
920 struct batadv_orig_ifinfo *orig_ifinfo,
920 const struct ethhdr *ethhdr, 921 const struct ethhdr *ethhdr,
921 const struct batadv_ogm_packet *batadv_ogm_packet, 922 const struct batadv_ogm_packet *batadv_ogm_packet,
922 struct batadv_hard_iface *if_incoming, 923 struct batadv_hard_iface *if_incoming,
923 struct batadv_hard_iface *if_outgoing, 924 struct batadv_hard_iface *if_outgoing,
924 const unsigned char *tt_buff,
925 enum batadv_dup_status dup_status) 925 enum batadv_dup_status dup_status)
926{ 926{
927 struct batadv_neigh_ifinfo *neigh_ifinfo = NULL; 927 struct batadv_neigh_ifinfo *neigh_ifinfo = NULL;
@@ -1004,14 +1004,14 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
1004 spin_unlock_bh(&neigh_node->ifinfo_lock); 1004 spin_unlock_bh(&neigh_node->ifinfo_lock);
1005 1005
1006 if (dup_status == BATADV_NO_DUP) { 1006 if (dup_status == BATADV_NO_DUP) {
1007 orig_node->last_ttl = batadv_ogm_packet->ttl; 1007 orig_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1008 neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl; 1008 neigh_ifinfo->last_ttl = batadv_ogm_packet->ttl;
1009 } 1009 }
1010 1010
1011 /* if this neighbor already is our next hop there is nothing 1011 /* if this neighbor already is our next hop there is nothing
1012 * to change 1012 * to change
1013 */ 1013 */
1014 router = batadv_orig_node_get_router(orig_node); 1014 router = batadv_orig_router_get(orig_node, if_outgoing);
1015 if (router == neigh_node) 1015 if (router == neigh_node)
1016 goto out; 1016 goto out;
1017 1017
@@ -1048,7 +1048,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
1048 goto out; 1048 goto out;
1049 } 1049 }
1050 1050
1051 batadv_update_route(bat_priv, orig_node, neigh_node); 1051 batadv_update_route(bat_priv, orig_node, if_outgoing, neigh_node);
1052 goto out; 1052 goto out;
1053 1053
1054unlock: 1054unlock:
@@ -1209,6 +1209,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1209{ 1209{
1210 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 1210 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1211 struct batadv_orig_node *orig_node; 1211 struct batadv_orig_node *orig_node;
1212 struct batadv_orig_ifinfo *orig_ifinfo = NULL;
1212 struct batadv_neigh_node *neigh_node; 1213 struct batadv_neigh_node *neigh_node;
1213 struct batadv_neigh_ifinfo *neigh_ifinfo; 1214 struct batadv_neigh_ifinfo *neigh_ifinfo;
1214 int is_dup; 1215 int is_dup;
@@ -1225,13 +1226,19 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1225 if (!orig_node) 1226 if (!orig_node)
1226 return BATADV_NO_DUP; 1227 return BATADV_NO_DUP;
1227 1228
1229 orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
1230 if (WARN_ON(!orig_ifinfo)) {
1231 batadv_orig_node_free_ref(orig_node);
1232 return 0;
1233 }
1234
1228 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); 1235 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1229 seq_diff = seqno - orig_node->last_real_seqno; 1236 seq_diff = seqno - orig_ifinfo->last_real_seqno;
1230 1237
1231 /* signalize caller that the packet is to be dropped. */ 1238 /* signalize caller that the packet is to be dropped. */
1232 if (!hlist_empty(&orig_node->neigh_list) && 1239 if (!hlist_empty(&orig_node->neigh_list) &&
1233 batadv_window_protected(bat_priv, seq_diff, 1240 batadv_window_protected(bat_priv, seq_diff,
1234 &orig_node->batman_seqno_reset)) { 1241 &orig_ifinfo->batman_seqno_reset)) {
1235 ret = BATADV_PROTECTED; 1242 ret = BATADV_PROTECTED;
1236 goto out; 1243 goto out;
1237 } 1244 }
@@ -1245,7 +1252,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1245 1252
1246 neigh_addr = neigh_node->addr; 1253 neigh_addr = neigh_node->addr;
1247 is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits, 1254 is_dup = batadv_test_bit(neigh_ifinfo->bat_iv.real_bits,
1248 orig_node->last_real_seqno, 1255 orig_ifinfo->last_real_seqno,
1249 seqno); 1256 seqno);
1250 1257
1251 if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && 1258 if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
@@ -1273,163 +1280,65 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1273 1280
1274 if (need_update) { 1281 if (need_update) {
1275 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1282 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1276 "updating last_seqno: old %u, new %u\n", 1283 "%s updating last_seqno: old %u, new %u\n",
1277 orig_node->last_real_seqno, seqno); 1284 if_outgoing ? if_outgoing->net_dev->name : "DEFAULT",
1278 orig_node->last_real_seqno = seqno; 1285 orig_ifinfo->last_real_seqno, seqno);
1286 orig_ifinfo->last_real_seqno = seqno;
1279 } 1287 }
1280 1288
1281out: 1289out:
1282 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); 1290 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1283 batadv_orig_node_free_ref(orig_node); 1291 batadv_orig_node_free_ref(orig_node);
1292 if (orig_ifinfo)
1293 batadv_orig_ifinfo_free_ref(orig_ifinfo);
1284 return ret; 1294 return ret;
1285} 1295}
1286 1296
1287static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, 1297
1288 struct batadv_ogm_packet *batadv_ogm_packet, 1298/**
1289 const unsigned char *tt_buff, 1299 * batadv_iv_ogm_process_per_outif - process a batman iv OGM for an outgoing if
1290 struct batadv_hard_iface *if_incoming) 1300 * @skb: the skb containing the OGM
1301 * @orig_node: the (cached) orig node for the originator of this OGM
1302 * @if_incoming: the interface where this packet was received
1303 * @if_outgoing: the interface for which the packet should be considered
1304 */
1305static void
1306batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
1307 struct batadv_orig_node *orig_node,
1308 struct batadv_hard_iface *if_incoming,
1309 struct batadv_hard_iface *if_outgoing)
1291{ 1310{
1292 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 1311 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1293 struct batadv_hard_iface *hard_iface;
1294 struct batadv_orig_node *orig_neigh_node, *orig_node, *orig_node_tmp;
1295 struct batadv_neigh_node *router = NULL, *router_router = NULL; 1312 struct batadv_neigh_node *router = NULL, *router_router = NULL;
1313 struct batadv_orig_node *orig_neigh_node;
1314 struct batadv_orig_ifinfo *orig_ifinfo;
1296 struct batadv_neigh_node *orig_neigh_router = NULL; 1315 struct batadv_neigh_node *orig_neigh_router = NULL;
1297 struct batadv_neigh_ifinfo *router_ifinfo = NULL; 1316 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
1298 int has_directlink_flag; 1317 struct batadv_ogm_packet *ogm_packet;
1299 int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
1300 int is_bidirect;
1301 bool is_single_hop_neigh = false;
1302 bool is_from_best_next_hop = false;
1303 int sameseq, similar_ttl;
1304 enum batadv_dup_status dup_status; 1318 enum batadv_dup_status dup_status;
1305 uint32_t if_incoming_seqno; 1319 bool is_from_best_next_hop = false;
1320 bool is_single_hop_neigh = false;
1321 bool sameseq, similar_ttl;
1322 struct sk_buff *skb_priv;
1323 struct ethhdr *ethhdr;
1306 uint8_t *prev_sender; 1324 uint8_t *prev_sender;
1325 int is_bidirect;
1307 1326
1308 /* Silently drop when the batman packet is actually not a 1327 /* create a private copy of the skb, as some functions change tq value
1309 * correct packet. 1328 * and/or flags.
1310 *
1311 * This might happen if a packet is padded (e.g. Ethernet has a
1312 * minimum frame length of 64 byte) and the aggregation interprets
1313 * it as an additional length.
1314 *
1315 * TODO: A more sane solution would be to have a bit in the
1316 * batadv_ogm_packet to detect whether the packet is the last
1317 * packet in an aggregation. Here we expect that the padding
1318 * is always zero (or not 0x01)
1319 */ 1329 */
1320 if (batadv_ogm_packet->packet_type != BATADV_IV_OGM) 1330 skb_priv = skb_copy(skb, GFP_ATOMIC);
1331 if (!skb_priv)
1321 return; 1332 return;
1322 1333
1323 /* could be changed by schedule_own_packet() */ 1334 ethhdr = eth_hdr(skb_priv);
1324 if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno); 1335 ogm_packet = (struct batadv_ogm_packet *)(skb_priv->data + ogm_offset);
1325
1326 if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
1327 has_directlink_flag = 1;
1328 else
1329 has_directlink_flag = 0;
1330 1336
1331 if (batadv_compare_eth(ethhdr->h_source, batadv_ogm_packet->orig)) 1337 dup_status = batadv_iv_ogm_update_seqnos(ethhdr, ogm_packet,
1338 if_incoming, if_outgoing);
1339 if (batadv_compare_eth(ethhdr->h_source, ogm_packet->orig))
1332 is_single_hop_neigh = true; 1340 is_single_hop_neigh = true;
1333 1341
1334 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1335 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
1336 ethhdr->h_source, if_incoming->net_dev->name,
1337 if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
1338 batadv_ogm_packet->prev_sender,
1339 ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq,
1340 batadv_ogm_packet->ttl,
1341 batadv_ogm_packet->version, has_directlink_flag);
1342
1343 rcu_read_lock();
1344 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1345 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1346 continue;
1347
1348 if (hard_iface->soft_iface != if_incoming->soft_iface)
1349 continue;
1350
1351 if (batadv_compare_eth(ethhdr->h_source,
1352 hard_iface->net_dev->dev_addr))
1353 is_my_addr = 1;
1354
1355 if (batadv_compare_eth(batadv_ogm_packet->orig,
1356 hard_iface->net_dev->dev_addr))
1357 is_my_orig = 1;
1358
1359 if (batadv_compare_eth(batadv_ogm_packet->prev_sender,
1360 hard_iface->net_dev->dev_addr))
1361 is_my_oldorig = 1;
1362 }
1363 rcu_read_unlock();
1364
1365 if (is_my_addr) {
1366 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1367 "Drop packet: received my own broadcast (sender: %pM)\n",
1368 ethhdr->h_source);
1369 return;
1370 }
1371
1372 if (is_my_orig) {
1373 unsigned long *word;
1374 int offset;
1375 int32_t bit_pos;
1376 int16_t if_num;
1377 uint8_t *weight;
1378
1379 orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1380 ethhdr->h_source);
1381 if (!orig_neigh_node)
1382 return;
1383
1384 /* neighbor has to indicate direct link and it has to
1385 * come via the corresponding interface
1386 * save packet seqno for bidirectional check
1387 */
1388 if (has_directlink_flag &&
1389 batadv_compare_eth(if_incoming->net_dev->dev_addr,
1390 batadv_ogm_packet->orig)) {
1391 if_num = if_incoming->if_num;
1392 offset = if_num * BATADV_NUM_WORDS;
1393
1394 spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1395 word = &(orig_neigh_node->bat_iv.bcast_own[offset]);
1396 bit_pos = if_incoming_seqno - 2;
1397 bit_pos -= ntohl(batadv_ogm_packet->seqno);
1398 batadv_set_bit(word, bit_pos);
1399 weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num];
1400 *weight = bitmap_weight(word,
1401 BATADV_TQ_LOCAL_WINDOW_SIZE);
1402 spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1403 }
1404
1405 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1406 "Drop packet: originator packet from myself (via neighbor)\n");
1407 batadv_orig_node_free_ref(orig_neigh_node);
1408 return;
1409 }
1410
1411 if (is_my_oldorig) {
1412 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1413 "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
1414 ethhdr->h_source);
1415 return;
1416 }
1417
1418 if (batadv_ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
1419 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1420 "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
1421 ethhdr->h_source);
1422 return;
1423 }
1424
1425 orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1426 if (!orig_node)
1427 return;
1428
1429 dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
1430 if_incoming,
1431 BATADV_IF_DEFAULT);
1432
1433 if (dup_status == BATADV_PROTECTED) { 1342 if (dup_status == BATADV_PROTECTED) {
1434 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1343 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1435 "Drop packet: packet within seqno protection time (sender: %pM)\n", 1344 "Drop packet: packet within seqno protection time (sender: %pM)\n",
@@ -1437,29 +1346,28 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1437 goto out; 1346 goto out;
1438 } 1347 }
1439 1348
1440 if (batadv_ogm_packet->tq == 0) { 1349 if (ogm_packet->tq == 0) {
1441 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1350 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1442 "Drop packet: originator packet with tq equal 0\n"); 1351 "Drop packet: originator packet with tq equal 0\n");
1443 goto out; 1352 goto out;
1444 } 1353 }
1445 1354
1446 router = batadv_orig_node_get_router(orig_node); 1355 router = batadv_orig_router_get(orig_node, if_outgoing);
1447 if (router) { 1356 if (router) {
1448 orig_node_tmp = router->orig_node; 1357 router_router = batadv_orig_router_get(router->orig_node,
1449 router_router = batadv_orig_node_get_router(orig_node_tmp); 1358 if_outgoing);
1450 router_ifinfo = batadv_neigh_ifinfo_get(router, 1359 router_ifinfo = batadv_neigh_ifinfo_get(router, if_outgoing);
1451 BATADV_IF_DEFAULT);
1452 } 1360 }
1453 1361
1454 if ((router && router_ifinfo->bat_iv.tq_avg != 0) && 1362 if ((router_ifinfo && router_ifinfo->bat_iv.tq_avg != 0) &&
1455 (batadv_compare_eth(router->addr, ethhdr->h_source))) 1363 (batadv_compare_eth(router->addr, ethhdr->h_source)))
1456 is_from_best_next_hop = true; 1364 is_from_best_next_hop = true;
1457 1365
1458 prev_sender = batadv_ogm_packet->prev_sender; 1366 prev_sender = ogm_packet->prev_sender;
1459 /* avoid temporary routing loops */ 1367 /* avoid temporary routing loops */
1460 if (router && router_router && 1368 if (router && router_router &&
1461 (batadv_compare_eth(router->addr, prev_sender)) && 1369 (batadv_compare_eth(router->addr, prev_sender)) &&
1462 !(batadv_compare_eth(batadv_ogm_packet->orig, prev_sender)) && 1370 !(batadv_compare_eth(ogm_packet->orig, prev_sender)) &&
1463 (batadv_compare_eth(router->addr, router_router->addr))) { 1371 (batadv_compare_eth(router->addr, router_router->addr))) {
1464 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1372 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1465 "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", 1373 "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
@@ -1467,7 +1375,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1467 goto out; 1375 goto out;
1468 } 1376 }
1469 1377
1470 batadv_tvlv_ogm_receive(bat_priv, batadv_ogm_packet, orig_node); 1378 if (if_outgoing == BATADV_IF_DEFAULT)
1379 batadv_tvlv_ogm_receive(bat_priv, ogm_packet, orig_node);
1471 1380
1472 /* if sender is a direct neighbor the sender mac equals 1381 /* if sender is a direct neighbor the sender mac equals
1473 * originator mac 1382 * originator mac
@@ -1483,9 +1392,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1483 1392
1484 /* Update nc_nodes of the originator */ 1393 /* Update nc_nodes of the originator */
1485 batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node, 1394 batadv_nc_update_nc_node(bat_priv, orig_node, orig_neigh_node,
1486 batadv_ogm_packet, is_single_hop_neigh); 1395 ogm_packet, is_single_hop_neigh);
1487 1396
1488 orig_neigh_router = batadv_orig_node_get_router(orig_neigh_node); 1397 orig_neigh_router = batadv_orig_router_get(orig_neigh_node,
1398 if_outgoing);
1489 1399
1490 /* drop packet if sender is not a direct neighbor and if we 1400 /* drop packet if sender is not a direct neighbor and if we
1491 * don't route towards it 1401 * don't route towards it
@@ -1497,25 +1407,41 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1497 } 1407 }
1498 1408
1499 is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node, 1409 is_bidirect = batadv_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1500 batadv_ogm_packet, if_incoming, 1410 ogm_packet, if_incoming,
1501 BATADV_IF_DEFAULT); 1411 if_outgoing);
1502 1412
1503 /* update ranking if it is not a duplicate or has the same 1413 /* update ranking if it is not a duplicate or has the same
1504 * seqno and similar ttl as the non-duplicate 1414 * seqno and similar ttl as the non-duplicate
1505 */ 1415 */
1506 sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); 1416 orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
1507 similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->ttl; 1417 if (!orig_ifinfo)
1418 goto out_neigh;
1419
1420 sameseq = orig_ifinfo->last_real_seqno == ntohl(ogm_packet->seqno);
1421 similar_ttl = (orig_ifinfo->last_ttl - 3) <= ogm_packet->ttl;
1422
1508 if (is_bidirect && ((dup_status == BATADV_NO_DUP) || 1423 if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
1509 (sameseq && similar_ttl))) 1424 (sameseq && similar_ttl))) {
1510 batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, 1425 batadv_iv_ogm_orig_update(bat_priv, orig_node,
1511 batadv_ogm_packet, if_incoming, 1426 orig_ifinfo, ethhdr,
1512 BATADV_IF_DEFAULT, tt_buff, 1427 ogm_packet, if_incoming,
1513 dup_status); 1428 if_outgoing, dup_status);
1429 }
1430 batadv_orig_ifinfo_free_ref(orig_ifinfo);
1514 1431
1515 /* is single hop (direct) neighbor */ 1432 /* is single hop (direct) neighbor */
1516 if (is_single_hop_neigh) { 1433 if (is_single_hop_neigh) {
1434 /* OGMs from secondary interfaces should only scheduled once
1435 * per interface where it has been received, not multiple times
1436 */
1437 if ((ogm_packet->ttl <= 2) &&
1438 (if_incoming != if_outgoing)) {
1439 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1440 "Drop packet: OGM from secondary interface and wrong outgoing interface\n");
1441 goto out_neigh;
1442 }
1517 /* mark direct link on incoming interface */ 1443 /* mark direct link on incoming interface */
1518 batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet, 1444 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1519 is_single_hop_neigh, 1445 is_single_hop_neigh,
1520 is_from_best_next_hop, if_incoming); 1446 is_from_best_next_hop, if_incoming);
1521 1447
@@ -1537,9 +1463,14 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1537 goto out_neigh; 1463 goto out_neigh;
1538 } 1464 }
1539 1465
1466 /* only forward the packet on the default interface until the
1467 * OGM forwarding has been reworked to send on specific interfaces.
1468 */
1469 if (if_outgoing != BATADV_IF_DEFAULT)
1470 goto out_neigh;
1540 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1471 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1541 "Forwarding packet: rebroadcast originator packet\n"); 1472 "Forwarding packet: rebroadcast originator packet\n");
1542 batadv_iv_ogm_forward(orig_node, ethhdr, batadv_ogm_packet, 1473 batadv_iv_ogm_forward(orig_node, ethhdr, ogm_packet,
1543 is_single_hop_neigh, is_from_best_next_hop, 1474 is_single_hop_neigh, is_from_best_next_hop,
1544 if_incoming); 1475 if_incoming);
1545 1476
@@ -1554,6 +1485,165 @@ out:
1554 if (orig_neigh_router) 1485 if (orig_neigh_router)
1555 batadv_neigh_node_free_ref(orig_neigh_router); 1486 batadv_neigh_node_free_ref(orig_neigh_router);
1556 1487
1488 kfree_skb(skb_priv);
1489}
1490
1491/**
1492 * batadv_iv_ogm_process - process an incoming batman iv OGM
1493 * @skb: the skb containing the OGM
1494 * @ogm_offset: offset to the OGM which should be processed (for aggregates)
1495 * @if_incoming: the interface where this packet was receved
1496 */
1497static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
1498 struct batadv_hard_iface *if_incoming)
1499{
1500 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1501 struct batadv_orig_node *orig_neigh_node, *orig_node;
1502 struct batadv_hard_iface *hard_iface;
1503 struct batadv_ogm_packet *ogm_packet;
1504 uint32_t if_incoming_seqno;
1505 bool has_directlink_flag;
1506 struct ethhdr *ethhdr;
1507 bool is_my_oldorig = false;
1508 bool is_my_addr = false;
1509 bool is_my_orig = false;
1510
1511 ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
1512 ethhdr = eth_hdr(skb);
1513
1514 /* Silently drop when the batman packet is actually not a
1515 * correct packet.
1516 *
1517 * This might happen if a packet is padded (e.g. Ethernet has a
1518 * minimum frame length of 64 byte) and the aggregation interprets
1519 * it as an additional length.
1520 *
1521 * TODO: A more sane solution would be to have a bit in the
1522 * batadv_ogm_packet to detect whether the packet is the last
1523 * packet in an aggregation. Here we expect that the padding
1524 * is always zero (or not 0x01)
1525 */
1526 if (ogm_packet->packet_type != BATADV_IV_OGM)
1527 return;
1528
1529 /* could be changed by schedule_own_packet() */
1530 if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
1531
1532 if (ogm_packet->flags & BATADV_DIRECTLINK)
1533 has_directlink_flag = true;
1534 else
1535 has_directlink_flag = false;
1536
1537 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1538 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, tq %d, TTL %d, V %d, IDF %d)\n",
1539 ethhdr->h_source, if_incoming->net_dev->name,
1540 if_incoming->net_dev->dev_addr, ogm_packet->orig,
1541 ogm_packet->prev_sender, ntohl(ogm_packet->seqno),
1542 ogm_packet->tq, ogm_packet->ttl,
1543 ogm_packet->version, has_directlink_flag);
1544
1545 rcu_read_lock();
1546 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1547 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1548 continue;
1549
1550 if (hard_iface->soft_iface != if_incoming->soft_iface)
1551 continue;
1552
1553 if (batadv_compare_eth(ethhdr->h_source,
1554 hard_iface->net_dev->dev_addr))
1555 is_my_addr = true;
1556
1557 if (batadv_compare_eth(ogm_packet->orig,
1558 hard_iface->net_dev->dev_addr))
1559 is_my_orig = true;
1560
1561 if (batadv_compare_eth(ogm_packet->prev_sender,
1562 hard_iface->net_dev->dev_addr))
1563 is_my_oldorig = true;
1564 }
1565 rcu_read_unlock();
1566
1567 if (is_my_addr) {
1568 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1569 "Drop packet: received my own broadcast (sender: %pM)\n",
1570 ethhdr->h_source);
1571 return;
1572 }
1573
1574 if (is_my_orig) {
1575 unsigned long *word;
1576 int offset;
1577 int32_t bit_pos;
1578 int16_t if_num;
1579 uint8_t *weight;
1580
1581 orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1582 ethhdr->h_source);
1583 if (!orig_neigh_node)
1584 return;
1585
1586 /* neighbor has to indicate direct link and it has to
1587 * come via the corresponding interface
1588 * save packet seqno for bidirectional check
1589 */
1590 if (has_directlink_flag &&
1591 batadv_compare_eth(if_incoming->net_dev->dev_addr,
1592 ogm_packet->orig)) {
1593 if_num = if_incoming->if_num;
1594 offset = if_num * BATADV_NUM_WORDS;
1595
1596 spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1597 word = &(orig_neigh_node->bat_iv.bcast_own[offset]);
1598 bit_pos = if_incoming_seqno - 2;
1599 bit_pos -= ntohl(ogm_packet->seqno);
1600 batadv_set_bit(word, bit_pos);
1601 weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num];
1602 *weight = bitmap_weight(word,
1603 BATADV_TQ_LOCAL_WINDOW_SIZE);
1604 spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1605 }
1606
1607 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1608 "Drop packet: originator packet from myself (via neighbor)\n");
1609 batadv_orig_node_free_ref(orig_neigh_node);
1610 return;
1611 }
1612
1613 if (is_my_oldorig) {
1614 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1615 "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
1616 ethhdr->h_source);
1617 return;
1618 }
1619
1620 if (ogm_packet->flags & BATADV_NOT_BEST_NEXT_HOP) {
1621 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
1622 "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
1623 ethhdr->h_source);
1624 return;
1625 }
1626
1627 orig_node = batadv_iv_ogm_orig_get(bat_priv, ogm_packet->orig);
1628 if (!orig_node)
1629 return;
1630
1631 batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
1632 if_incoming, BATADV_IF_DEFAULT);
1633
1634 rcu_read_lock();
1635 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
1636 if (hard_iface->if_status != BATADV_IF_ACTIVE)
1637 continue;
1638
1639 if (hard_iface->soft_iface != bat_priv->soft_iface)
1640 continue;
1641
1642 batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
1643 if_incoming, hard_iface);
1644 }
1645 rcu_read_unlock();
1646
1557 batadv_orig_node_free_ref(orig_node); 1647 batadv_orig_node_free_ref(orig_node);
1558} 1648}
1559 1649
@@ -1561,11 +1651,9 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1561 struct batadv_hard_iface *if_incoming) 1651 struct batadv_hard_iface *if_incoming)
1562{ 1652{
1563 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 1653 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1564 struct batadv_ogm_packet *batadv_ogm_packet; 1654 struct batadv_ogm_packet *ogm_packet;
1565 struct ethhdr *ethhdr;
1566 int buff_pos = 0, packet_len;
1567 unsigned char *tvlv_buff, *packet_buff;
1568 uint8_t *packet_pos; 1655 uint8_t *packet_pos;
1656 int ogm_offset;
1569 bool ret; 1657 bool ret;
1570 1658
1571 ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN); 1659 ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
@@ -1582,24 +1670,19 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1582 batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES, 1670 batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
1583 skb->len + ETH_HLEN); 1671 skb->len + ETH_HLEN);
1584 1672
1585 packet_len = skb_headlen(skb); 1673 ogm_offset = 0;
1586 ethhdr = eth_hdr(skb); 1674 ogm_packet = (struct batadv_ogm_packet *)skb->data;
1587 packet_buff = skb->data;
1588 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
1589 1675
1590 /* unpack the aggregated packets and process them one by one */ 1676 /* unpack the aggregated packets and process them one by one */
1591 while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len, 1677 while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
1592 batadv_ogm_packet->tvlv_len)) { 1678 ogm_packet->tvlv_len)) {
1593 tvlv_buff = packet_buff + buff_pos + BATADV_OGM_HLEN; 1679 batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
1594 1680
1595 batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, 1681 ogm_offset += BATADV_OGM_HLEN;
1596 tvlv_buff, if_incoming); 1682 ogm_offset += ntohs(ogm_packet->tvlv_len);
1597 1683
1598 buff_pos += BATADV_OGM_HLEN; 1684 packet_pos = skb->data + ogm_offset;
1599 buff_pos += ntohs(batadv_ogm_packet->tvlv_len); 1685 ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1600
1601 packet_pos = packet_buff + buff_pos;
1602 batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
1603 } 1686 }
1604 1687
1605 kfree_skb(skb); 1688 kfree_skb(skb);
@@ -1661,7 +1744,8 @@ static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
1661 1744
1662 rcu_read_lock(); 1745 rcu_read_lock();
1663 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 1746 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1664 neigh_node = batadv_orig_node_get_router(orig_node); 1747 neigh_node = batadv_orig_router_get(orig_node,
1748 BATADV_IF_DEFAULT);
1665 if (!neigh_node) 1749 if (!neigh_node)
1666 continue; 1750 continue;
1667 1751
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 997ae6ac51ff..1d214cd5738e 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -589,7 +589,8 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
589 if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND) 589 if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND)
590 continue; 590 continue;
591 591
592 neigh_node = batadv_orig_node_get_router(cand[i].orig_node); 592 neigh_node = batadv_orig_router_get(cand[i].orig_node,
593 BATADV_IF_DEFAULT);
593 if (!neigh_node) 594 if (!neigh_node)
594 goto free_orig; 595 goto free_orig;
595 596
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 4e8f5b1eedfc..9ece204d3a00 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -146,7 +146,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
146 continue; 146 continue;
147 147
148 orig_node = gw_node->orig_node; 148 orig_node = gw_node->orig_node;
149 router = batadv_orig_node_get_router(orig_node); 149 router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
150 if (!router) 150 if (!router)
151 continue; 151 continue;
152 152
@@ -266,7 +266,8 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
266 if (next_gw) { 266 if (next_gw) {
267 sprintf(gw_addr, "%pM", next_gw->orig_node->orig); 267 sprintf(gw_addr, "%pM", next_gw->orig_node->orig);
268 268
269 router = batadv_orig_node_get_router(next_gw->orig_node); 269 router = batadv_orig_router_get(next_gw->orig_node,
270 BATADV_IF_DEFAULT);
270 if (!router) { 271 if (!router) {
271 batadv_gw_reselect(bat_priv); 272 batadv_gw_reselect(bat_priv);
272 goto out; 273 goto out;
@@ -335,7 +336,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
335 if (!curr_gw_orig) 336 if (!curr_gw_orig)
336 goto reselect; 337 goto reselect;
337 338
338 router_gw = batadv_orig_node_get_router(curr_gw_orig); 339 router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
339 if (!router_gw) 340 if (!router_gw)
340 goto reselect; 341 goto reselect;
341 342
@@ -348,7 +349,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
348 if (curr_gw_orig == orig_node) 349 if (curr_gw_orig == orig_node)
349 goto out; 350 goto out;
350 351
351 router_orig = batadv_orig_node_get_router(orig_node); 352 router_orig = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
352 if (!router_orig) 353 if (!router_orig)
353 goto out; 354 goto out;
354 355
@@ -576,7 +577,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
576 struct batadv_neigh_ifinfo *router_ifinfo = NULL; 577 struct batadv_neigh_ifinfo *router_ifinfo = NULL;
577 int ret = -1; 578 int ret = -1;
578 579
579 router = batadv_orig_node_get_router(gw_node->orig_node); 580 router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
580 if (!router) 581 if (!router)
581 goto out; 582 goto out;
582 583
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 3c08eee1b920..b384cb86f5ea 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -215,7 +215,8 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
215 if (!orig_node) 215 if (!orig_node)
216 goto dst_unreach; 216 goto dst_unreach;
217 217
218 neigh_node = batadv_orig_node_get_router(orig_node); 218 neigh_node = batadv_orig_router_get(orig_node,
219 BATADV_IF_DEFAULT);
219 if (!neigh_node) 220 if (!neigh_node)
220 goto dst_unreach; 221 goto dst_unreach;
221 222
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index aec3fa564027..6a0b3284219f 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -718,9 +718,21 @@ static bool batadv_can_nc_with_orig(struct batadv_priv *bat_priv,
718 struct batadv_orig_node *orig_node, 718 struct batadv_orig_node *orig_node,
719 struct batadv_ogm_packet *ogm_packet) 719 struct batadv_ogm_packet *ogm_packet)
720{ 720{
721 if (orig_node->last_real_seqno != ntohl(ogm_packet->seqno)) 721 struct batadv_orig_ifinfo *orig_ifinfo;
722 uint32_t last_real_seqno;
723 uint8_t last_ttl;
724
725 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, BATADV_IF_DEFAULT);
726 if (!orig_ifinfo)
722 return false; 727 return false;
723 if (orig_node->last_ttl != ogm_packet->ttl + 1) 728
729 last_ttl = orig_ifinfo->last_ttl;
730 last_real_seqno = orig_ifinfo->last_real_seqno;
731 batadv_orig_ifinfo_free_ref(orig_ifinfo);
732
733 if (last_real_seqno != ntohl(ogm_packet->seqno))
734 return false;
735 if (last_ttl != ogm_packet->ttl + 1)
724 return false; 736 return false;
725 if (!batadv_compare_eth(ogm_packet->orig, ogm_packet->prev_sender)) 737 if (!batadv_compare_eth(ogm_packet->orig, ogm_packet->prev_sender))
726 return false; 738 return false;
@@ -1019,7 +1031,11 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
1019 int coded_size = sizeof(*coded_packet); 1031 int coded_size = sizeof(*coded_packet);
1020 int header_add = coded_size - unicast_size; 1032 int header_add = coded_size - unicast_size;
1021 1033
1022 router_neigh = batadv_orig_node_get_router(neigh_node->orig_node); 1034 /* TODO: do we need to consider the outgoing interface for
1035 * coded packets?
1036 */
1037 router_neigh = batadv_orig_router_get(neigh_node->orig_node,
1038 BATADV_IF_DEFAULT);
1023 if (!router_neigh) 1039 if (!router_neigh)
1024 goto out; 1040 goto out;
1025 1041
@@ -1029,7 +1045,8 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
1029 goto out; 1045 goto out;
1030 1046
1031 neigh_tmp = nc_packet->neigh_node; 1047 neigh_tmp = nc_packet->neigh_node;
1032 router_coding = batadv_orig_node_get_router(neigh_tmp->orig_node); 1048 router_coding = batadv_orig_router_get(neigh_tmp->orig_node,
1049 BATADV_IF_DEFAULT);
1033 if (!router_coding) 1050 if (!router_coding)
1034 goto out; 1051 goto out;
1035 1052
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 1a4725f5267d..b8ef41600166 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -231,14 +231,31 @@ void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
231 call_rcu(&neigh_node->rcu, batadv_neigh_node_free_rcu); 231 call_rcu(&neigh_node->rcu, batadv_neigh_node_free_rcu);
232} 232}
233 233
234/* increases the refcounter of a found router */ 234/**
235 * batadv_orig_node_get_router - router to the originator depending on iface
236 * @orig_node: the orig node for the router
237 * @if_outgoing: the interface where the payload packet has been received or
238 * the OGM should be sent to
239 *
240 * Returns the neighbor which should be router for this orig_node/iface.
241 *
242 * The object is returned with refcounter increased by 1.
243 */
235struct batadv_neigh_node * 244struct batadv_neigh_node *
236batadv_orig_node_get_router(struct batadv_orig_node *orig_node) 245batadv_orig_router_get(struct batadv_orig_node *orig_node,
246 const struct batadv_hard_iface *if_outgoing)
237{ 247{
238 struct batadv_neigh_node *router; 248 struct batadv_orig_ifinfo *orig_ifinfo;
249 struct batadv_neigh_node *router = NULL;
239 250
240 rcu_read_lock(); 251 rcu_read_lock();
241 router = rcu_dereference(orig_node->router); 252 hlist_for_each_entry_rcu(orig_ifinfo, &orig_node->ifinfo_list, list) {
253 if (orig_ifinfo->if_outgoing != if_outgoing)
254 continue;
255
256 router = rcu_dereference(orig_ifinfo->router);
257 break;
258 }
242 259
243 if (router && !atomic_inc_not_zero(&router->refcount)) 260 if (router && !atomic_inc_not_zero(&router->refcount))
244 router = NULL; 261 router = NULL;
@@ -248,6 +265,86 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
248} 265}
249 266
250/** 267/**
268 * batadv_orig_ifinfo_get - find the ifinfo from an orig_node
269 * @orig_node: the orig node to be queried
270 * @if_outgoing: the interface for which the ifinfo should be acquired
271 *
272 * Returns the requested orig_ifinfo or NULL if not found.
273 *
274 * The object is returned with refcounter increased by 1.
275 */
276struct batadv_orig_ifinfo *
277batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
278 struct batadv_hard_iface *if_outgoing)
279{
280 struct batadv_orig_ifinfo *tmp, *orig_ifinfo = NULL;
281
282 rcu_read_lock();
283 hlist_for_each_entry_rcu(tmp, &orig_node->ifinfo_list,
284 list) {
285 if (tmp->if_outgoing != if_outgoing)
286 continue;
287
288 if (!atomic_inc_not_zero(&tmp->refcount))
289 continue;
290
291 orig_ifinfo = tmp;
292 break;
293 }
294 rcu_read_unlock();
295
296 return orig_ifinfo;
297}
298
299/**
300 * batadv_orig_ifinfo_new - search and possibly create an orig_ifinfo object
301 * @orig_node: the orig node to be queried
302 * @if_outgoing: the interface for which the ifinfo should be acquired
303 *
304 * Returns NULL in case of failure or the orig_ifinfo object for the if_outgoing
305 * interface otherwise. The object is created and added to the list
306 * if it does not exist.
307 *
308 * The object is returned with refcounter increased by 1.
309 */
310struct batadv_orig_ifinfo *
311batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
312 struct batadv_hard_iface *if_outgoing)
313{
314 struct batadv_orig_ifinfo *orig_ifinfo = NULL;
315 unsigned long reset_time;
316
317 spin_lock_bh(&orig_node->neigh_list_lock);
318
319 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, if_outgoing);
320 if (orig_ifinfo)
321 goto out;
322
323 orig_ifinfo = kzalloc(sizeof(*orig_ifinfo), GFP_ATOMIC);
324 if (!orig_ifinfo)
325 goto out;
326
327 if (if_outgoing != BATADV_IF_DEFAULT &&
328 !atomic_inc_not_zero(&if_outgoing->refcount)) {
329 kfree(orig_ifinfo);
330 orig_ifinfo = NULL;
331 goto out;
332 }
333
334 reset_time = jiffies - 1;
335 reset_time -= msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
336 orig_ifinfo->batman_seqno_reset = reset_time;
337 orig_ifinfo->if_outgoing = if_outgoing;
338 INIT_HLIST_NODE(&orig_ifinfo->list);
339 atomic_set(&orig_ifinfo->refcount, 2);
340 hlist_add_head_rcu(&orig_ifinfo->list,
341 &orig_node->ifinfo_list);
342out:
343 spin_unlock_bh(&orig_node->neigh_list_lock);
344 return orig_ifinfo;
345}
346
347/**
251 * batadv_neigh_ifinfo_get - find the ifinfo from an neigh_node 348 * batadv_neigh_ifinfo_get - find the ifinfo from an neigh_node
252 * @neigh_node: the neigh node to be queried 349 * @neigh_node: the neigh node to be queried
253 * @if_outgoing: the interface for which the ifinfo should be acquired 350 * @if_outgoing: the interface for which the ifinfo should be acquired
@@ -360,11 +457,51 @@ out:
360 return neigh_node; 457 return neigh_node;
361} 458}
362 459
460/**
461 * batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object
462 * @rcu: rcu pointer of the orig_ifinfo object
463 */
464static void batadv_orig_ifinfo_free_rcu(struct rcu_head *rcu)
465{
466 struct batadv_orig_ifinfo *orig_ifinfo;
467
468 orig_ifinfo = container_of(rcu, struct batadv_orig_ifinfo, rcu);
469
470 if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
471 batadv_hardif_free_ref_now(orig_ifinfo->if_outgoing);
472
473 kfree(orig_ifinfo);
474}
475
476/**
477 * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free
478 * the orig_ifinfo (without rcu callback)
479 * @orig_ifinfo: the orig_ifinfo object to release
480 */
481static void
482batadv_orig_ifinfo_free_ref_now(struct batadv_orig_ifinfo *orig_ifinfo)
483{
484 if (atomic_dec_and_test(&orig_ifinfo->refcount))
485 batadv_orig_ifinfo_free_rcu(&orig_ifinfo->rcu);
486}
487
488/**
489 * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly free
490 * the orig_ifinfo
491 * @orig_ifinfo: the orig_ifinfo object to release
492 */
493void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
494{
495 if (atomic_dec_and_test(&orig_ifinfo->refcount))
496 call_rcu(&orig_ifinfo->rcu, batadv_orig_ifinfo_free_rcu);
497}
498
363static void batadv_orig_node_free_rcu(struct rcu_head *rcu) 499static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
364{ 500{
365 struct hlist_node *node_tmp; 501 struct hlist_node *node_tmp;
366 struct batadv_neigh_node *neigh_node; 502 struct batadv_neigh_node *neigh_node;
367 struct batadv_orig_node *orig_node; 503 struct batadv_orig_node *orig_node;
504 struct batadv_orig_ifinfo *orig_ifinfo;
368 505
369 orig_node = container_of(rcu, struct batadv_orig_node, rcu); 506 orig_node = container_of(rcu, struct batadv_orig_node, rcu);
370 507
@@ -377,6 +514,11 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
377 batadv_neigh_node_free_ref_now(neigh_node); 514 batadv_neigh_node_free_ref_now(neigh_node);
378 } 515 }
379 516
517 hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
518 &orig_node->ifinfo_list, list) {
519 hlist_del_rcu(&orig_ifinfo->list);
520 batadv_orig_ifinfo_free_ref_now(orig_ifinfo);
521 }
380 spin_unlock_bh(&orig_node->neigh_list_lock); 522 spin_unlock_bh(&orig_node->neigh_list_lock);
381 523
382 /* Free nc_nodes */ 524 /* Free nc_nodes */
@@ -474,6 +616,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
474 616
475 INIT_HLIST_HEAD(&orig_node->neigh_list); 617 INIT_HLIST_HEAD(&orig_node->neigh_list);
476 INIT_LIST_HEAD(&orig_node->vlan_list); 618 INIT_LIST_HEAD(&orig_node->vlan_list);
619 INIT_HLIST_HEAD(&orig_node->ifinfo_list);
477 spin_lock_init(&orig_node->bcast_seqno_lock); 620 spin_lock_init(&orig_node->bcast_seqno_lock);
478 spin_lock_init(&orig_node->neigh_list_lock); 621 spin_lock_init(&orig_node->neigh_list_lock);
479 spin_lock_init(&orig_node->tt_buff_lock); 622 spin_lock_init(&orig_node->tt_buff_lock);
@@ -489,13 +632,11 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
489 orig_node->bat_priv = bat_priv; 632 orig_node->bat_priv = bat_priv;
490 memcpy(orig_node->orig, addr, ETH_ALEN); 633 memcpy(orig_node->orig, addr, ETH_ALEN);
491 batadv_dat_init_orig_node_addr(orig_node); 634 batadv_dat_init_orig_node_addr(orig_node);
492 orig_node->router = NULL;
493 atomic_set(&orig_node->last_ttvn, 0); 635 atomic_set(&orig_node->last_ttvn, 0);
494 orig_node->tt_buff = NULL; 636 orig_node->tt_buff = NULL;
495 orig_node->tt_buff_len = 0; 637 orig_node->tt_buff_len = 0;
496 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS); 638 reset_time = jiffies - 1 - msecs_to_jiffies(BATADV_RESET_PROTECTION_MS);
497 orig_node->bcast_seqno_reset = reset_time; 639 orig_node->bcast_seqno_reset = reset_time;
498 orig_node->batman_seqno_reset = reset_time;
499 640
500 /* create a vlan object for the "untagged" LAN */ 641 /* create a vlan object for the "untagged" LAN */
501 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS); 642 vlan = batadv_orig_node_vlan_new(orig_node, BATADV_NO_FLAGS);
@@ -520,6 +661,55 @@ free_orig_node:
520} 661}
521 662
522/** 663/**
664 * batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator
665 * @bat_priv: the bat priv with all the soft interface information
666 * @orig_node: orig node which is to be checked
667 *
668 * Returns true if any ifinfo entry was purged, false otherwise.
669 */
670static bool
671batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
672 struct batadv_orig_node *orig_node)
673{
674 struct batadv_orig_ifinfo *orig_ifinfo;
675 struct batadv_hard_iface *if_outgoing;
676 struct hlist_node *node_tmp;
677 bool ifinfo_purged = false;
678
679 spin_lock_bh(&orig_node->neigh_list_lock);
680
681 /* for all ifinfo objects for this originator */
682 hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
683 &orig_node->ifinfo_list, list) {
684 if_outgoing = orig_ifinfo->if_outgoing;
685
686 /* always keep the default interface */
687 if (if_outgoing == BATADV_IF_DEFAULT)
688 continue;
689
690 /* don't purge if the interface is not (going) down */
691 if ((if_outgoing->if_status != BATADV_IF_INACTIVE) &&
692 (if_outgoing->if_status != BATADV_IF_NOT_IN_USE) &&
693 (if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED))
694 continue;
695
696 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
697 "router/ifinfo purge: originator %pM, iface: %s\n",
698 orig_node->orig, if_outgoing->net_dev->name);
699
700 ifinfo_purged = true;
701
702 hlist_del_rcu(&orig_ifinfo->list);
703 batadv_orig_ifinfo_free_ref(orig_ifinfo);
704 }
705
706 spin_unlock_bh(&orig_node->neigh_list_lock);
707
708 return ifinfo_purged;
709}
710
711
712/**
523 * batadv_purge_orig_neighbors - purges neighbors from originator 713 * batadv_purge_orig_neighbors - purges neighbors from originator
524 * @bat_priv: the bat priv with all the soft interface information 714 * @bat_priv: the bat priv with all the soft interface information
525 * @orig_node: orig node which is to be checked 715 * @orig_node: orig node which is to be checked
@@ -607,10 +797,22 @@ batadv_find_best_neighbor(struct batadv_priv *bat_priv,
607 return best; 797 return best;
608} 798}
609 799
800/**
801 * batadv_purge_orig_node - purges obsolete information from an orig_node
802 * @bat_priv: the bat priv with all the soft interface information
803 * @orig_node: orig node which is to be checked
804 *
805 * This function checks if the orig_node or substructures of it have become
806 * obsolete, and purges this information if that's the case.
807 *
808 * Returns true if the orig_node is to be removed, false otherwise.
809 */
610static bool batadv_purge_orig_node(struct batadv_priv *bat_priv, 810static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
611 struct batadv_orig_node *orig_node) 811 struct batadv_orig_node *orig_node)
612{ 812{
613 struct batadv_neigh_node *best_neigh_node; 813 struct batadv_neigh_node *best_neigh_node;
814 struct batadv_hard_iface *hard_iface;
815 bool changed;
614 816
615 if (batadv_has_timed_out(orig_node->last_seen, 817 if (batadv_has_timed_out(orig_node->last_seen,
616 2 * BATADV_PURGE_TIMEOUT)) { 818 2 * BATADV_PURGE_TIMEOUT)) {
@@ -620,15 +822,39 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
620 jiffies_to_msecs(orig_node->last_seen)); 822 jiffies_to_msecs(orig_node->last_seen));
621 return true; 823 return true;
622 } 824 }
623 if (!batadv_purge_orig_neighbors(bat_priv, orig_node)) 825 changed = batadv_purge_orig_ifinfo(bat_priv, orig_node);
826 changed = changed || batadv_purge_orig_neighbors(bat_priv, orig_node);
827
828 if (!changed)
624 return false; 829 return false;
625 830
831 /* first for NULL ... */
626 best_neigh_node = batadv_find_best_neighbor(bat_priv, orig_node, 832 best_neigh_node = batadv_find_best_neighbor(bat_priv, orig_node,
627 BATADV_IF_DEFAULT); 833 BATADV_IF_DEFAULT);
628 batadv_update_route(bat_priv, orig_node, best_neigh_node); 834 batadv_update_route(bat_priv, orig_node, BATADV_IF_DEFAULT,
835 best_neigh_node);
629 if (best_neigh_node) 836 if (best_neigh_node)
630 batadv_neigh_node_free_ref(best_neigh_node); 837 batadv_neigh_node_free_ref(best_neigh_node);
631 838
839 /* ... then for all other interfaces. */
840 rcu_read_lock();
841 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
842 if (hard_iface->if_status != BATADV_IF_ACTIVE)
843 continue;
844
845 if (hard_iface->soft_iface != bat_priv->soft_iface)
846 continue;
847
848 best_neigh_node = batadv_find_best_neighbor(bat_priv,
849 orig_node,
850 hard_iface);
851 batadv_update_route(bat_priv, orig_node, hard_iface,
852 best_neigh_node);
853 if (best_neigh_node)
854 batadv_neigh_node_free_ref(best_neigh_node);
855 }
856 rcu_read_unlock();
857
632 return false; 858 return false;
633} 859}
634 860
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 29fa4c428b59..75a4d7bad620 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -34,7 +34,8 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
34 struct batadv_orig_node *orig_node); 34 struct batadv_orig_node *orig_node);
35void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node); 35void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
36struct batadv_neigh_node * 36struct batadv_neigh_node *
37batadv_orig_node_get_router(struct batadv_orig_node *orig_node); 37batadv_orig_router_get(struct batadv_orig_node *orig_node,
38 const struct batadv_hard_iface *if_outgoing);
38struct batadv_neigh_ifinfo * 39struct batadv_neigh_ifinfo *
39batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh, 40batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
40 struct batadv_hard_iface *if_outgoing); 41 struct batadv_hard_iface *if_outgoing);
@@ -42,6 +43,15 @@ struct batadv_neigh_ifinfo *
42batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh, 43batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
43 struct batadv_hard_iface *if_outgoing); 44 struct batadv_hard_iface *if_outgoing);
44void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo); 45void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo);
46
47struct batadv_orig_ifinfo *
48batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
49 struct batadv_hard_iface *if_outgoing);
50struct batadv_orig_ifinfo *
51batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
52 struct batadv_hard_iface *if_outgoing);
53void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo);
54
45int batadv_orig_seq_print_text(struct seq_file *seq, void *offset); 55int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
46int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, 56int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
47 int max_if_num); 57 int max_if_num);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 4fd2687b88c2..55e9aebcbc80 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -33,13 +33,32 @@
33static int batadv_route_unicast_packet(struct sk_buff *skb, 33static int batadv_route_unicast_packet(struct sk_buff *skb,
34 struct batadv_hard_iface *recv_if); 34 struct batadv_hard_iface *recv_if);
35 35
36/**
37 * _batadv_update_route - set the router for this originator
38 * @bat_priv: the bat priv with all the soft interface information
39 * @orig_node: orig node which is to be configured
40 * @recv_if: the receive interface for which this route is set
41 * @neigh_node: neighbor which should be the next router
42 *
43 * This function does not perform any error checks
44 */
36static void _batadv_update_route(struct batadv_priv *bat_priv, 45static void _batadv_update_route(struct batadv_priv *bat_priv,
37 struct batadv_orig_node *orig_node, 46 struct batadv_orig_node *orig_node,
47 struct batadv_hard_iface *recv_if,
38 struct batadv_neigh_node *neigh_node) 48 struct batadv_neigh_node *neigh_node)
39{ 49{
50 struct batadv_orig_ifinfo *orig_ifinfo;
40 struct batadv_neigh_node *curr_router; 51 struct batadv_neigh_node *curr_router;
41 52
42 curr_router = batadv_orig_node_get_router(orig_node); 53 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, recv_if);
54 if (!orig_ifinfo)
55 return;
56
57 rcu_read_lock();
58 curr_router = rcu_dereference(orig_ifinfo->router);
59 if (curr_router && !atomic_inc_not_zero(&curr_router->refcount))
60 curr_router = NULL;
61 rcu_read_unlock();
43 62
44 /* route deleted */ 63 /* route deleted */
45 if ((curr_router) && (!neigh_node)) { 64 if ((curr_router) && (!neigh_node)) {
@@ -69,16 +88,25 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
69 neigh_node = NULL; 88 neigh_node = NULL;
70 89
71 spin_lock_bh(&orig_node->neigh_list_lock); 90 spin_lock_bh(&orig_node->neigh_list_lock);
72 rcu_assign_pointer(orig_node->router, neigh_node); 91 rcu_assign_pointer(orig_ifinfo->router, neigh_node);
73 spin_unlock_bh(&orig_node->neigh_list_lock); 92 spin_unlock_bh(&orig_node->neigh_list_lock);
93 batadv_orig_ifinfo_free_ref(orig_ifinfo);
74 94
75 /* decrease refcount of previous best neighbor */ 95 /* decrease refcount of previous best neighbor */
76 if (curr_router) 96 if (curr_router)
77 batadv_neigh_node_free_ref(curr_router); 97 batadv_neigh_node_free_ref(curr_router);
78} 98}
79 99
100/**
101 * batadv_update_route - set the router for this originator
102 * @bat_priv: the bat priv with all the soft interface information
103 * @orig_node: orig node which is to be configured
104 * @recv_if: the receive interface for which this route is set
105 * @neigh_node: neighbor which should be the next router
106 */
80void batadv_update_route(struct batadv_priv *bat_priv, 107void batadv_update_route(struct batadv_priv *bat_priv,
81 struct batadv_orig_node *orig_node, 108 struct batadv_orig_node *orig_node,
109 struct batadv_hard_iface *recv_if,
82 struct batadv_neigh_node *neigh_node) 110 struct batadv_neigh_node *neigh_node)
83{ 111{
84 struct batadv_neigh_node *router = NULL; 112 struct batadv_neigh_node *router = NULL;
@@ -86,10 +114,10 @@ void batadv_update_route(struct batadv_priv *bat_priv,
86 if (!orig_node) 114 if (!orig_node)
87 goto out; 115 goto out;
88 116
89 router = batadv_orig_node_get_router(orig_node); 117 router = batadv_orig_router_get(orig_node, recv_if);
90 118
91 if (router != neigh_node) 119 if (router != neigh_node)
92 _batadv_update_route(bat_priv, orig_node, neigh_node); 120 _batadv_update_route(bat_priv, orig_node, recv_if, neigh_node);
93 121
94out: 122out:
95 if (router) 123 if (router)
@@ -406,7 +434,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
406 if (!orig_node) 434 if (!orig_node)
407 return NULL; 435 return NULL;
408 436
409 router = batadv_orig_node_get_router(orig_node); 437 router = batadv_orig_router_get(orig_node, recv_if);
410 438
411 /* TODO: fill this later with new bonding mechanism */ 439 /* TODO: fill this later with new bonding mechanism */
412 440
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index 192f0aab7a2b..8920d0b1056c 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -23,6 +23,7 @@ bool batadv_check_management_packet(struct sk_buff *skb,
23 int header_len); 23 int header_len);
24void batadv_update_route(struct batadv_priv *bat_priv, 24void batadv_update_route(struct batadv_priv *bat_priv,
25 struct batadv_orig_node *orig_node, 25 struct batadv_orig_node *orig_node,
26 struct batadv_hard_iface *recv_if,
26 struct batadv_neigh_node *neigh_node); 27 struct batadv_neigh_node *neigh_node);
27int batadv_recv_icmp_packet(struct sk_buff *skb, 28int batadv_recv_icmp_packet(struct sk_buff *skb,
28 struct batadv_hard_iface *recv_if); 29 struct batadv_hard_iface *recv_if);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 22c32ae12e65..ec89a1b9fc06 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1400,7 +1400,8 @@ batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1400 1400
1401 head = &tt_global_entry->orig_list; 1401 head = &tt_global_entry->orig_list;
1402 hlist_for_each_entry_rcu(orig_entry, head, list) { 1402 hlist_for_each_entry_rcu(orig_entry, head, list) {
1403 router = batadv_orig_node_get_router(orig_entry->orig_node); 1403 router = batadv_orig_router_get(orig_entry->orig_node,
1404 BATADV_IF_DEFAULT);
1404 if (!router) 1405 if (!router)
1405 continue; 1406 continue;
1406 1407
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 8435d7c83a14..d3e2bf486ec0 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -101,6 +101,28 @@ struct batadv_hard_iface {
101}; 101};
102 102
103/** 103/**
104 * struct batadv_orig_ifinfo - originator info per outgoing interface
105 * @list: list node for orig_node::ifinfo_list
106 * @if_outgoing: pointer to outgoing hard interface
107 * @router: router that should be used to reach this originator
108 * @last_real_seqno: last and best known sequence number
109 * @last_ttl: ttl of last received packet
110 * @batman_seqno_reset: time when the batman seqno window was reset
111 * @refcount: number of contexts the object is used
112 * @rcu: struct used for freeing in an RCU-safe manner
113 */
114struct batadv_orig_ifinfo {
115 struct hlist_node list;
116 struct batadv_hard_iface *if_outgoing;
117 struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
118 uint32_t last_real_seqno;
119 uint8_t last_ttl;
120 unsigned long batman_seqno_reset;
121 atomic_t refcount;
122 struct rcu_head rcu;
123};
124
125/**
104 * struct batadv_frag_table_entry - head in the fragment buffer table 126 * struct batadv_frag_table_entry - head in the fragment buffer table
105 * @head: head of list with fragments 127 * @head: head of list with fragments
106 * @lock: lock to protect the list of fragments 128 * @lock: lock to protect the list of fragments
@@ -175,11 +197,10 @@ struct batadv_orig_bat_iv {
175 * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh 197 * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh
176 * @orig: originator ethernet address 198 * @orig: originator ethernet address
177 * @primary_addr: hosts primary interface address 199 * @primary_addr: hosts primary interface address
178 * @router: router that should be used to reach this originator 200 * @ifinfo_list: list for routers per outgoing interface
179 * @batadv_dat_addr_t: address of the orig node in the distributed hash 201 * @batadv_dat_addr_t: address of the orig node in the distributed hash
180 * @last_seen: time when last packet from this node was received 202 * @last_seen: time when last packet from this node was received
181 * @bcast_seqno_reset: time when the broadcast seqno window was reset 203 * @bcast_seqno_reset: time when the broadcast seqno window was reset
182 * @batman_seqno_reset: time when the batman seqno window was reset
183 * @capabilities: announced capabilities of this originator 204 * @capabilities: announced capabilities of this originator
184 * @last_ttvn: last seen translation table version number 205 * @last_ttvn: last seen translation table version number
185 * @tt_buff: last tt changeset this node received from the orig node 206 * @tt_buff: last tt changeset this node received from the orig node
@@ -192,8 +213,6 @@ struct batadv_orig_bat_iv {
192 * made up by two operations (data structure update and metdata -CRC/TTVN- 213 * made up by two operations (data structure update and metdata -CRC/TTVN-
193 * recalculation) and they have to be executed atomically in order to avoid 214 * recalculation) and they have to be executed atomically in order to avoid
194 * another thread to read the table/metadata between those. 215 * another thread to read the table/metadata between those.
195 * @last_real_seqno: last and best known sequence number
196 * @last_ttl: ttl of last received packet
197 * @bcast_bits: bitfield containing the info which payload broadcast originated 216 * @bcast_bits: bitfield containing the info which payload broadcast originated
198 * from this orig node this host already has seen (relative to 217 * from this orig node this host already has seen (relative to
199 * last_bcast_seqno) 218 * last_bcast_seqno)
@@ -218,13 +237,12 @@ struct batadv_orig_bat_iv {
218struct batadv_orig_node { 237struct batadv_orig_node {
219 uint8_t orig[ETH_ALEN]; 238 uint8_t orig[ETH_ALEN];
220 uint8_t primary_addr[ETH_ALEN]; 239 uint8_t primary_addr[ETH_ALEN];
221 struct batadv_neigh_node __rcu *router; /* rcu protected pointer */ 240 struct hlist_head ifinfo_list;
222#ifdef CONFIG_BATMAN_ADV_DAT 241#ifdef CONFIG_BATMAN_ADV_DAT
223 batadv_dat_addr_t dat_addr; 242 batadv_dat_addr_t dat_addr;
224#endif 243#endif
225 unsigned long last_seen; 244 unsigned long last_seen;
226 unsigned long bcast_seqno_reset; 245 unsigned long bcast_seqno_reset;
227 unsigned long batman_seqno_reset;
228 uint8_t capabilities; 246 uint8_t capabilities;
229 atomic_t last_ttvn; 247 atomic_t last_ttvn;
230 unsigned char *tt_buff; 248 unsigned char *tt_buff;
@@ -233,8 +251,6 @@ struct batadv_orig_node {
233 bool tt_initialised; 251 bool tt_initialised;
234 /* prevents from changing the table while reading it */ 252 /* prevents from changing the table while reading it */
235 spinlock_t tt_lock; 253 spinlock_t tt_lock;
236 uint32_t last_real_seqno;
237 uint8_t last_ttl;
238 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); 254 DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
239 uint32_t last_bcast_seqno; 255 uint32_t last_bcast_seqno;
240 struct hlist_head neigh_list; 256 struct hlist_head neigh_list;