diff options
author | David S. Miller <davem@davemloft.net> | 2012-10-31 13:52:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-10-31 13:52:52 -0400 |
commit | 157083811c933fc223a3193d319c7ac805f30bb7 (patch) | |
tree | 5ff8ebd0cd890b4949777199e44b05ff5d5cb807 | |
parent | 1627801def0e1cef948f9d593e6757eab295803f (diff) | |
parent | 0aca86cd92282359d2f7202804bd92e7d092c04e (diff) |
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
included changes:
- some code cleanups and minor fixes (3 of them were reported by Coverity)
- 'struct hard_iface' re-shaping to improve multi-protocol support
- ECTP packets silent drop
- transfer the WIFI flag on clients in case of roaming
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 43 | ||||
-rw-r--r-- | net/batman-adv/bitarray.c | 23 | ||||
-rw-r--r-- | net/batman-adv/bridge_loop_avoidance.c | 36 | ||||
-rw-r--r-- | net/batman-adv/debugfs.c | 6 | ||||
-rw-r--r-- | net/batman-adv/gateway_client.c | 19 | ||||
-rw-r--r-- | net/batman-adv/hard-interface.c | 4 | ||||
-rw-r--r-- | net/batman-adv/icmp_socket.c | 12 | ||||
-rw-r--r-- | net/batman-adv/main.c | 46 | ||||
-rw-r--r-- | net/batman-adv/main.h | 19 | ||||
-rw-r--r-- | net/batman-adv/originator.c | 19 | ||||
-rw-r--r-- | net/batman-adv/routing.c | 54 | ||||
-rw-r--r-- | net/batman-adv/soft-interface.c | 56 | ||||
-rw-r--r-- | net/batman-adv/sysfs.c | 49 | ||||
-rw-r--r-- | net/batman-adv/translation-table.c | 77 | ||||
-rw-r--r-- | net/batman-adv/translation-table.h | 6 | ||||
-rw-r--r-- | net/batman-adv/types.h | 16 |
16 files changed, 238 insertions, 247 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index b02b75dae3a8..75403a491892 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -57,20 +57,22 @@ out: | |||
57 | static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) | 57 | static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) |
58 | { | 58 | { |
59 | struct batadv_ogm_packet *batadv_ogm_packet; | 59 | struct batadv_ogm_packet *batadv_ogm_packet; |
60 | unsigned char *ogm_buff; | ||
60 | uint32_t random_seqno; | 61 | uint32_t random_seqno; |
61 | int res = -ENOMEM; | 62 | int res = -ENOMEM; |
62 | 63 | ||
63 | /* randomize initial seqno to avoid collision */ | 64 | /* randomize initial seqno to avoid collision */ |
64 | get_random_bytes(&random_seqno, sizeof(random_seqno)); | 65 | get_random_bytes(&random_seqno, sizeof(random_seqno)); |
65 | atomic_set(&hard_iface->seqno, random_seqno); | 66 | atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); |
66 | 67 | ||
67 | hard_iface->packet_len = BATADV_OGM_HLEN; | 68 | hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; |
68 | hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); | 69 | ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); |
69 | 70 | if (!ogm_buff) | |
70 | if (!hard_iface->packet_buff) | ||
71 | goto out; | 71 | goto out; |
72 | 72 | ||
73 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 73 | hard_iface->bat_iv.ogm_buff = ogm_buff; |
74 | |||
75 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; | ||
74 | batadv_ogm_packet->header.packet_type = BATADV_IV_OGM; | 76 | batadv_ogm_packet->header.packet_type = BATADV_IV_OGM; |
75 | batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; | 77 | batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION; |
76 | batadv_ogm_packet->header.ttl = 2; | 78 | batadv_ogm_packet->header.ttl = 2; |
@@ -87,15 +89,16 @@ out: | |||
87 | 89 | ||
88 | static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) | 90 | static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) |
89 | { | 91 | { |
90 | kfree(hard_iface->packet_buff); | 92 | kfree(hard_iface->bat_iv.ogm_buff); |
91 | hard_iface->packet_buff = NULL; | 93 | hard_iface->bat_iv.ogm_buff = NULL; |
92 | } | 94 | } |
93 | 95 | ||
94 | static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) | 96 | static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) |
95 | { | 97 | { |
96 | struct batadv_ogm_packet *batadv_ogm_packet; | 98 | struct batadv_ogm_packet *batadv_ogm_packet; |
99 | unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
97 | 100 | ||
98 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 101 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; |
99 | memcpy(batadv_ogm_packet->orig, | 102 | memcpy(batadv_ogm_packet->orig, |
100 | hard_iface->net_dev->dev_addr, ETH_ALEN); | 103 | hard_iface->net_dev->dev_addr, ETH_ALEN); |
101 | memcpy(batadv_ogm_packet->prev_sender, | 104 | memcpy(batadv_ogm_packet->prev_sender, |
@@ -106,8 +109,9 @@ static void | |||
106 | batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) | 109 | batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) |
107 | { | 110 | { |
108 | struct batadv_ogm_packet *batadv_ogm_packet; | 111 | struct batadv_ogm_packet *batadv_ogm_packet; |
112 | unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; | ||
109 | 113 | ||
110 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 114 | batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; |
111 | batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; | 115 | batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP; |
112 | batadv_ogm_packet->header.ttl = BATADV_TTL; | 116 | batadv_ogm_packet->header.ttl = BATADV_TTL; |
113 | } | 117 | } |
@@ -590,8 +594,10 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, | |||
590 | static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | 594 | static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) |
591 | { | 595 | { |
592 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); | 596 | struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); |
597 | unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; | ||
593 | struct batadv_ogm_packet *batadv_ogm_packet; | 598 | struct batadv_ogm_packet *batadv_ogm_packet; |
594 | struct batadv_hard_iface *primary_if; | 599 | struct batadv_hard_iface *primary_if; |
600 | int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len; | ||
595 | int vis_server, tt_num_changes = 0; | 601 | int vis_server, tt_num_changes = 0; |
596 | uint32_t seqno; | 602 | uint32_t seqno; |
597 | uint8_t bandwidth; | 603 | uint8_t bandwidth; |
@@ -600,17 +606,16 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | |||
600 | primary_if = batadv_primary_if_get_selected(bat_priv); | 606 | primary_if = batadv_primary_if_get_selected(bat_priv); |
601 | 607 | ||
602 | if (hard_iface == primary_if) | 608 | if (hard_iface == primary_if) |
603 | tt_num_changes = batadv_tt_append_diff(bat_priv, | 609 | tt_num_changes = batadv_tt_append_diff(bat_priv, ogm_buff, |
604 | &hard_iface->packet_buff, | 610 | ogm_buff_len, |
605 | &hard_iface->packet_len, | ||
606 | BATADV_OGM_HLEN); | 611 | BATADV_OGM_HLEN); |
607 | 612 | ||
608 | batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; | 613 | batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff); |
609 | 614 | ||
610 | /* change sequence number to network order */ | 615 | /* change sequence number to network order */ |
611 | seqno = (uint32_t)atomic_read(&hard_iface->seqno); | 616 | seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno); |
612 | batadv_ogm_packet->seqno = htonl(seqno); | 617 | batadv_ogm_packet->seqno = htonl(seqno); |
613 | atomic_inc(&hard_iface->seqno); | 618 | atomic_inc(&hard_iface->bat_iv.ogm_seqno); |
614 | 619 | ||
615 | batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); | 620 | batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); |
616 | batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); | 621 | batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); |
@@ -631,8 +636,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) | |||
631 | } | 636 | } |
632 | 637 | ||
633 | batadv_slide_own_bcast_window(hard_iface); | 638 | batadv_slide_own_bcast_window(hard_iface); |
634 | batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, | 639 | batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff, |
635 | hard_iface->packet_len, hard_iface, 1, | 640 | hard_iface->bat_iv.ogm_buff_len, hard_iface, 1, |
636 | batadv_iv_ogm_emit_send_time(bat_priv)); | 641 | batadv_iv_ogm_emit_send_time(bat_priv)); |
637 | 642 | ||
638 | if (primary_if) | 643 | if (primary_if) |
@@ -1015,7 +1020,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1015 | return; | 1020 | return; |
1016 | 1021 | ||
1017 | /* could be changed by schedule_own_packet() */ | 1022 | /* could be changed by schedule_own_packet() */ |
1018 | if_incoming_seqno = atomic_read(&if_incoming->seqno); | 1023 | if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno); |
1019 | 1024 | ||
1020 | if (batadv_ogm_packet->flags & BATADV_DIRECTLINK) | 1025 | if (batadv_ogm_packet->flags & BATADV_DIRECTLINK) |
1021 | has_directlink_flag = 1; | 1026 | has_directlink_flag = 1; |
diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index aea174cdbfbd..5453b17d8df2 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c | |||
@@ -79,20 +79,17 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, | |||
79 | * or the old packet got delayed somewhere in the network. The | 79 | * or the old packet got delayed somewhere in the network. The |
80 | * packet should be dropped without calling this function if the | 80 | * packet should be dropped without calling this function if the |
81 | * seqno window is protected. | 81 | * seqno window is protected. |
82 | * | ||
83 | * seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE | ||
84 | * or | ||
85 | * seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE | ||
82 | */ | 86 | */ |
83 | if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE || | 87 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
84 | seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) { | 88 | "Other host probably restarted!\n"); |
85 | 89 | ||
86 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 90 | bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); |
87 | "Other host probably restarted!\n"); | 91 | if (set_mark) |
88 | 92 | batadv_set_bit(seq_bits, 0); | |
89 | bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); | ||
90 | if (set_mark) | ||
91 | batadv_set_bit(seq_bits, 0); | ||
92 | |||
93 | return 1; | ||
94 | } | ||
95 | 93 | ||
96 | /* never reached */ | 94 | return 1; |
97 | return 0; | ||
98 | } | 95 | } |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index fd8d5afec0dd..29a5542aac75 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -1585,23 +1585,11 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1585 | struct hlist_head *head; | 1585 | struct hlist_head *head; |
1586 | uint32_t i; | 1586 | uint32_t i; |
1587 | bool is_own; | 1587 | bool is_own; |
1588 | int ret = 0; | ||
1589 | uint8_t *primary_addr; | 1588 | uint8_t *primary_addr; |
1590 | 1589 | ||
1591 | primary_if = batadv_primary_if_get_selected(bat_priv); | 1590 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
1592 | if (!primary_if) { | 1591 | if (!primary_if) |
1593 | ret = seq_printf(seq, | ||
1594 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
1595 | net_dev->name); | ||
1596 | goto out; | ||
1597 | } | ||
1598 | |||
1599 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
1600 | ret = seq_printf(seq, | ||
1601 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
1602 | net_dev->name); | ||
1603 | goto out; | 1592 | goto out; |
1604 | } | ||
1605 | 1593 | ||
1606 | primary_addr = primary_if->net_dev->dev_addr; | 1594 | primary_addr = primary_if->net_dev->dev_addr; |
1607 | seq_printf(seq, | 1595 | seq_printf(seq, |
@@ -1628,7 +1616,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1628 | out: | 1616 | out: |
1629 | if (primary_if) | 1617 | if (primary_if) |
1630 | batadv_hardif_free_ref(primary_if); | 1618 | batadv_hardif_free_ref(primary_if); |
1631 | return ret; | 1619 | return 0; |
1632 | } | 1620 | } |
1633 | 1621 | ||
1634 | int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | 1622 | int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) |
@@ -1643,23 +1631,11 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1643 | int secs, msecs; | 1631 | int secs, msecs; |
1644 | uint32_t i; | 1632 | uint32_t i; |
1645 | bool is_own; | 1633 | bool is_own; |
1646 | int ret = 0; | ||
1647 | uint8_t *primary_addr; | 1634 | uint8_t *primary_addr; |
1648 | 1635 | ||
1649 | primary_if = batadv_primary_if_get_selected(bat_priv); | 1636 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
1650 | if (!primary_if) { | 1637 | if (!primary_if) |
1651 | ret = seq_printf(seq, | ||
1652 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
1653 | net_dev->name); | ||
1654 | goto out; | ||
1655 | } | ||
1656 | |||
1657 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
1658 | ret = seq_printf(seq, | ||
1659 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
1660 | net_dev->name); | ||
1661 | goto out; | 1638 | goto out; |
1662 | } | ||
1663 | 1639 | ||
1664 | primary_addr = primary_if->net_dev->dev_addr; | 1640 | primary_addr = primary_if->net_dev->dev_addr; |
1665 | seq_printf(seq, | 1641 | seq_printf(seq, |
@@ -1693,5 +1669,5 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) | |||
1693 | out: | 1669 | out: |
1694 | if (primary_if) | 1670 | if (primary_if) |
1695 | batadv_hardif_free_ref(primary_if); | 1671 | batadv_hardif_free_ref(primary_if); |
1696 | return ret; | 1672 | return 0; |
1697 | } | 1673 | } |
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c index 391d4fb2026f..bd032bc4e262 100644 --- a/net/batman-adv/debugfs.c +++ b/net/batman-adv/debugfs.c | |||
@@ -99,15 +99,17 @@ int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) | |||
99 | 99 | ||
100 | static int batadv_log_open(struct inode *inode, struct file *file) | 100 | static int batadv_log_open(struct inode *inode, struct file *file) |
101 | { | 101 | { |
102 | if (!try_module_get(THIS_MODULE)) | ||
103 | return -EBUSY; | ||
104 | |||
102 | nonseekable_open(inode, file); | 105 | nonseekable_open(inode, file); |
103 | file->private_data = inode->i_private; | 106 | file->private_data = inode->i_private; |
104 | batadv_inc_module_count(); | ||
105 | return 0; | 107 | return 0; |
106 | } | 108 | } |
107 | 109 | ||
108 | static int batadv_log_release(struct inode *inode, struct file *file) | 110 | static int batadv_log_release(struct inode *inode, struct file *file) |
109 | { | 111 | { |
110 | batadv_dec_module_count(); | 112 | module_put(THIS_MODULE); |
111 | return 0; | 113 | return 0; |
112 | } | 114 | } |
113 | 115 | ||
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 15d67abc10a4..dd07c7e3654f 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -477,22 +477,11 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) | |||
477 | struct batadv_hard_iface *primary_if; | 477 | struct batadv_hard_iface *primary_if; |
478 | struct batadv_gw_node *gw_node; | 478 | struct batadv_gw_node *gw_node; |
479 | struct hlist_node *node; | 479 | struct hlist_node *node; |
480 | int gw_count = 0, ret = 0; | 480 | int gw_count = 0; |
481 | 481 | ||
482 | primary_if = batadv_primary_if_get_selected(bat_priv); | 482 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
483 | if (!primary_if) { | 483 | if (!primary_if) |
484 | ret = seq_printf(seq, | ||
485 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
486 | net_dev->name); | ||
487 | goto out; | 484 | goto out; |
488 | } | ||
489 | |||
490 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
491 | ret = seq_printf(seq, | ||
492 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
493 | net_dev->name); | ||
494 | goto out; | ||
495 | } | ||
496 | 485 | ||
497 | seq_printf(seq, | 486 | seq_printf(seq, |
498 | " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", | 487 | " %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", |
@@ -519,7 +508,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) | |||
519 | out: | 508 | out: |
520 | if (primary_if) | 509 | if (primary_if) |
521 | batadv_hardif_free_ref(primary_if); | 510 | batadv_hardif_free_ref(primary_if); |
522 | return ret; | 511 | return 0; |
523 | } | 512 | } |
524 | 513 | ||
525 | static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) | 514 | static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len) |
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index d112fd6750b0..fab9e4158dc2 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c | |||
@@ -450,8 +450,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) | |||
450 | /* This can't be called via a bat_priv callback because | 450 | /* This can't be called via a bat_priv callback because |
451 | * we have no bat_priv yet. | 451 | * we have no bat_priv yet. |
452 | */ | 452 | */ |
453 | atomic_set(&hard_iface->seqno, 1); | 453 | atomic_set(&hard_iface->bat_iv.ogm_seqno, 1); |
454 | hard_iface->packet_buff = NULL; | 454 | hard_iface->bat_iv.ogm_buff = NULL; |
455 | 455 | ||
456 | return hard_iface; | 456 | return hard_iface; |
457 | 457 | ||
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index bde3cf747507..5874c0e84846 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c | |||
@@ -42,12 +42,16 @@ static int batadv_socket_open(struct inode *inode, struct file *file) | |||
42 | unsigned int i; | 42 | unsigned int i; |
43 | struct batadv_socket_client *socket_client; | 43 | struct batadv_socket_client *socket_client; |
44 | 44 | ||
45 | if (!try_module_get(THIS_MODULE)) | ||
46 | return -EBUSY; | ||
47 | |||
45 | nonseekable_open(inode, file); | 48 | nonseekable_open(inode, file); |
46 | 49 | ||
47 | socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL); | 50 | socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL); |
48 | 51 | if (!socket_client) { | |
49 | if (!socket_client) | 52 | module_put(THIS_MODULE); |
50 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | } | ||
51 | 55 | ||
52 | for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) { | 56 | for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) { |
53 | if (!batadv_socket_client_hash[i]) { | 57 | if (!batadv_socket_client_hash[i]) { |
@@ -59,6 +63,7 @@ static int batadv_socket_open(struct inode *inode, struct file *file) | |||
59 | if (i == ARRAY_SIZE(batadv_socket_client_hash)) { | 63 | if (i == ARRAY_SIZE(batadv_socket_client_hash)) { |
60 | pr_err("Error - can't add another packet client: maximum number of clients reached\n"); | 64 | pr_err("Error - can't add another packet client: maximum number of clients reached\n"); |
61 | kfree(socket_client); | 65 | kfree(socket_client); |
66 | module_put(THIS_MODULE); | ||
62 | return -EXFULL; | 67 | return -EXFULL; |
63 | } | 68 | } |
64 | 69 | ||
@@ -71,7 +76,6 @@ static int batadv_socket_open(struct inode *inode, struct file *file) | |||
71 | 76 | ||
72 | file->private_data = socket_client; | 77 | file->private_data = socket_client; |
73 | 78 | ||
74 | batadv_inc_module_count(); | ||
75 | return 0; | 79 | return 0; |
76 | } | 80 | } |
77 | 81 | ||
@@ -96,7 +100,7 @@ static int batadv_socket_release(struct inode *inode, struct file *file) | |||
96 | spin_unlock_bh(&socket_client->lock); | 100 | spin_unlock_bh(&socket_client->lock); |
97 | 101 | ||
98 | kfree(socket_client); | 102 | kfree(socket_client); |
99 | batadv_dec_module_count(); | 103 | module_put(THIS_MODULE); |
100 | 104 | ||
101 | return 0; | 105 | return 0; |
102 | } | 106 | } |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index b4aa470bc4a6..f9bcfa17f50f 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -160,16 +160,6 @@ void batadv_mesh_free(struct net_device *soft_iface) | |||
160 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); | 160 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); |
161 | } | 161 | } |
162 | 162 | ||
163 | void batadv_inc_module_count(void) | ||
164 | { | ||
165 | try_module_get(THIS_MODULE); | ||
166 | } | ||
167 | |||
168 | void batadv_dec_module_count(void) | ||
169 | { | ||
170 | module_put(THIS_MODULE); | ||
171 | } | ||
172 | |||
173 | int batadv_is_my_mac(const uint8_t *addr) | 163 | int batadv_is_my_mac(const uint8_t *addr) |
174 | { | 164 | { |
175 | const struct batadv_hard_iface *hard_iface; | 165 | const struct batadv_hard_iface *hard_iface; |
@@ -188,6 +178,42 @@ int batadv_is_my_mac(const uint8_t *addr) | |||
188 | return 0; | 178 | return 0; |
189 | } | 179 | } |
190 | 180 | ||
181 | /** | ||
182 | * batadv_seq_print_text_primary_if_get - called from debugfs table printing | ||
183 | * function that requires the primary interface | ||
184 | * @seq: debugfs table seq_file struct | ||
185 | * | ||
186 | * Returns primary interface if found or NULL otherwise. | ||
187 | */ | ||
188 | struct batadv_hard_iface * | ||
189 | batadv_seq_print_text_primary_if_get(struct seq_file *seq) | ||
190 | { | ||
191 | struct net_device *net_dev = (struct net_device *)seq->private; | ||
192 | struct batadv_priv *bat_priv = netdev_priv(net_dev); | ||
193 | struct batadv_hard_iface *primary_if; | ||
194 | |||
195 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
196 | |||
197 | if (!primary_if) { | ||
198 | seq_printf(seq, | ||
199 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
200 | net_dev->name); | ||
201 | goto out; | ||
202 | } | ||
203 | |||
204 | if (primary_if->if_status == BATADV_IF_ACTIVE) | ||
205 | goto out; | ||
206 | |||
207 | seq_printf(seq, | ||
208 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
209 | net_dev->name); | ||
210 | batadv_hardif_free_ref(primary_if); | ||
211 | primary_if = NULL; | ||
212 | |||
213 | out: | ||
214 | return primary_if; | ||
215 | } | ||
216 | |||
191 | static int batadv_recv_unhandled_packet(struct sk_buff *skb, | 217 | static int batadv_recv_unhandled_packet(struct sk_buff *skb, |
192 | struct batadv_hard_iface *recv_if) | 218 | struct batadv_hard_iface *recv_if) |
193 | { | 219 | { |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index d57b746219de..897ba6a8f8f2 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -150,9 +150,9 @@ extern struct workqueue_struct *batadv_event_workqueue; | |||
150 | 150 | ||
151 | int batadv_mesh_init(struct net_device *soft_iface); | 151 | int batadv_mesh_init(struct net_device *soft_iface); |
152 | void batadv_mesh_free(struct net_device *soft_iface); | 152 | void batadv_mesh_free(struct net_device *soft_iface); |
153 | void batadv_inc_module_count(void); | ||
154 | void batadv_dec_module_count(void); | ||
155 | int batadv_is_my_mac(const uint8_t *addr); | 153 | int batadv_is_my_mac(const uint8_t *addr); |
154 | struct batadv_hard_iface * | ||
155 | batadv_seq_print_text_primary_if_get(struct seq_file *seq); | ||
156 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | 156 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, |
157 | struct packet_type *ptype, | 157 | struct packet_type *ptype, |
158 | struct net_device *orig_dev); | 158 | struct net_device *orig_dev); |
@@ -165,12 +165,19 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops); | |||
165 | int batadv_algo_select(struct batadv_priv *bat_priv, char *name); | 165 | int batadv_algo_select(struct batadv_priv *bat_priv, char *name); |
166 | int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); | 166 | int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); |
167 | 167 | ||
168 | /* all messages related to routing / flooding / broadcasting / etc */ | 168 | /** |
169 | * enum batadv_dbg_level - available log levels | ||
170 | * @BATADV_DBG_BATMAN: OGM and TQ computations related messages | ||
171 | * @BATADV_DBG_ROUTES: route added / changed / deleted | ||
172 | * @BATADV_DBG_TT: translation table messages | ||
173 | * @BATADV_DBG_BLA: bridge loop avoidance messages | ||
174 | * @BATADV_DBG_ALL: the union of all the above log levels | ||
175 | */ | ||
169 | enum batadv_dbg_level { | 176 | enum batadv_dbg_level { |
170 | BATADV_DBG_BATMAN = BIT(0), | 177 | BATADV_DBG_BATMAN = BIT(0), |
171 | BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */ | 178 | BATADV_DBG_ROUTES = BIT(1), |
172 | BATADV_DBG_TT = BIT(2), /* translation table operations */ | 179 | BATADV_DBG_TT = BIT(2), |
173 | BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */ | 180 | BATADV_DBG_BLA = BIT(3), |
174 | BATADV_DBG_ALL = 15, | 181 | BATADV_DBG_ALL = 15, |
175 | }; | 182 | }; |
176 | 183 | ||
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index ac9bdf8f80a6..d9c14b8fca0e 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -415,23 +415,10 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) | |||
415 | int last_seen_msecs; | 415 | int last_seen_msecs; |
416 | unsigned long last_seen_jiffies; | 416 | unsigned long last_seen_jiffies; |
417 | uint32_t i; | 417 | uint32_t i; |
418 | int ret = 0; | ||
419 | 418 | ||
420 | primary_if = batadv_primary_if_get_selected(bat_priv); | 419 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
421 | 420 | if (!primary_if) | |
422 | if (!primary_if) { | ||
423 | ret = seq_printf(seq, | ||
424 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
425 | net_dev->name); | ||
426 | goto out; | ||
427 | } | ||
428 | |||
429 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | ||
430 | ret = seq_printf(seq, | ||
431 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
432 | net_dev->name); | ||
433 | goto out; | 421 | goto out; |
434 | } | ||
435 | 422 | ||
436 | seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", | 423 | seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", |
437 | BATADV_SOURCE_VERSION, primary_if->net_dev->name, | 424 | BATADV_SOURCE_VERSION, primary_if->net_dev->name, |
@@ -485,7 +472,7 @@ next: | |||
485 | out: | 472 | out: |
486 | if (primary_if) | 473 | if (primary_if) |
487 | batadv_hardif_free_ref(primary_if); | 474 | batadv_hardif_free_ref(primary_if); |
488 | return ret; | 475 | return 0; |
489 | } | 476 | } |
490 | 477 | ||
491 | static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, | 478 | static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 376b4cc6ca82..46dd5b47ed29 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -549,25 +549,18 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, | |||
549 | if (tmp_neigh_node->if_incoming == recv_if) | 549 | if (tmp_neigh_node->if_incoming == recv_if) |
550 | continue; | 550 | continue; |
551 | 551 | ||
552 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) | 552 | if (router && tmp_neigh_node->tq_avg <= router->tq_avg) |
553 | continue; | 553 | continue; |
554 | 554 | ||
555 | /* if we don't have a router yet | 555 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) |
556 | * or this one is better, choose it. | 556 | continue; |
557 | */ | ||
558 | if ((!router) || | ||
559 | (tmp_neigh_node->tq_avg > router->tq_avg)) { | ||
560 | /* decrement refcount of | ||
561 | * previously selected router | ||
562 | */ | ||
563 | if (router) | ||
564 | batadv_neigh_node_free_ref(router); | ||
565 | 557 | ||
566 | router = tmp_neigh_node; | 558 | /* decrement refcount of previously selected router */ |
567 | atomic_inc_not_zero(&router->refcount); | 559 | if (router) |
568 | } | 560 | batadv_neigh_node_free_ref(router); |
569 | 561 | ||
570 | batadv_neigh_node_free_ref(tmp_neigh_node); | 562 | /* we found a better router (or at least one valid router) */ |
563 | router = tmp_neigh_node; | ||
571 | } | 564 | } |
572 | 565 | ||
573 | /* use the first candidate if nothing was found. */ | 566 | /* use the first candidate if nothing was found. */ |
@@ -687,21 +680,8 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) | |||
687 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 680 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
688 | struct batadv_roam_adv_packet *roam_adv_packet; | 681 | struct batadv_roam_adv_packet *roam_adv_packet; |
689 | struct batadv_orig_node *orig_node; | 682 | struct batadv_orig_node *orig_node; |
690 | struct ethhdr *ethhdr; | ||
691 | 683 | ||
692 | /* drop packet if it has not necessary minimum size */ | 684 | if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0) |
693 | if (unlikely(!pskb_may_pull(skb, | ||
694 | sizeof(struct batadv_roam_adv_packet)))) | ||
695 | goto out; | ||
696 | |||
697 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | ||
698 | |||
699 | /* packet with unicast indication but broadcast recipient */ | ||
700 | if (is_broadcast_ether_addr(ethhdr->h_dest)) | ||
701 | goto out; | ||
702 | |||
703 | /* packet with broadcast sender address */ | ||
704 | if (is_broadcast_ether_addr(ethhdr->h_source)) | ||
705 | goto out; | 685 | goto out; |
706 | 686 | ||
707 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); | 687 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); |
@@ -928,8 +908,12 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
928 | bool tt_poss_change; | 908 | bool tt_poss_change; |
929 | int is_old_ttvn; | 909 | int is_old_ttvn; |
930 | 910 | ||
931 | /* I could need to modify it */ | 911 | /* check if there is enough data before accessing it */ |
932 | if (skb_cow(skb, sizeof(struct batadv_unicast_packet)) < 0) | 912 | if (pskb_may_pull(skb, sizeof(*unicast_packet) + ETH_HLEN) < 0) |
913 | return 0; | ||
914 | |||
915 | /* create a copy of the skb (in case of for re-routing) to modify it. */ | ||
916 | if (skb_cow(skb, sizeof(*unicast_packet)) < 0) | ||
933 | return 0; | 917 | return 0; |
934 | 918 | ||
935 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 919 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
@@ -985,10 +969,10 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
985 | batadv_orig_node_free_ref(orig_node); | 969 | batadv_orig_node_free_ref(orig_node); |
986 | } | 970 | } |
987 | 971 | ||
988 | batadv_dbg(BATADV_DBG_ROUTES, bat_priv, | 972 | net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv, |
989 | "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", | 973 | "TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n", |
990 | unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest, | 974 | unicast_packet->ttvn, curr_ttvn, |
991 | unicast_packet->dest); | 975 | ethhdr->h_dest, unicast_packet->dest); |
992 | 976 | ||
993 | unicast_packet->ttvn = curr_ttvn; | 977 | unicast_packet->ttvn = curr_ttvn; |
994 | } | 978 | } |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2dd3e8..22bc65102370 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -146,8 +146,10 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
146 | struct batadv_bcast_packet *bcast_packet; | 146 | struct batadv_bcast_packet *bcast_packet; |
147 | struct vlan_ethhdr *vhdr; | 147 | struct vlan_ethhdr *vhdr; |
148 | __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); | 148 | __be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN); |
149 | static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, | 149 | static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, |
150 | 0x00}; | 150 | 0x00, 0x00}; |
151 | static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, | ||
152 | 0x00, 0x00}; | ||
151 | unsigned int header_len = 0; | 153 | unsigned int header_len = 0; |
152 | int data_len = skb->len, ret; | 154 | int data_len = skb->len, ret; |
153 | short vid __maybe_unused = -1; | 155 | short vid __maybe_unused = -1; |
@@ -180,10 +182,16 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
180 | 182 | ||
181 | /* don't accept stp packets. STP does not help in meshes. | 183 | /* don't accept stp packets. STP does not help in meshes. |
182 | * better use the bridge loop avoidance ... | 184 | * better use the bridge loop avoidance ... |
185 | * | ||
186 | * The same goes for ECTP sent at least by some Cisco Switches, | ||
187 | * it might confuse the mesh when used with bridge loop avoidance. | ||
183 | */ | 188 | */ |
184 | if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) | 189 | if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) |
185 | goto dropped; | 190 | goto dropped; |
186 | 191 | ||
192 | if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) | ||
193 | goto dropped; | ||
194 | |||
187 | if (is_multicast_ether_addr(ethhdr->h_dest)) { | 195 | if (is_multicast_ether_addr(ethhdr->h_dest)) { |
188 | do_bcast = true; | 196 | do_bcast = true; |
189 | 197 | ||
@@ -347,7 +355,51 @@ out: | |||
347 | return; | 355 | return; |
348 | } | 356 | } |
349 | 357 | ||
358 | /* batman-adv network devices have devices nesting below it and are a special | ||
359 | * "super class" of normal network devices; split their locks off into a | ||
360 | * separate class since they always nest. | ||
361 | */ | ||
362 | static struct lock_class_key batadv_netdev_xmit_lock_key; | ||
363 | static struct lock_class_key batadv_netdev_addr_lock_key; | ||
364 | |||
365 | /** | ||
366 | * batadv_set_lockdep_class_one - Set lockdep class for a single tx queue | ||
367 | * @dev: device which owns the tx queue | ||
368 | * @txq: tx queue to modify | ||
369 | * @_unused: always NULL | ||
370 | */ | ||
371 | static void batadv_set_lockdep_class_one(struct net_device *dev, | ||
372 | struct netdev_queue *txq, | ||
373 | void *_unused) | ||
374 | { | ||
375 | lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * batadv_set_lockdep_class - Set txq and addr_list lockdep class | ||
380 | * @dev: network device to modify | ||
381 | */ | ||
382 | static void batadv_set_lockdep_class(struct net_device *dev) | ||
383 | { | ||
384 | lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); | ||
385 | netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * batadv_softif_init - Late stage initialization of soft interface | ||
390 | * @dev: registered network device to modify | ||
391 | * | ||
392 | * Returns error code on failures | ||
393 | */ | ||
394 | static int batadv_softif_init(struct net_device *dev) | ||
395 | { | ||
396 | batadv_set_lockdep_class(dev); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
350 | static const struct net_device_ops batadv_netdev_ops = { | 401 | static const struct net_device_ops batadv_netdev_ops = { |
402 | .ndo_init = batadv_softif_init, | ||
351 | .ndo_open = batadv_interface_open, | 403 | .ndo_open = batadv_interface_open, |
352 | .ndo_stop = batadv_interface_release, | 404 | .ndo_stop = batadv_interface_release, |
353 | .ndo_get_stats = batadv_interface_stats, | 405 | .ndo_get_stats = batadv_interface_stats, |
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 66518c75c217..42cd09e24c5f 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c | |||
@@ -122,55 +122,6 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ | |||
122 | batadv_store_##_name) | 122 | batadv_store_##_name) |
123 | 123 | ||
124 | 124 | ||
125 | #define BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \ | ||
126 | ssize_t batadv_store_##_name(struct kobject *kobj, \ | ||
127 | struct attribute *attr, char *buff, \ | ||
128 | size_t count) \ | ||
129 | { \ | ||
130 | struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ | ||
131 | struct batadv_hard_iface *hard_iface; \ | ||
132 | ssize_t length; \ | ||
133 | \ | ||
134 | hard_iface = batadv_hardif_get_by_netdev(net_dev); \ | ||
135 | if (!hard_iface) \ | ||
136 | return 0; \ | ||
137 | \ | ||
138 | length = __batadv_store_uint_attr(buff, count, _min, _max, \ | ||
139 | _post_func, attr, \ | ||
140 | &hard_iface->_name, net_dev); \ | ||
141 | \ | ||
142 | batadv_hardif_free_ref(hard_iface); \ | ||
143 | return length; \ | ||
144 | } | ||
145 | |||
146 | #define BATADV_ATTR_HIF_SHOW_UINT(_name) \ | ||
147 | ssize_t batadv_show_##_name(struct kobject *kobj, \ | ||
148 | struct attribute *attr, char *buff) \ | ||
149 | { \ | ||
150 | struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ | ||
151 | struct batadv_hard_iface *hard_iface; \ | ||
152 | ssize_t length; \ | ||
153 | \ | ||
154 | hard_iface = batadv_hardif_get_by_netdev(net_dev); \ | ||
155 | if (!hard_iface) \ | ||
156 | return 0; \ | ||
157 | \ | ||
158 | length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\ | ||
159 | \ | ||
160 | batadv_hardif_free_ref(hard_iface); \ | ||
161 | return length; \ | ||
162 | } | ||
163 | |||
164 | /* Use this, if you are going to set [name] in hard_iface to an | ||
165 | * unsigned integer value | ||
166 | */ | ||
167 | #define BATADV_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \ | ||
168 | static BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func)\ | ||
169 | static BATADV_ATTR_HIF_SHOW_UINT(_name) \ | ||
170 | static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ | ||
171 | batadv_store_##_name) | ||
172 | |||
173 | |||
174 | static int batadv_store_bool_attr(char *buff, size_t count, | 125 | static int batadv_store_bool_attr(char *buff, size_t count, |
175 | struct net_device *net_dev, | 126 | struct net_device *net_dev, |
176 | const char *attr_name, atomic_t *attr) | 127 | const char *attr_name, atomic_t *attr) |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 112edd371b2f..a570d957a5a0 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -434,22 +434,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
434 | struct hlist_node *node; | 434 | struct hlist_node *node; |
435 | struct hlist_head *head; | 435 | struct hlist_head *head; |
436 | uint32_t i; | 436 | uint32_t i; |
437 | int ret = 0; | ||
438 | |||
439 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
440 | if (!primary_if) { | ||
441 | ret = seq_printf(seq, | ||
442 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
443 | net_dev->name); | ||
444 | goto out; | ||
445 | } | ||
446 | 437 | ||
447 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | 438 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
448 | ret = seq_printf(seq, | 439 | if (!primary_if) |
449 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
450 | net_dev->name); | ||
451 | goto out; | 440 | goto out; |
452 | } | ||
453 | 441 | ||
454 | seq_printf(seq, | 442 | seq_printf(seq, |
455 | "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", | 443 | "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", |
@@ -479,7 +467,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) | |||
479 | out: | 467 | out: |
480 | if (primary_if) | 468 | if (primary_if) |
481 | batadv_hardif_free_ref(primary_if); | 469 | batadv_hardif_free_ref(primary_if); |
482 | return ret; | 470 | return 0; |
483 | } | 471 | } |
484 | 472 | ||
485 | static void | 473 | static void |
@@ -501,24 +489,39 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv, | |||
501 | tt_local_entry->common.addr, message); | 489 | tt_local_entry->common.addr, message); |
502 | } | 490 | } |
503 | 491 | ||
504 | void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr, | 492 | /** |
505 | const char *message, bool roaming) | 493 | * batadv_tt_local_remove - logically remove an entry from the local table |
494 | * @bat_priv: the bat priv with all the soft interface information | ||
495 | * @addr: the MAC address of the client to remove | ||
496 | * @message: message to append to the log on deletion | ||
497 | * @roaming: true if the deletion is due to a roaming event | ||
498 | * | ||
499 | * Returns the flags assigned to the local entry before being deleted | ||
500 | */ | ||
501 | uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, | ||
502 | const uint8_t *addr, const char *message, | ||
503 | bool roaming) | ||
506 | { | 504 | { |
507 | struct batadv_tt_local_entry *tt_local_entry = NULL; | 505 | struct batadv_tt_local_entry *tt_local_entry = NULL; |
508 | uint16_t flags; | 506 | uint16_t flags, curr_flags = BATADV_NO_FLAGS; |
509 | 507 | ||
510 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); | 508 | tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr); |
511 | if (!tt_local_entry) | 509 | if (!tt_local_entry) |
512 | goto out; | 510 | goto out; |
513 | 511 | ||
512 | curr_flags = tt_local_entry->common.flags; | ||
513 | |||
514 | flags = BATADV_TT_CLIENT_DEL; | 514 | flags = BATADV_TT_CLIENT_DEL; |
515 | if (roaming) | 515 | if (roaming) |
516 | flags |= BATADV_TT_CLIENT_ROAM; | 516 | flags |= BATADV_TT_CLIENT_ROAM; |
517 | 517 | ||
518 | batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message); | 518 | batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message); |
519 | |||
519 | out: | 520 | out: |
520 | if (tt_local_entry) | 521 | if (tt_local_entry) |
521 | batadv_tt_local_entry_free_ref(tt_local_entry); | 522 | batadv_tt_local_entry_free_ref(tt_local_entry); |
523 | |||
524 | return curr_flags; | ||
522 | } | 525 | } |
523 | 526 | ||
524 | static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, | 527 | static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, |
@@ -725,6 +728,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
725 | int ret = 0; | 728 | int ret = 0; |
726 | int hash_added; | 729 | int hash_added; |
727 | struct batadv_tt_common_entry *common; | 730 | struct batadv_tt_common_entry *common; |
731 | uint16_t local_flags; | ||
728 | 732 | ||
729 | tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); | 733 | tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr); |
730 | 734 | ||
@@ -738,6 +742,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
738 | 742 | ||
739 | common->flags = flags; | 743 | common->flags = flags; |
740 | tt_global_entry->roam_at = 0; | 744 | tt_global_entry->roam_at = 0; |
745 | /* node must store current time in case of roaming. This is | ||
746 | * needed to purge this entry out on timeout (if nobody claims | ||
747 | * it) | ||
748 | */ | ||
749 | if (flags & BATADV_TT_CLIENT_ROAM) | ||
750 | tt_global_entry->roam_at = jiffies; | ||
741 | atomic_set(&common->refcount, 2); | 751 | atomic_set(&common->refcount, 2); |
742 | common->added_at = jiffies; | 752 | common->added_at = jiffies; |
743 | 753 | ||
@@ -788,13 +798,16 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, | |||
788 | batadv_dbg(BATADV_DBG_TT, bat_priv, | 798 | batadv_dbg(BATADV_DBG_TT, bat_priv, |
789 | "Creating new global tt entry: %pM (via %pM)\n", | 799 | "Creating new global tt entry: %pM (via %pM)\n", |
790 | tt_global_entry->common.addr, orig_node->orig); | 800 | tt_global_entry->common.addr, orig_node->orig); |
801 | ret = 1; | ||
791 | 802 | ||
792 | out_remove: | 803 | out_remove: |
804 | |||
793 | /* remove address from local hash if present */ | 805 | /* remove address from local hash if present */ |
794 | batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr, | 806 | local_flags = batadv_tt_local_remove(bat_priv, tt_addr, |
795 | "global tt received", | 807 | "global tt received", |
796 | flags & BATADV_TT_CLIENT_ROAM); | 808 | flags & BATADV_TT_CLIENT_ROAM); |
797 | ret = 1; | 809 | tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI; |
810 | |||
798 | out: | 811 | out: |
799 | if (tt_global_entry) | 812 | if (tt_global_entry) |
800 | batadv_tt_global_entry_free_ref(tt_global_entry); | 813 | batadv_tt_global_entry_free_ref(tt_global_entry); |
@@ -842,22 +855,10 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
842 | struct hlist_node *node; | 855 | struct hlist_node *node; |
843 | struct hlist_head *head; | 856 | struct hlist_head *head; |
844 | uint32_t i; | 857 | uint32_t i; |
845 | int ret = 0; | ||
846 | |||
847 | primary_if = batadv_primary_if_get_selected(bat_priv); | ||
848 | if (!primary_if) { | ||
849 | ret = seq_printf(seq, | ||
850 | "BATMAN mesh %s disabled - please specify interfaces to enable it\n", | ||
851 | net_dev->name); | ||
852 | goto out; | ||
853 | } | ||
854 | 858 | ||
855 | if (primary_if->if_status != BATADV_IF_ACTIVE) { | 859 | primary_if = batadv_seq_print_text_primary_if_get(seq); |
856 | ret = seq_printf(seq, | 860 | if (!primary_if) |
857 | "BATMAN mesh %s disabled - primary interface not active\n", | ||
858 | net_dev->name); | ||
859 | goto out; | 861 | goto out; |
860 | } | ||
861 | 862 | ||
862 | seq_printf(seq, | 863 | seq_printf(seq, |
863 | "Globally announced TT entries received via the mesh %s\n", | 864 | "Globally announced TT entries received via the mesh %s\n", |
@@ -881,7 +882,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) | |||
881 | out: | 882 | out: |
882 | if (primary_if) | 883 | if (primary_if) |
883 | batadv_hardif_free_ref(primary_if); | 884 | batadv_hardif_free_ref(primary_if); |
884 | return ret; | 885 | return 0; |
885 | } | 886 | } |
886 | 887 | ||
887 | /* deletes the orig list of a tt_global_entry */ | 888 | /* deletes the orig list of a tt_global_entry */ |
@@ -2438,7 +2439,7 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, | |||
2438 | if (!tt_global_entry) | 2439 | if (!tt_global_entry) |
2439 | goto out; | 2440 | goto out; |
2440 | 2441 | ||
2441 | ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM; | 2442 | ret = !!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM); |
2442 | batadv_tt_global_entry_free_ref(tt_global_entry); | 2443 | batadv_tt_global_entry_free_ref(tt_global_entry); |
2443 | out: | 2444 | out: |
2444 | return ret; | 2445 | return ret; |
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index 811fffd4760c..9fa4fe41c868 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h | |||
@@ -24,9 +24,9 @@ int batadv_tt_len(int changes_num); | |||
24 | int batadv_tt_init(struct batadv_priv *bat_priv); | 24 | int batadv_tt_init(struct batadv_priv *bat_priv); |
25 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, | 25 | void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, |
26 | int ifindex); | 26 | int ifindex); |
27 | void batadv_tt_local_remove(struct batadv_priv *bat_priv, | 27 | uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, |
28 | const uint8_t *addr, const char *message, | 28 | const uint8_t *addr, const char *message, |
29 | bool roaming); | 29 | bool roaming); |
30 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); | 30 | int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset); |
31 | void batadv_tt_global_add_orig(struct batadv_priv *bat_priv, | 31 | void batadv_tt_global_add_orig(struct batadv_priv *bat_priv, |
32 | struct batadv_orig_node *orig_node, | 32 | struct batadv_orig_node *orig_node, |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index ac1e07a80454..faaebd6c8140 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -28,20 +28,30 @@ | |||
28 | (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \ | 28 | (ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \ |
29 | sizeof(struct batadv_bcast_packet))) | 29 | sizeof(struct batadv_bcast_packet))) |
30 | 30 | ||
31 | /** | ||
32 | * struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data | ||
33 | * @ogm_buff: buffer holding the OGM packet | ||
34 | * @ogm_buff_len: length of the OGM packet buffer | ||
35 | * @ogm_seqno: OGM sequence number - used to identify each OGM | ||
36 | */ | ||
37 | struct batadv_hard_iface_bat_iv { | ||
38 | unsigned char *ogm_buff; | ||
39 | int ogm_buff_len; | ||
40 | atomic_t ogm_seqno; | ||
41 | }; | ||
42 | |||
31 | struct batadv_hard_iface { | 43 | struct batadv_hard_iface { |
32 | struct list_head list; | 44 | struct list_head list; |
33 | int16_t if_num; | 45 | int16_t if_num; |
34 | char if_status; | 46 | char if_status; |
35 | struct net_device *net_dev; | 47 | struct net_device *net_dev; |
36 | atomic_t seqno; | ||
37 | atomic_t frag_seqno; | 48 | atomic_t frag_seqno; |
38 | unsigned char *packet_buff; | ||
39 | int packet_len; | ||
40 | struct kobject *hardif_obj; | 49 | struct kobject *hardif_obj; |
41 | atomic_t refcount; | 50 | atomic_t refcount; |
42 | struct packet_type batman_adv_ptype; | 51 | struct packet_type batman_adv_ptype; |
43 | struct net_device *soft_iface; | 52 | struct net_device *soft_iface; |
44 | struct rcu_head rcu; | 53 | struct rcu_head rcu; |
54 | struct batadv_hard_iface_bat_iv bat_iv; | ||
45 | }; | 55 | }; |
46 | 56 | ||
47 | /** | 57 | /** |