aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-10-23 17:12:33 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-23 17:12:33 -0400
commitb45bd46decd947eaa3497699d450e0851d247534 (patch)
treedd7416329e0be51c2ae559c74e866b76116c75bc /net
parent0cad43a7484179ec349e8e5792c558ee787a06ba (diff)
parentda6b8c20a5b8c7edce95c95fa2356300691094f5 (diff)
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Antonio Quartulli says: ==================== this is another set of changes intended for net-next/linux-3.13. (probably our last pull request for this cycle) Patches 1 and 2 reshape two of our main data structures in a way that they can easily be extended in the future to accommodate new routing protocols. Patches from 3 to 9 improve our routing protocol API and its users so that all the protocol-related code is not mixed up with the other components anymore. Patch 10 limits the local Translation Table maximum size to a value such that it can be fully transfered over the air if needed. This value depends on fragmentation being enabled or not and on the mtu values. Patch 11 makes batman-adv send a uevent in case of soft-interface destruction while a "bat-Gateway" was configured (this informs userspace about the GW not being available anymore). Patches 13 and 14 enable the TT component to detect non-mesh client flag changes at runtime (till now those flags where set upon client detection and were not changed anymore). Patch 16 is a generalisation of our user-to-kernel space communication (and viceversa) used to exchange ICMP packets to send/received to/from the mesh network. Now it can easily accommodate new ICMP packet types without breaking the existing userspace API anymore. Remaining patches are minor changes and cleanups. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/bat_iv_ogm.c399
-rw-r--r--net/batman-adv/gateway_client.c16
-rw-r--r--net/batman-adv/hard-interface.c83
-rw-r--r--net/batman-adv/hard-interface.h2
-rw-r--r--net/batman-adv/icmp_socket.c128
-rw-r--r--net/batman-adv/icmp_socket.h2
-rw-r--r--net/batman-adv/main.c4
-rw-r--r--net/batman-adv/main.h8
-rw-r--r--net/batman-adv/network-coding.c8
-rw-r--r--net/batman-adv/originator.c249
-rw-r--r--net/batman-adv/originator.h6
-rw-r--r--net/batman-adv/packet.h7
-rw-r--r--net/batman-adv/routing.c159
-rw-r--r--net/batman-adv/routing.h3
-rw-r--r--net/batman-adv/soft-interface.c12
-rw-r--r--net/batman-adv/translation-table.c235
-rw-r--r--net/batman-adv/translation-table.h3
-rw-r--r--net/batman-adv/types.h109
18 files changed, 956 insertions, 477 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 97b42d3c4bef..a2b480a90872 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -87,22 +87,198 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
87 return (uint8_t)(sum / count); 87 return (uint8_t)(sum / count);
88} 88}
89 89
90/**
91 * batadv_iv_ogm_orig_free - free the private resources allocated for this
92 * orig_node
93 * @orig_node: the orig_node for which the resources have to be free'd
94 */
95static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node)
96{
97 kfree(orig_node->bat_iv.bcast_own);
98 kfree(orig_node->bat_iv.bcast_own_sum);
99}
100
101/**
102 * batadv_iv_ogm_orig_add_if - change the private structures of the orig_node to
103 * include the new hard-interface
104 * @orig_node: the orig_node that has to be changed
105 * @max_if_num: the current amount of interfaces
106 *
107 * Returns 0 on success, a negative error code otherwise.
108 */
109static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
110 int max_if_num)
111{
112 void *data_ptr;
113 size_t data_size, old_size;
114 int ret = -ENOMEM;
115
116 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
117
118 data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS;
119 old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS;
120 data_ptr = kmalloc(data_size, GFP_ATOMIC);
121 if (!data_ptr)
122 goto unlock;
123
124 memcpy(data_ptr, orig_node->bat_iv.bcast_own, old_size);
125 kfree(orig_node->bat_iv.bcast_own);
126 orig_node->bat_iv.bcast_own = data_ptr;
127
128 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
129 if (!data_ptr) {
130 kfree(orig_node->bat_iv.bcast_own);
131 goto unlock;
132 }
133
134 memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
135 (max_if_num - 1) * sizeof(uint8_t));
136 kfree(orig_node->bat_iv.bcast_own_sum);
137 orig_node->bat_iv.bcast_own_sum = data_ptr;
138
139 ret = 0;
140
141unlock:
142 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
143
144 return ret;
145}
146
147/**
148 * batadv_iv_ogm_orig_del_if - change the private structures of the orig_node to
149 * exclude the removed interface
150 * @orig_node: the orig_node that has to be changed
151 * @max_if_num: the current amount of interfaces
152 * @del_if_num: the index of the interface being removed
153 *
154 * Returns 0 on success, a negative error code otherwise.
155 */
156static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
157 int max_if_num, int del_if_num)
158{
159 int chunk_size, ret = -ENOMEM, if_offset;
160 void *data_ptr = NULL;
161
162 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
163
164 /* last interface was removed */
165 if (max_if_num == 0)
166 goto free_bcast_own;
167
168 chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS;
169 data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
170 if (!data_ptr)
171 goto unlock;
172
173 /* copy first part */
174 memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size);
175
176 /* copy second part */
177 memcpy((char *)data_ptr + del_if_num * chunk_size,
178 orig_node->bat_iv.bcast_own + ((del_if_num + 1) * chunk_size),
179 (max_if_num - del_if_num) * chunk_size);
180
181free_bcast_own:
182 kfree(orig_node->bat_iv.bcast_own);
183 orig_node->bat_iv.bcast_own = data_ptr;
184
185 if (max_if_num == 0)
186 goto free_own_sum;
187
188 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
189 if (!data_ptr) {
190 kfree(orig_node->bat_iv.bcast_own);
191 goto unlock;
192 }
193
194 memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
195 del_if_num * sizeof(uint8_t));
196
197 if_offset = (del_if_num + 1) * sizeof(uint8_t);
198 memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t),
199 orig_node->bat_iv.bcast_own_sum + if_offset,
200 (max_if_num - del_if_num) * sizeof(uint8_t));
201
202free_own_sum:
203 kfree(orig_node->bat_iv.bcast_own_sum);
204 orig_node->bat_iv.bcast_own_sum = data_ptr;
205
206 ret = 0;
207unlock:
208 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
209
210 return ret;
211}
212
213/**
214 * batadv_iv_ogm_orig_get - retrieve or create (if does not exist) an originator
215 * @bat_priv: the bat priv with all the soft interface information
216 * @addr: mac address of the originator
217 *
218 * Returns the originator object corresponding to the passed mac address or NULL
219 * on failure.
220 * If the object does not exists it is created an initialised.
221 */
222static struct batadv_orig_node *
223batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr)
224{
225 struct batadv_orig_node *orig_node;
226 int size, hash_added;
227
228 orig_node = batadv_orig_hash_find(bat_priv, addr);
229 if (orig_node)
230 return orig_node;
231
232 orig_node = batadv_orig_node_new(bat_priv, addr);
233 if (!orig_node)
234 return NULL;
235
236 spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);
237
238 size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS;
239 orig_node->bat_iv.bcast_own = kzalloc(size, GFP_ATOMIC);
240 if (!orig_node->bat_iv.bcast_own)
241 goto free_orig_node;
242
243 size = bat_priv->num_ifaces * sizeof(uint8_t);
244 orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC);
245 if (!orig_node->bat_iv.bcast_own_sum)
246 goto free_bcast_own;
247
248 hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
249 batadv_choose_orig, orig_node,
250 &orig_node->hash_entry);
251 if (hash_added != 0)
252 goto free_bcast_own;
253
254 return orig_node;
255
256free_bcast_own:
257 kfree(orig_node->bat_iv.bcast_own);
258free_orig_node:
259 batadv_orig_node_free_ref(orig_node);
260
261 return NULL;
262}
263
90static struct batadv_neigh_node * 264static struct batadv_neigh_node *
91batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, 265batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
92 const uint8_t *neigh_addr, 266 const uint8_t *neigh_addr,
93 struct batadv_orig_node *orig_node, 267 struct batadv_orig_node *orig_node,
94 struct batadv_orig_node *orig_neigh) 268 struct batadv_orig_node *orig_neigh)
95{ 269{
270 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
96 struct batadv_neigh_node *neigh_node; 271 struct batadv_neigh_node *neigh_node;
97 272
98 neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr); 273 neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node);
99 if (!neigh_node) 274 if (!neigh_node)
100 goto out; 275 goto out;
101 276
102 INIT_LIST_HEAD(&neigh_node->bonding_list); 277 spin_lock_init(&neigh_node->bat_iv.lq_update_lock);
103 278
104 neigh_node->orig_node = orig_neigh; 279 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
105 neigh_node->if_incoming = hard_iface; 280 "Creating new neighbor %pM for orig_node %pM on interface %s\n",
281 neigh_addr, orig_node->orig, hard_iface->net_dev->name);
106 282
107 spin_lock_bh(&orig_node->neigh_list_lock); 283 spin_lock_bh(&orig_node->neigh_list_lock);
108 hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); 284 hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
@@ -661,20 +837,22 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
661 uint32_t i; 837 uint32_t i;
662 size_t word_index; 838 size_t word_index;
663 uint8_t *w; 839 uint8_t *w;
840 int if_num;
664 841
665 for (i = 0; i < hash->size; i++) { 842 for (i = 0; i < hash->size; i++) {
666 head = &hash->table[i]; 843 head = &hash->table[i];
667 844
668 rcu_read_lock(); 845 rcu_read_lock();
669 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 846 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
670 spin_lock_bh(&orig_node->ogm_cnt_lock); 847 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
671 word_index = hard_iface->if_num * BATADV_NUM_WORDS; 848 word_index = hard_iface->if_num * BATADV_NUM_WORDS;
672 word = &(orig_node->bcast_own[word_index]); 849 word = &(orig_node->bat_iv.bcast_own[word_index]);
673 850
674 batadv_bit_get_packet(bat_priv, word, 1, 0); 851 batadv_bit_get_packet(bat_priv, word, 1, 0);
675 w = &orig_node->bcast_own_sum[hard_iface->if_num]; 852 if_num = hard_iface->if_num;
853 w = &orig_node->bat_iv.bcast_own_sum[if_num];
676 *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE); 854 *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
677 spin_unlock_bh(&orig_node->ogm_cnt_lock); 855 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
678 } 856 }
679 rcu_read_unlock(); 857 rcu_read_unlock();
680 } 858 }
@@ -755,18 +933,18 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
755 if (dup_status != BATADV_NO_DUP) 933 if (dup_status != BATADV_NO_DUP)
756 continue; 934 continue;
757 935
758 spin_lock_bh(&tmp_neigh_node->lq_update_lock); 936 spin_lock_bh(&tmp_neigh_node->bat_iv.lq_update_lock);
759 batadv_ring_buffer_set(tmp_neigh_node->tq_recv, 937 batadv_ring_buffer_set(tmp_neigh_node->bat_iv.tq_recv,
760 &tmp_neigh_node->tq_index, 0); 938 &tmp_neigh_node->bat_iv.tq_index, 0);
761 tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); 939 tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->bat_iv.tq_recv);
762 tmp_neigh_node->tq_avg = tq_avg; 940 tmp_neigh_node->bat_iv.tq_avg = tq_avg;
763 spin_unlock_bh(&tmp_neigh_node->lq_update_lock); 941 spin_unlock_bh(&tmp_neigh_node->bat_iv.lq_update_lock);
764 } 942 }
765 943
766 if (!neigh_node) { 944 if (!neigh_node) {
767 struct batadv_orig_node *orig_tmp; 945 struct batadv_orig_node *orig_tmp;
768 946
769 orig_tmp = batadv_get_orig_node(bat_priv, ethhdr->h_source); 947 orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source);
770 if (!orig_tmp) 948 if (!orig_tmp)
771 goto unlock; 949 goto unlock;
772 950
@@ -785,19 +963,20 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
785 963
786 neigh_node->last_seen = jiffies; 964 neigh_node->last_seen = jiffies;
787 965
788 spin_lock_bh(&neigh_node->lq_update_lock); 966 spin_lock_bh(&neigh_node->bat_iv.lq_update_lock);
789 batadv_ring_buffer_set(neigh_node->tq_recv, 967 batadv_ring_buffer_set(neigh_node->bat_iv.tq_recv,
790 &neigh_node->tq_index, 968 &neigh_node->bat_iv.tq_index,
791 batadv_ogm_packet->tq); 969 batadv_ogm_packet->tq);
792 neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); 970 tq_avg = batadv_ring_buffer_avg(neigh_node->bat_iv.tq_recv);
793 spin_unlock_bh(&neigh_node->lq_update_lock); 971 neigh_node->bat_iv.tq_avg = tq_avg;
972 spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock);
794 973
795 if (dup_status == BATADV_NO_DUP) { 974 if (dup_status == BATADV_NO_DUP) {
796 orig_node->last_ttl = batadv_ogm_packet->header.ttl; 975 orig_node->last_ttl = batadv_ogm_packet->header.ttl;
797 neigh_node->last_ttl = batadv_ogm_packet->header.ttl; 976 neigh_node->last_ttl = batadv_ogm_packet->header.ttl;
798 } 977 }
799 978
800 batadv_bonding_candidate_add(orig_node, neigh_node); 979 batadv_bonding_candidate_add(bat_priv, orig_node, neigh_node);
801 980
802 /* if this neighbor already is our next hop there is nothing 981 /* if this neighbor already is our next hop there is nothing
803 * to change 982 * to change
@@ -807,24 +986,24 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
807 goto out; 986 goto out;
808 987
809 /* if this neighbor does not offer a better TQ we won't consider it */ 988 /* if this neighbor does not offer a better TQ we won't consider it */
810 if (router && (router->tq_avg > neigh_node->tq_avg)) 989 if (router && (router->bat_iv.tq_avg > neigh_node->bat_iv.tq_avg))
811 goto out; 990 goto out;
812 991
813 /* if the TQ is the same and the link not more symmetric we 992 /* if the TQ is the same and the link not more symmetric we
814 * won't consider it either 993 * won't consider it either
815 */ 994 */
816 if (router && (neigh_node->tq_avg == router->tq_avg)) { 995 if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) {
817 orig_node_tmp = router->orig_node; 996 orig_node_tmp = router->orig_node;
818 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 997 spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
819 if_num = router->if_incoming->if_num; 998 if_num = router->if_incoming->if_num;
820 sum_orig = orig_node_tmp->bcast_own_sum[if_num]; 999 sum_orig = orig_node_tmp->bat_iv.bcast_own_sum[if_num];
821 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 1000 spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
822 1001
823 orig_node_tmp = neigh_node->orig_node; 1002 orig_node_tmp = neigh_node->orig_node;
824 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); 1003 spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
825 if_num = neigh_node->if_incoming->if_num; 1004 if_num = neigh_node->if_incoming->if_num;
826 sum_neigh = orig_node_tmp->bcast_own_sum[if_num]; 1005 sum_neigh = orig_node_tmp->bat_iv.bcast_own_sum[if_num];
827 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); 1006 spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
828 1007
829 if (sum_orig >= sum_neigh) 1008 if (sum_orig >= sum_neigh)
830 goto out; 1009 goto out;
@@ -852,7 +1031,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
852 uint8_t total_count; 1031 uint8_t total_count;
853 uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; 1032 uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
854 unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; 1033 unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
855 int tq_asym_penalty, inv_asym_penalty, ret = 0; 1034 int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0;
856 unsigned int combined_tq; 1035 unsigned int combined_tq;
857 1036
858 /* find corresponding one hop neighbor */ 1037 /* find corresponding one hop neighbor */
@@ -890,10 +1069,11 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
890 orig_node->last_seen = jiffies; 1069 orig_node->last_seen = jiffies;
891 1070
892 /* find packet count of corresponding one hop neighbor */ 1071 /* find packet count of corresponding one hop neighbor */
893 spin_lock_bh(&orig_node->ogm_cnt_lock); 1072 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
894 orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; 1073 if_num = if_incoming->if_num;
895 neigh_rq_count = neigh_node->real_packet_count; 1074 orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];
896 spin_unlock_bh(&orig_node->ogm_cnt_lock); 1075 neigh_rq_count = neigh_node->bat_iv.real_packet_count;
1076 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
897 1077
898 /* pay attention to not get a value bigger than 100 % */ 1078 /* pay attention to not get a value bigger than 100 % */
899 if (orig_eq_count > neigh_rq_count) 1079 if (orig_eq_count > neigh_rq_count)
@@ -975,12 +1155,13 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
975 uint32_t seqno = ntohl(batadv_ogm_packet->seqno); 1155 uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
976 uint8_t *neigh_addr; 1156 uint8_t *neigh_addr;
977 uint8_t packet_count; 1157 uint8_t packet_count;
1158 unsigned long *bitmap;
978 1159
979 orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); 1160 orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
980 if (!orig_node) 1161 if (!orig_node)
981 return BATADV_NO_DUP; 1162 return BATADV_NO_DUP;
982 1163
983 spin_lock_bh(&orig_node->ogm_cnt_lock); 1164 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
984 seq_diff = seqno - orig_node->last_real_seqno; 1165 seq_diff = seqno - orig_node->last_real_seqno;
985 1166
986 /* signalize caller that the packet is to be dropped. */ 1167 /* signalize caller that the packet is to be dropped. */
@@ -995,7 +1176,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
995 hlist_for_each_entry_rcu(tmp_neigh_node, 1176 hlist_for_each_entry_rcu(tmp_neigh_node,
996 &orig_node->neigh_list, list) { 1177 &orig_node->neigh_list, list) {
997 neigh_addr = tmp_neigh_node->addr; 1178 neigh_addr = tmp_neigh_node->addr;
998 is_dup = batadv_test_bit(tmp_neigh_node->real_bits, 1179 is_dup = batadv_test_bit(tmp_neigh_node->bat_iv.real_bits,
999 orig_node->last_real_seqno, 1180 orig_node->last_real_seqno,
1000 seqno); 1181 seqno);
1001 1182
@@ -1011,13 +1192,13 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1011 } 1192 }
1012 1193
1013 /* if the window moved, set the update flag. */ 1194 /* if the window moved, set the update flag. */
1014 need_update |= batadv_bit_get_packet(bat_priv, 1195 bitmap = tmp_neigh_node->bat_iv.real_bits;
1015 tmp_neigh_node->real_bits, 1196 need_update |= batadv_bit_get_packet(bat_priv, bitmap,
1016 seq_diff, set_mark); 1197 seq_diff, set_mark);
1017 1198
1018 packet_count = bitmap_weight(tmp_neigh_node->real_bits, 1199 packet_count = bitmap_weight(tmp_neigh_node->bat_iv.real_bits,
1019 BATADV_TQ_LOCAL_WINDOW_SIZE); 1200 BATADV_TQ_LOCAL_WINDOW_SIZE);
1020 tmp_neigh_node->real_packet_count = packet_count; 1201 tmp_neigh_node->bat_iv.real_packet_count = packet_count;
1021 } 1202 }
1022 rcu_read_unlock(); 1203 rcu_read_unlock();
1023 1204
@@ -1029,7 +1210,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
1029 } 1210 }
1030 1211
1031out: 1212out:
1032 spin_unlock_bh(&orig_node->ogm_cnt_lock); 1213 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
1033 batadv_orig_node_free_ref(orig_node); 1214 batadv_orig_node_free_ref(orig_node);
1034 return ret; 1215 return ret;
1035} 1216}
@@ -1041,7 +1222,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1041{ 1222{
1042 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 1223 struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1043 struct batadv_hard_iface *hard_iface; 1224 struct batadv_hard_iface *hard_iface;
1044 struct batadv_orig_node *orig_neigh_node, *orig_node; 1225 struct batadv_orig_node *orig_neigh_node, *orig_node, *orig_node_tmp;
1045 struct batadv_neigh_node *router = NULL, *router_router = NULL; 1226 struct batadv_neigh_node *router = NULL, *router_router = NULL;
1046 struct batadv_neigh_node *orig_neigh_router = NULL; 1227 struct batadv_neigh_node *orig_neigh_router = NULL;
1047 int has_directlink_flag; 1228 int has_directlink_flag;
@@ -1125,8 +1306,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1125 int16_t if_num; 1306 int16_t if_num;
1126 uint8_t *weight; 1307 uint8_t *weight;
1127 1308
1128 orig_neigh_node = batadv_get_orig_node(bat_priv, 1309 orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1129 ethhdr->h_source); 1310 ethhdr->h_source);
1130 if (!orig_neigh_node) 1311 if (!orig_neigh_node)
1131 return; 1312 return;
1132 1313
@@ -1140,15 +1321,15 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1140 if_num = if_incoming->if_num; 1321 if_num = if_incoming->if_num;
1141 offset = if_num * BATADV_NUM_WORDS; 1322 offset = if_num * BATADV_NUM_WORDS;
1142 1323
1143 spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); 1324 spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1144 word = &(orig_neigh_node->bcast_own[offset]); 1325 word = &(orig_neigh_node->bat_iv.bcast_own[offset]);
1145 bit_pos = if_incoming_seqno - 2; 1326 bit_pos = if_incoming_seqno - 2;
1146 bit_pos -= ntohl(batadv_ogm_packet->seqno); 1327 bit_pos -= ntohl(batadv_ogm_packet->seqno);
1147 batadv_set_bit(word, bit_pos); 1328 batadv_set_bit(word, bit_pos);
1148 weight = &orig_neigh_node->bcast_own_sum[if_num]; 1329 weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num];
1149 *weight = bitmap_weight(word, 1330 *weight = bitmap_weight(word,
1150 BATADV_TQ_LOCAL_WINDOW_SIZE); 1331 BATADV_TQ_LOCAL_WINDOW_SIZE);
1151 spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); 1332 spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
1152 } 1333 }
1153 1334
1154 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 1335 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -1171,7 +1352,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1171 return; 1352 return;
1172 } 1353 }
1173 1354
1174 orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); 1355 orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig);
1175 if (!orig_node) 1356 if (!orig_node)
1176 return; 1357 return;
1177 1358
@@ -1192,10 +1373,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1192 } 1373 }
1193 1374
1194 router = batadv_orig_node_get_router(orig_node); 1375 router = batadv_orig_node_get_router(orig_node);
1195 if (router) 1376 if (router) {
1196 router_router = batadv_orig_node_get_router(router->orig_node); 1377 orig_node_tmp = router->orig_node;
1378 router_router = batadv_orig_node_get_router(orig_node_tmp);
1379 }
1197 1380
1198 if ((router && router->tq_avg != 0) && 1381 if ((router && router->bat_iv.tq_avg != 0) &&
1199 (batadv_compare_eth(router->addr, ethhdr->h_source))) 1382 (batadv_compare_eth(router->addr, ethhdr->h_source)))
1200 is_from_best_next_hop = true; 1383 is_from_best_next_hop = true;
1201 1384
@@ -1219,8 +1402,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
1219 if (is_single_hop_neigh) 1402 if (is_single_hop_neigh)
1220 orig_neigh_node = orig_node; 1403 orig_neigh_node = orig_node;
1221 else 1404 else
1222 orig_neigh_node = batadv_get_orig_node(bat_priv, 1405 orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
1223 ethhdr->h_source); 1406 ethhdr->h_source);
1224 1407
1225 if (!orig_neigh_node) 1408 if (!orig_neigh_node)
1226 goto out; 1409 goto out;
@@ -1351,6 +1534,106 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
1351 return NET_RX_SUCCESS; 1534 return NET_RX_SUCCESS;
1352} 1535}
1353 1536
1537/**
1538 * batadv_iv_ogm_orig_print - print the originator table
1539 * @bat_priv: the bat priv with all the soft interface information
1540 * @seq: debugfs table seq_file struct
1541 */
1542static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
1543 struct seq_file *seq)
1544{
1545 struct batadv_neigh_node *neigh_node, *neigh_node_tmp;
1546 struct batadv_hashtable *hash = bat_priv->orig_hash;
1547 int last_seen_msecs, last_seen_secs;
1548 struct batadv_orig_node *orig_node;
1549 unsigned long last_seen_jiffies;
1550 struct hlist_head *head;
1551 int batman_count = 0;
1552 uint32_t i;
1553
1554 seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
1555 "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
1556 "Nexthop", "outgoingIF", "Potential nexthops");
1557
1558 for (i = 0; i < hash->size; i++) {
1559 head = &hash->table[i];
1560
1561 rcu_read_lock();
1562 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
1563 neigh_node = batadv_orig_node_get_router(orig_node);
1564 if (!neigh_node)
1565 continue;
1566
1567 if (neigh_node->bat_iv.tq_avg == 0)
1568 goto next;
1569
1570 last_seen_jiffies = jiffies - orig_node->last_seen;
1571 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
1572 last_seen_secs = last_seen_msecs / 1000;
1573 last_seen_msecs = last_seen_msecs % 1000;
1574
1575 seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
1576 orig_node->orig, last_seen_secs,
1577 last_seen_msecs, neigh_node->bat_iv.tq_avg,
1578 neigh_node->addr,
1579 neigh_node->if_incoming->net_dev->name);
1580
1581 hlist_for_each_entry_rcu(neigh_node_tmp,
1582 &orig_node->neigh_list, list) {
1583 seq_printf(seq, " %pM (%3i)",
1584 neigh_node_tmp->addr,
1585 neigh_node_tmp->bat_iv.tq_avg);
1586 }
1587
1588 seq_puts(seq, "\n");
1589 batman_count++;
1590
1591next:
1592 batadv_neigh_node_free_ref(neigh_node);
1593 }
1594 rcu_read_unlock();
1595 }
1596
1597 if (batman_count == 0)
1598 seq_puts(seq, "No batman nodes in range ...\n");
1599}
1600
1601/**
1602 * batadv_iv_ogm_neigh_cmp - compare the metrics of two neighbors
1603 * @neigh1: the first neighbor object of the comparison
1604 * @neigh2: the second neighbor object of the comparison
1605 *
1606 * Returns a value less, equal to or greater than 0 if the metric via neigh1 is
1607 * lower, the same as or higher than the metric via neigh2
1608 */
1609static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
1610 struct batadv_neigh_node *neigh2)
1611{
1612 uint8_t tq1, tq2;
1613
1614 tq1 = neigh1->bat_iv.tq_avg;
1615 tq2 = neigh2->bat_iv.tq_avg;
1616
1617 return tq1 - tq2;
1618}
1619
1620/**
1621 * batadv_iv_ogm_neigh_is_eob - check if neigh1 is equally good or better than
1622 * neigh2 from the metric prospective
1623 * @neigh1: the first neighbor object of the comparison
1624 * @neigh2: the second neighbor object of the comparison
1625 *
1626 * Returns true if the metric via neigh1 is equally good or better than the
1627 * metric via neigh2, false otherwise.
1628 */
1629static bool batadv_iv_ogm_neigh_is_eob(struct batadv_neigh_node *neigh1,
1630 struct batadv_neigh_node *neigh2)
1631{
1632 int diff = batadv_iv_ogm_neigh_cmp(neigh1, neigh2);
1633
1634 return diff > -BATADV_TQ_SIMILARITY_THRESHOLD;
1635}
1636
1354static struct batadv_algo_ops batadv_batman_iv __read_mostly = { 1637static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
1355 .name = "BATMAN_IV", 1638 .name = "BATMAN_IV",
1356 .bat_iface_enable = batadv_iv_ogm_iface_enable, 1639 .bat_iface_enable = batadv_iv_ogm_iface_enable,
@@ -1359,6 +1642,12 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
1359 .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set, 1642 .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set,
1360 .bat_ogm_schedule = batadv_iv_ogm_schedule, 1643 .bat_ogm_schedule = batadv_iv_ogm_schedule,
1361 .bat_ogm_emit = batadv_iv_ogm_emit, 1644 .bat_ogm_emit = batadv_iv_ogm_emit,
1645 .bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
1646 .bat_neigh_is_equiv_or_better = batadv_iv_ogm_neigh_is_eob,
1647 .bat_orig_print = batadv_iv_ogm_orig_print,
1648 .bat_orig_free = batadv_iv_ogm_orig_free,
1649 .bat_orig_add_if = batadv_iv_ogm_orig_add_if,
1650 .bat_orig_del_if = batadv_iv_ogm_orig_del_if,
1362}; 1651};
1363 1652
1364int __init batadv_iv_init(void) 1653int __init batadv_iv_init(void)
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 20fa053b7f57..2449afaa7638 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -137,7 +137,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
137 if (!atomic_inc_not_zero(&gw_node->refcount)) 137 if (!atomic_inc_not_zero(&gw_node->refcount))
138 goto next; 138 goto next;
139 139
140 tq_avg = router->tq_avg; 140 tq_avg = router->bat_iv.tq_avg;
141 141
142 switch (atomic_read(&bat_priv->gw_sel_class)) { 142 switch (atomic_read(&bat_priv->gw_sel_class)) {
143 case 1: /* fast connection */ 143 case 1: /* fast connection */
@@ -256,7 +256,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
256 next_gw->bandwidth_down / 10, 256 next_gw->bandwidth_down / 10,
257 next_gw->bandwidth_down % 10, 257 next_gw->bandwidth_down % 10,
258 next_gw->bandwidth_up / 10, 258 next_gw->bandwidth_up / 10,
259 next_gw->bandwidth_up % 10, router->tq_avg); 259 next_gw->bandwidth_up % 10, router->bat_iv.tq_avg);
260 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD, 260 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
261 gw_addr); 261 gw_addr);
262 } else { 262 } else {
@@ -266,7 +266,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
266 next_gw->bandwidth_down / 10, 266 next_gw->bandwidth_down / 10,
267 next_gw->bandwidth_down % 10, 267 next_gw->bandwidth_down % 10,
268 next_gw->bandwidth_up / 10, 268 next_gw->bandwidth_up / 10,
269 next_gw->bandwidth_up % 10, router->tq_avg); 269 next_gw->bandwidth_up % 10, router->bat_iv.tq_avg);
270 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE, 270 batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
271 gw_addr); 271 gw_addr);
272 } 272 }
@@ -305,8 +305,8 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
305 if (!router_orig) 305 if (!router_orig)
306 goto out; 306 goto out;
307 307
308 gw_tq_avg = router_gw->tq_avg; 308 gw_tq_avg = router_gw->bat_iv.tq_avg;
309 orig_tq_avg = router_orig->tq_avg; 309 orig_tq_avg = router_orig->bat_iv.tq_avg;
310 310
311 /* the TQ value has to be better */ 311 /* the TQ value has to be better */
312 if (orig_tq_avg < gw_tq_avg) 312 if (orig_tq_avg < gw_tq_avg)
@@ -528,7 +528,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
528 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n", 528 ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
529 (curr_gw == gw_node ? "=>" : " "), 529 (curr_gw == gw_node ? "=>" : " "),
530 gw_node->orig_node->orig, 530 gw_node->orig_node->orig,
531 router->tq_avg, router->addr, 531 router->bat_iv.tq_avg, router->addr,
532 router->if_incoming->net_dev->name, 532 router->if_incoming->net_dev->name,
533 gw_node->bandwidth_down / 10, 533 gw_node->bandwidth_down / 10,
534 gw_node->bandwidth_down % 10, 534 gw_node->bandwidth_down % 10,
@@ -792,7 +792,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
792 if (!neigh_curr) 792 if (!neigh_curr)
793 goto out; 793 goto out;
794 794
795 curr_tq_avg = neigh_curr->tq_avg; 795 curr_tq_avg = neigh_curr->bat_iv.tq_avg;
796 break; 796 break;
797 case BATADV_GW_MODE_OFF: 797 case BATADV_GW_MODE_OFF:
798 default: 798 default:
@@ -803,7 +803,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
803 if (!neigh_old) 803 if (!neigh_old)
804 goto out; 804 goto out;
805 805
806 if (curr_tq_avg - neigh_old->tq_avg > BATADV_GW_THRESHOLD) 806 if (curr_tq_avg - neigh_old->bat_iv.tq_avg > BATADV_GW_THRESHOLD)
807 out_of_range = true; 807 out_of_range = true;
808 808
809out: 809out:
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c5f871f218c6..57c2a19dcb5c 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,6 +28,7 @@
28#include "originator.h" 28#include "originator.h"
29#include "hash.h" 29#include "hash.h"
30#include "bridge_loop_avoidance.h" 30#include "bridge_loop_avoidance.h"
31#include "gateway_client.h"
31 32
32#include <linux/if_arp.h> 33#include <linux/if_arp.h>
33#include <linux/if_ether.h> 34#include <linux/if_ether.h>
@@ -124,8 +125,11 @@ static int batadv_is_valid_iface(const struct net_device *net_dev)
124 * 125 *
125 * Returns true if the net device is a 802.11 wireless device, false otherwise. 126 * Returns true if the net device is a 802.11 wireless device, false otherwise.
126 */ 127 */
127static bool batadv_is_wifi_netdev(struct net_device *net_device) 128bool batadv_is_wifi_netdev(struct net_device *net_device)
128{ 129{
130 if (!net_device)
131 return false;
132
129#ifdef CONFIG_WIRELESS_EXT 133#ifdef CONFIG_WIRELESS_EXT
130 /* pre-cfg80211 drivers have to implement WEXT, so it is possible to 134 /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
131 * check for wireless_handlers != NULL 135 * check for wireless_handlers != NULL
@@ -141,34 +145,6 @@ static bool batadv_is_wifi_netdev(struct net_device *net_device)
141 return false; 145 return false;
142} 146}
143 147
144/**
145 * batadv_is_wifi_iface - check if the given interface represented by ifindex
146 * is a wifi interface
147 * @ifindex: interface index to check
148 *
149 * Returns true if the interface represented by ifindex is a 802.11 wireless
150 * device, false otherwise.
151 */
152bool batadv_is_wifi_iface(int ifindex)
153{
154 struct net_device *net_device = NULL;
155 bool ret = false;
156
157 if (ifindex == BATADV_NULL_IFINDEX)
158 goto out;
159
160 net_device = dev_get_by_index(&init_net, ifindex);
161 if (!net_device)
162 goto out;
163
164 ret = batadv_is_wifi_netdev(net_device);
165
166out:
167 if (net_device)
168 dev_put(net_device);
169 return ret;
170}
171
172static struct batadv_hard_iface * 148static struct batadv_hard_iface *
173batadv_hardif_get_active(const struct net_device *soft_iface) 149batadv_hardif_get_active(const struct net_device *soft_iface)
174{ 150{
@@ -266,16 +242,9 @@ static void batadv_check_known_mac_addr(const struct net_device *net_dev)
266 242
267int batadv_hardif_min_mtu(struct net_device *soft_iface) 243int batadv_hardif_min_mtu(struct net_device *soft_iface)
268{ 244{
269 const struct batadv_priv *bat_priv = netdev_priv(soft_iface); 245 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
270 const struct batadv_hard_iface *hard_iface; 246 const struct batadv_hard_iface *hard_iface;
271 /* allow big frames if all devices are capable to do so
272 * (have MTU > 1500 + batadv_max_header_len())
273 */
274 int min_mtu = ETH_DATA_LEN; 247 int min_mtu = ETH_DATA_LEN;
275 int max_header_len = batadv_max_header_len();
276
277 if (atomic_read(&bat_priv->fragmentation))
278 goto out;
279 248
280 rcu_read_lock(); 249 rcu_read_lock();
281 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 250 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
@@ -286,22 +255,40 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface)
286 if (hard_iface->soft_iface != soft_iface) 255 if (hard_iface->soft_iface != soft_iface)
287 continue; 256 continue;
288 257
289 min_mtu = min_t(int, hard_iface->net_dev->mtu - max_header_len, 258 min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
290 min_mtu);
291 } 259 }
292 rcu_read_unlock(); 260 rcu_read_unlock();
261
262 atomic_set(&bat_priv->packet_size_max, min_mtu);
263
264 if (atomic_read(&bat_priv->fragmentation) == 0)
265 goto out;
266
267 /* with fragmentation enabled the maximum size of internally generated
268 * packets such as translation table exchanges or tvlv containers, etc
269 * has to be calculated
270 */
271 min_mtu = min_t(int, min_mtu, BATADV_FRAG_MAX_FRAG_SIZE);
272 min_mtu -= sizeof(struct batadv_frag_packet);
273 min_mtu *= BATADV_FRAG_MAX_FRAGMENTS;
274 atomic_set(&bat_priv->packet_size_max, min_mtu);
275
276 /* with fragmentation enabled we can fragment external packets easily */
277 min_mtu = min_t(int, min_mtu, ETH_DATA_LEN);
278
293out: 279out:
294 return min_mtu; 280 return min_mtu - batadv_max_header_len();
295} 281}
296 282
297/* adjusts the MTU if a new interface with a smaller MTU appeared. */ 283/* adjusts the MTU if a new interface with a smaller MTU appeared. */
298void batadv_update_min_mtu(struct net_device *soft_iface) 284void batadv_update_min_mtu(struct net_device *soft_iface)
299{ 285{
300 int min_mtu; 286 soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
301 287
302 min_mtu = batadv_hardif_min_mtu(soft_iface); 288 /* Check if the local translate table should be cleaned up to match a
303 if (soft_iface->mtu != min_mtu) 289 * new (and smaller) MTU.
304 soft_iface->mtu = min_mtu; 290 */
291 batadv_tt_local_resize_to_mtu(soft_iface);
305} 292}
306 293
307static void 294static void
@@ -524,8 +511,12 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
524 dev_put(hard_iface->soft_iface); 511 dev_put(hard_iface->soft_iface);
525 512
526 /* nobody uses this interface anymore */ 513 /* nobody uses this interface anymore */
527 if (!bat_priv->num_ifaces && autodel == BATADV_IF_CLEANUP_AUTO) 514 if (!bat_priv->num_ifaces) {
528 batadv_softif_destroy_sysfs(hard_iface->soft_iface); 515 batadv_gw_check_client_stop(bat_priv);
516
517 if (autodel == BATADV_IF_CLEANUP_AUTO)
518 batadv_softif_destroy_sysfs(hard_iface->soft_iface);
519 }
529 520
530 netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface); 521 netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
531 hard_iface->soft_iface = NULL; 522 hard_iface->soft_iface = NULL;
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index 49892881a7c5..df4c8bd45c40 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -41,6 +41,7 @@ enum batadv_hard_if_cleanup {
41 41
42extern struct notifier_block batadv_hard_if_notifier; 42extern struct notifier_block batadv_hard_if_notifier;
43 43
44bool batadv_is_wifi_netdev(struct net_device *net_device);
44struct batadv_hard_iface* 45struct batadv_hard_iface*
45batadv_hardif_get_by_netdev(const struct net_device *net_dev); 46batadv_hardif_get_by_netdev(const struct net_device *net_dev);
46int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, 47int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
@@ -51,7 +52,6 @@ void batadv_hardif_remove_interfaces(void);
51int batadv_hardif_min_mtu(struct net_device *soft_iface); 52int batadv_hardif_min_mtu(struct net_device *soft_iface);
52void batadv_update_min_mtu(struct net_device *soft_iface); 53void batadv_update_min_mtu(struct net_device *soft_iface);
53void batadv_hardif_free_rcu(struct rcu_head *rcu); 54void batadv_hardif_free_rcu(struct rcu_head *rcu);
54bool batadv_is_wifi_iface(int ifindex);
55 55
56static inline void 56static inline void
57batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface) 57batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface)
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 82ac6472fa6f..29ae4efe3543 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -29,7 +29,7 @@
29static struct batadv_socket_client *batadv_socket_client_hash[256]; 29static struct batadv_socket_client *batadv_socket_client_hash[256];
30 30
31static void batadv_socket_add_packet(struct batadv_socket_client *socket_client, 31static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
32 struct batadv_icmp_packet_rr *icmp_packet, 32 struct batadv_icmp_header *icmph,
33 size_t icmp_len); 33 size_t icmp_len);
34 34
35void batadv_socket_init(void) 35void batadv_socket_init(void)
@@ -155,13 +155,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
155 struct batadv_priv *bat_priv = socket_client->bat_priv; 155 struct batadv_priv *bat_priv = socket_client->bat_priv;
156 struct batadv_hard_iface *primary_if = NULL; 156 struct batadv_hard_iface *primary_if = NULL;
157 struct sk_buff *skb; 157 struct sk_buff *skb;
158 struct batadv_icmp_packet_rr *icmp_packet; 158 struct batadv_icmp_packet_rr *icmp_packet_rr;
159 159 struct batadv_icmp_header *icmp_header;
160 struct batadv_orig_node *orig_node = NULL; 160 struct batadv_orig_node *orig_node = NULL;
161 struct batadv_neigh_node *neigh_node = NULL; 161 struct batadv_neigh_node *neigh_node = NULL;
162 size_t packet_len = sizeof(struct batadv_icmp_packet); 162 size_t packet_len = sizeof(struct batadv_icmp_packet);
163 163
164 if (len < sizeof(struct batadv_icmp_packet)) { 164 if (len < sizeof(struct batadv_icmp_header)) {
165 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 165 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
166 "Error - can't send packet from char device: invalid packet size\n"); 166 "Error - can't send packet from char device: invalid packet size\n");
167 return -EINVAL; 167 return -EINVAL;
@@ -174,8 +174,10 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
174 goto out; 174 goto out;
175 } 175 }
176 176
177 if (len >= sizeof(struct batadv_icmp_packet_rr)) 177 if (len >= BATADV_ICMP_MAX_PACKET_SIZE)
178 packet_len = sizeof(struct batadv_icmp_packet_rr); 178 packet_len = BATADV_ICMP_MAX_PACKET_SIZE;
179 else
180 packet_len = len;
179 181
180 skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN); 182 skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
181 if (!skb) { 183 if (!skb) {
@@ -185,67 +187,78 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
185 187
186 skb->priority = TC_PRIO_CONTROL; 188 skb->priority = TC_PRIO_CONTROL;
187 skb_reserve(skb, ETH_HLEN); 189 skb_reserve(skb, ETH_HLEN);
188 icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len); 190 icmp_header = (struct batadv_icmp_header *)skb_put(skb, packet_len);
189 191
190 if (copy_from_user(icmp_packet, buff, packet_len)) { 192 if (copy_from_user(icmp_header, buff, packet_len)) {
191 len = -EFAULT; 193 len = -EFAULT;
192 goto free_skb; 194 goto free_skb;
193 } 195 }
194 196
195 if (icmp_packet->icmph.header.packet_type != BATADV_ICMP) { 197 if (icmp_header->header.packet_type != BATADV_ICMP) {
196 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 198 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
197 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); 199 "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
198 len = -EINVAL; 200 len = -EINVAL;
199 goto free_skb; 201 goto free_skb;
200 } 202 }
201 203
202 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) { 204 switch (icmp_header->msg_type) {
205 case BATADV_ECHO_REQUEST:
206 if (len < sizeof(struct batadv_icmp_packet)) {
207 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
208 "Error - can't send packet from char device: invalid packet size\n");
209 len = -EINVAL;
210 goto free_skb;
211 }
212
213 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
214 goto dst_unreach;
215
216 orig_node = batadv_orig_hash_find(bat_priv, icmp_header->dst);
217 if (!orig_node)
218 goto dst_unreach;
219
220 neigh_node = batadv_orig_node_get_router(orig_node);
221 if (!neigh_node)
222 goto dst_unreach;
223
224 if (!neigh_node->if_incoming)
225 goto dst_unreach;
226
227 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
228 goto dst_unreach;
229
230 icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmp_header;
231 if (packet_len == sizeof(*icmp_packet_rr))
232 memcpy(icmp_packet_rr->rr,
233 neigh_node->if_incoming->net_dev->dev_addr,
234 ETH_ALEN);
235
236 break;
237 default:
203 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 238 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
204 "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); 239 "Error - can't send packet from char device: got unknown message type\n");
205 len = -EINVAL; 240 len = -EINVAL;
206 goto free_skb; 241 goto free_skb;
207 } 242 }
208 243
209 icmp_packet->icmph.uid = socket_client->index; 244 icmp_header->uid = socket_client->index;
210 245
211 if (icmp_packet->icmph.header.version != BATADV_COMPAT_VERSION) { 246 if (icmp_header->header.version != BATADV_COMPAT_VERSION) {
212 icmp_packet->icmph.msg_type = BATADV_PARAMETER_PROBLEM; 247 icmp_header->msg_type = BATADV_PARAMETER_PROBLEM;
213 icmp_packet->icmph.header.version = BATADV_COMPAT_VERSION; 248 icmp_header->header.version = BATADV_COMPAT_VERSION;
214 batadv_socket_add_packet(socket_client, icmp_packet, 249 batadv_socket_add_packet(socket_client, icmp_header,
215 packet_len); 250 packet_len);
216 goto free_skb; 251 goto free_skb;
217 } 252 }
218 253
219 if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 254 memcpy(icmp_header->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
220 goto dst_unreach;
221
222 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst);
223 if (!orig_node)
224 goto dst_unreach;
225
226 neigh_node = batadv_orig_node_get_router(orig_node);
227 if (!neigh_node)
228 goto dst_unreach;
229
230 if (!neigh_node->if_incoming)
231 goto dst_unreach;
232
233 if (neigh_node->if_incoming->if_status != BATADV_IF_ACTIVE)
234 goto dst_unreach;
235
236 memcpy(icmp_packet->icmph.orig,
237 primary_if->net_dev->dev_addr, ETH_ALEN);
238
239 if (packet_len == sizeof(struct batadv_icmp_packet_rr))
240 memcpy(icmp_packet->rr,
241 neigh_node->if_incoming->net_dev->dev_addr, ETH_ALEN);
242 255
243 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 256 batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
244 goto out; 257 goto out;
245 258
246dst_unreach: 259dst_unreach:
247 icmp_packet->icmph.msg_type = BATADV_DESTINATION_UNREACHABLE; 260 icmp_header->msg_type = BATADV_DESTINATION_UNREACHABLE;
248 batadv_socket_add_packet(socket_client, icmp_packet, packet_len); 261 batadv_socket_add_packet(socket_client, icmp_header, packet_len);
249free_skb: 262free_skb:
250 kfree_skb(skb); 263 kfree_skb(skb);
251out: 264out:
@@ -298,27 +311,40 @@ err:
298 return -ENOMEM; 311 return -ENOMEM;
299} 312}
300 313
314/**
315 * batadv_socket_receive_packet - schedule an icmp packet to be sent to userspace
316 * on an icmp socket.
317 * @socket_client: the socket this packet belongs to
318 * @icmph: pointer to the header of the icmp packet
319 * @icmp_len: total length of the icmp packet
320 */
301static void batadv_socket_add_packet(struct batadv_socket_client *socket_client, 321static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
302 struct batadv_icmp_packet_rr *icmp_packet, 322 struct batadv_icmp_header *icmph,
303 size_t icmp_len) 323 size_t icmp_len)
304{ 324{
305 struct batadv_socket_packet *socket_packet; 325 struct batadv_socket_packet *socket_packet;
326 size_t len;
306 327
307 socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC); 328 socket_packet = kmalloc(sizeof(*socket_packet), GFP_ATOMIC);
308 329
309 if (!socket_packet) 330 if (!socket_packet)
310 return; 331 return;
311 332
333 len = icmp_len;
334 /* check the maximum length before filling the buffer */
335 if (len > sizeof(socket_packet->icmp_packet))
336 len = sizeof(socket_packet->icmp_packet);
337
312 INIT_LIST_HEAD(&socket_packet->list); 338 INIT_LIST_HEAD(&socket_packet->list);
313 memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len); 339 memcpy(&socket_packet->icmp_packet, icmph, len);
314 socket_packet->icmp_len = icmp_len; 340 socket_packet->icmp_len = len;
315 341
316 spin_lock_bh(&socket_client->lock); 342 spin_lock_bh(&socket_client->lock);
317 343
318 /* while waiting for the lock the socket_client could have been 344 /* while waiting for the lock the socket_client could have been
319 * deleted 345 * deleted
320 */ 346 */
321 if (!batadv_socket_client_hash[icmp_packet->icmph.uid]) { 347 if (!batadv_socket_client_hash[icmph->uid]) {
322 spin_unlock_bh(&socket_client->lock); 348 spin_unlock_bh(&socket_client->lock);
323 kfree(socket_packet); 349 kfree(socket_packet);
324 return; 350 return;
@@ -342,12 +368,18 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
342 wake_up(&socket_client->queue_wait); 368 wake_up(&socket_client->queue_wait);
343} 369}
344 370
345void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet, 371/**
372 * batadv_socket_receive_packet - schedule an icmp packet to be received
373 * locally and sent to userspace.
374 * @icmph: pointer to the header of the icmp packet
375 * @icmp_len: total length of the icmp packet
376 */
377void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
346 size_t icmp_len) 378 size_t icmp_len)
347{ 379{
348 struct batadv_socket_client *hash; 380 struct batadv_socket_client *hash;
349 381
350 hash = batadv_socket_client_hash[icmp_packet->icmph.uid]; 382 hash = batadv_socket_client_hash[icmph->uid];
351 if (hash) 383 if (hash)
352 batadv_socket_add_packet(hash, icmp_packet, icmp_len); 384 batadv_socket_add_packet(hash, icmph, icmp_len);
353} 385}
diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h
index 1fcca37b6223..6665080dff79 100644
--- a/net/batman-adv/icmp_socket.h
+++ b/net/batman-adv/icmp_socket.h
@@ -24,7 +24,7 @@
24 24
25void batadv_socket_init(void); 25void batadv_socket_init(void);
26int batadv_socket_setup(struct batadv_priv *bat_priv); 26int batadv_socket_setup(struct batadv_priv *bat_priv);
27void batadv_socket_receive_packet(struct batadv_icmp_packet_rr *icmp_packet, 27void batadv_socket_receive_packet(struct batadv_icmp_header *icmph,
28 size_t icmp_len); 28 size_t icmp_len);
29 29
30#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */ 30#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 3159a148c1ac..c51a5e568f0a 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -501,7 +501,9 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops)
501 !bat_algo_ops->bat_iface_update_mac || 501 !bat_algo_ops->bat_iface_update_mac ||
502 !bat_algo_ops->bat_primary_iface_set || 502 !bat_algo_ops->bat_primary_iface_set ||
503 !bat_algo_ops->bat_ogm_schedule || 503 !bat_algo_ops->bat_ogm_schedule ||
504 !bat_algo_ops->bat_ogm_emit) { 504 !bat_algo_ops->bat_ogm_emit ||
505 !bat_algo_ops->bat_neigh_cmp ||
506 !bat_algo_ops->bat_neigh_is_equiv_or_better) {
505 pr_info("Routing algo '%s' does not implement required ops\n", 507 pr_info("Routing algo '%s' does not implement required ops\n",
506 bat_algo_ops->name); 508 bat_algo_ops->name);
507 ret = -EINVAL; 509 ret = -EINVAL;
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index d7dfafe45f29..f94f287b8670 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -26,7 +26,7 @@
26#define BATADV_DRIVER_DEVICE "batman-adv" 26#define BATADV_DRIVER_DEVICE "batman-adv"
27 27
28#ifndef BATADV_SOURCE_VERSION 28#ifndef BATADV_SOURCE_VERSION
29#define BATADV_SOURCE_VERSION "2013.4.0" 29#define BATADV_SOURCE_VERSION "2013.5.0"
30#endif 30#endif
31 31
32/* B.A.T.M.A.N. parameters */ 32/* B.A.T.M.A.N. parameters */
@@ -86,6 +86,12 @@
86/* numbers of originator to contact for any PUT/GET DHT operation */ 86/* numbers of originator to contact for any PUT/GET DHT operation */
87#define BATADV_DAT_CANDIDATES_NUM 3 87#define BATADV_DAT_CANDIDATES_NUM 3
88 88
89/**
90 * BATADV_TQ_SIMILARITY_THRESHOLD - TQ points that a secondary metric can differ
91 * at most from the primary one in order to be still considered acceptable
92 */
93#define BATADV_TQ_SIMILARITY_THRESHOLD 50
94
89/* how much worse secondary interfaces may be to be considered as bonding 95/* how much worse secondary interfaces may be to be considered as bonding
90 * candidates 96 * candidates
91 */ 97 */
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index 23f611bedb0f..351e199bc0af 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -1003,7 +1003,7 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
1003 struct batadv_nc_packet *nc_packet, 1003 struct batadv_nc_packet *nc_packet,
1004 struct batadv_neigh_node *neigh_node) 1004 struct batadv_neigh_node *neigh_node)
1005{ 1005{
1006 uint8_t tq_weighted_neigh, tq_weighted_coding; 1006 uint8_t tq_weighted_neigh, tq_weighted_coding, tq_tmp;
1007 struct sk_buff *skb_dest, *skb_src; 1007 struct sk_buff *skb_dest, *skb_src;
1008 struct batadv_unicast_packet *packet1; 1008 struct batadv_unicast_packet *packet1;
1009 struct batadv_unicast_packet *packet2; 1009 struct batadv_unicast_packet *packet2;
@@ -1028,8 +1028,10 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
1028 if (!router_coding) 1028 if (!router_coding)
1029 goto out; 1029 goto out;
1030 1030
1031 tq_weighted_neigh = batadv_nc_random_weight_tq(router_neigh->tq_avg); 1031 tq_tmp = batadv_nc_random_weight_tq(router_neigh->bat_iv.tq_avg);
1032 tq_weighted_coding = batadv_nc_random_weight_tq(router_coding->tq_avg); 1032 tq_weighted_neigh = tq_tmp;
1033 tq_tmp = batadv_nc_random_weight_tq(router_coding->bat_iv.tq_avg);
1034 tq_weighted_coding = tq_tmp;
1033 1035
1034 /* Select one destination for the MAC-header dst-field based on 1036 /* Select one destination for the MAC-header dst-field based on
1035 * weighted TQ-values. 1037 * weighted TQ-values.
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index ee1d84724205..8ab14340d10f 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -36,7 +36,7 @@ static struct lock_class_key batadv_orig_hash_lock_class_key;
36static void batadv_purge_orig(struct work_struct *work); 36static void batadv_purge_orig(struct work_struct *work);
37 37
38/* returns 1 if they are the same originator */ 38/* returns 1 if they are the same originator */
39static int batadv_compare_orig(const struct hlist_node *node, const void *data2) 39int batadv_compare_orig(const struct hlist_node *node, const void *data2)
40{ 40{
41 const void *data1 = container_of(node, struct batadv_orig_node, 41 const void *data1 = container_of(node, struct batadv_orig_node,
42 hash_entry); 42 hash_entry);
@@ -172,11 +172,20 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
172 return router; 172 return router;
173} 173}
174 174
175/**
176 * batadv_neigh_node_new - create and init a new neigh_node object
177 * @hard_iface: the interface where the neighbour is connected to
178 * @neigh_addr: the mac address of the neighbour interface
179 * @orig_node: originator object representing the neighbour
180 *
181 * Allocates a new neigh_node object and initialises all the generic fields.
182 * Returns the new object or NULL on failure.
183 */
175struct batadv_neigh_node * 184struct batadv_neigh_node *
176batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, 185batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
177 const uint8_t *neigh_addr) 186 const uint8_t *neigh_addr,
187 struct batadv_orig_node *orig_node)
178{ 188{
179 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
180 struct batadv_neigh_node *neigh_node; 189 struct batadv_neigh_node *neigh_node;
181 190
182 neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); 191 neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
@@ -186,15 +195,14 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
186 INIT_HLIST_NODE(&neigh_node->list); 195 INIT_HLIST_NODE(&neigh_node->list);
187 196
188 memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); 197 memcpy(neigh_node->addr, neigh_addr, ETH_ALEN);
189 spin_lock_init(&neigh_node->lq_update_lock); 198 neigh_node->if_incoming = hard_iface;
199 neigh_node->orig_node = orig_node;
200
201 INIT_LIST_HEAD(&neigh_node->bonding_list);
190 202
191 /* extra reference for return */ 203 /* extra reference for return */
192 atomic_set(&neigh_node->refcount, 2); 204 atomic_set(&neigh_node->refcount, 2);
193 205
194 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
195 "Creating new neighbor %pM on interface %s\n", neigh_addr,
196 hard_iface->net_dev->name);
197
198out: 206out:
199 return neigh_node; 207 return neigh_node;
200} 208}
@@ -233,9 +241,10 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
233 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1, 241 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
234 "originator timed out"); 242 "originator timed out");
235 243
244 if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
245 orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
246
236 kfree(orig_node->tt_buff); 247 kfree(orig_node->tt_buff);
237 kfree(orig_node->bcast_own);
238 kfree(orig_node->bcast_own_sum);
239 kfree(orig_node); 248 kfree(orig_node);
240} 249}
241 250
@@ -293,21 +302,22 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
293 batadv_hash_destroy(hash); 302 batadv_hash_destroy(hash);
294} 303}
295 304
296/* this function finds or creates an originator entry for the given 305/**
297 * address if it does not exits 306 * batadv_orig_node_new - creates a new orig_node
307 * @bat_priv: the bat priv with all the soft interface information
308 * @addr: the mac address of the originator
309 *
310 * Creates a new originator object and initialise all the generic fields.
311 * The new object is not added to the originator list.
312 * Returns the newly created object or NULL on failure.
298 */ 313 */
299struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, 314struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
300 const uint8_t *addr) 315 const uint8_t *addr)
301{ 316{
302 struct batadv_orig_node *orig_node; 317 struct batadv_orig_node *orig_node;
303 struct batadv_orig_node_vlan *vlan; 318 struct batadv_orig_node_vlan *vlan;
304 int size, i;
305 int hash_added;
306 unsigned long reset_time; 319 unsigned long reset_time;
307 320 int i;
308 orig_node = batadv_orig_hash_find(bat_priv, addr);
309 if (orig_node)
310 return orig_node;
311 321
312 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 322 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
313 "Creating new originator: %pM\n", addr); 323 "Creating new originator: %pM\n", addr);
@@ -319,7 +329,6 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
319 INIT_HLIST_HEAD(&orig_node->neigh_list); 329 INIT_HLIST_HEAD(&orig_node->neigh_list);
320 INIT_LIST_HEAD(&orig_node->bond_list); 330 INIT_LIST_HEAD(&orig_node->bond_list);
321 INIT_LIST_HEAD(&orig_node->vlan_list); 331 INIT_LIST_HEAD(&orig_node->vlan_list);
322 spin_lock_init(&orig_node->ogm_cnt_lock);
323 spin_lock_init(&orig_node->bcast_seqno_lock); 332 spin_lock_init(&orig_node->bcast_seqno_lock);
324 spin_lock_init(&orig_node->neigh_list_lock); 333 spin_lock_init(&orig_node->neigh_list_lock);
325 spin_lock_init(&orig_node->tt_buff_lock); 334 spin_lock_init(&orig_node->tt_buff_lock);
@@ -355,37 +364,13 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
355 */ 364 */
356 batadv_orig_node_vlan_free_ref(vlan); 365 batadv_orig_node_vlan_free_ref(vlan);
357 366
358 size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS;
359
360 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
361 if (!orig_node->bcast_own)
362 goto free_vlan;
363
364 size = bat_priv->num_ifaces * sizeof(uint8_t);
365 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
366
367 for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) { 367 for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
368 INIT_HLIST_HEAD(&orig_node->fragments[i].head); 368 INIT_HLIST_HEAD(&orig_node->fragments[i].head);
369 spin_lock_init(&orig_node->fragments[i].lock); 369 spin_lock_init(&orig_node->fragments[i].lock);
370 orig_node->fragments[i].size = 0; 370 orig_node->fragments[i].size = 0;
371 } 371 }
372 372
373 if (!orig_node->bcast_own_sum)
374 goto free_bcast_own;
375
376 hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
377 batadv_choose_orig, orig_node,
378 &orig_node->hash_entry);
379 if (hash_added != 0)
380 goto free_bcast_own_sum;
381
382 return orig_node; 373 return orig_node;
383free_bcast_own_sum:
384 kfree(orig_node->bcast_own_sum);
385free_bcast_own:
386 kfree(orig_node->bcast_own);
387free_vlan:
388 batadv_orig_node_vlan_free_ref(vlan);
389free_orig_node: 374free_orig_node:
390 kfree(orig_node); 375 kfree(orig_node);
391 return NULL; 376 return NULL;
@@ -394,15 +379,16 @@ free_orig_node:
394static bool 379static bool
395batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, 380batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
396 struct batadv_orig_node *orig_node, 381 struct batadv_orig_node *orig_node,
397 struct batadv_neigh_node **best_neigh_node) 382 struct batadv_neigh_node **best_neigh)
398{ 383{
384 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
399 struct hlist_node *node_tmp; 385 struct hlist_node *node_tmp;
400 struct batadv_neigh_node *neigh_node; 386 struct batadv_neigh_node *neigh_node;
401 bool neigh_purged = false; 387 bool neigh_purged = false;
402 unsigned long last_seen; 388 unsigned long last_seen;
403 struct batadv_hard_iface *if_incoming; 389 struct batadv_hard_iface *if_incoming;
404 390
405 *best_neigh_node = NULL; 391 *best_neigh = NULL;
406 392
407 spin_lock_bh(&orig_node->neigh_list_lock); 393 spin_lock_bh(&orig_node->neigh_list_lock);
408 394
@@ -435,9 +421,12 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
435 batadv_bonding_candidate_del(orig_node, neigh_node); 421 batadv_bonding_candidate_del(orig_node, neigh_node);
436 batadv_neigh_node_free_ref(neigh_node); 422 batadv_neigh_node_free_ref(neigh_node);
437 } else { 423 } else {
438 if ((!*best_neigh_node) || 424 /* store the best_neighbour if this is the first
439 (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) 425 * iteration or if a better neighbor has been found
440 *best_neigh_node = neigh_node; 426 */
427 if (!*best_neigh ||
428 bao->bat_neigh_cmp(neigh_node, *best_neigh) > 0)
429 *best_neigh = neigh_node;
441 } 430 }
442 } 431 }
443 432
@@ -526,100 +515,26 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
526{ 515{
527 struct net_device *net_dev = (struct net_device *)seq->private; 516 struct net_device *net_dev = (struct net_device *)seq->private;
528 struct batadv_priv *bat_priv = netdev_priv(net_dev); 517 struct batadv_priv *bat_priv = netdev_priv(net_dev);
529 struct batadv_hashtable *hash = bat_priv->orig_hash;
530 struct hlist_head *head;
531 struct batadv_hard_iface *primary_if; 518 struct batadv_hard_iface *primary_if;
532 struct batadv_orig_node *orig_node;
533 struct batadv_neigh_node *neigh_node, *neigh_node_tmp;
534 int batman_count = 0;
535 int last_seen_secs;
536 int last_seen_msecs;
537 unsigned long last_seen_jiffies;
538 uint32_t i;
539 519
540 primary_if = batadv_seq_print_text_primary_if_get(seq); 520 primary_if = batadv_seq_print_text_primary_if_get(seq);
541 if (!primary_if) 521 if (!primary_if)
542 goto out; 522 return 0;
543 523
544 seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", 524 seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n",
545 BATADV_SOURCE_VERSION, primary_if->net_dev->name, 525 BATADV_SOURCE_VERSION, primary_if->net_dev->name,
546 primary_if->net_dev->dev_addr, net_dev->name); 526 primary_if->net_dev->dev_addr, net_dev->name,
547 seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", 527 bat_priv->bat_algo_ops->name);
548 "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
549 "Nexthop", "outgoingIF", "Potential nexthops");
550
551 for (i = 0; i < hash->size; i++) {
552 head = &hash->table[i];
553
554 rcu_read_lock();
555 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
556 neigh_node = batadv_orig_node_get_router(orig_node);
557 if (!neigh_node)
558 continue;
559
560 if (neigh_node->tq_avg == 0)
561 goto next;
562
563 last_seen_jiffies = jiffies - orig_node->last_seen;
564 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
565 last_seen_secs = last_seen_msecs / 1000;
566 last_seen_msecs = last_seen_msecs % 1000;
567
568 seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
569 orig_node->orig, last_seen_secs,
570 last_seen_msecs, neigh_node->tq_avg,
571 neigh_node->addr,
572 neigh_node->if_incoming->net_dev->name);
573
574 hlist_for_each_entry_rcu(neigh_node_tmp,
575 &orig_node->neigh_list, list) {
576 seq_printf(seq, " %pM (%3i)",
577 neigh_node_tmp->addr,
578 neigh_node_tmp->tq_avg);
579 }
580 528
581 seq_puts(seq, "\n"); 529 batadv_hardif_free_ref(primary_if);
582 batman_count++;
583 530
584next: 531 if (!bat_priv->bat_algo_ops->bat_orig_print) {
585 batadv_neigh_node_free_ref(neigh_node); 532 seq_puts(seq,
586 } 533 "No printing function for this routing protocol\n");
587 rcu_read_unlock(); 534 return 0;
588 } 535 }
589 536
590 if (batman_count == 0) 537 bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq);
591 seq_puts(seq, "No batman nodes in range ...\n");
592
593out:
594 if (primary_if)
595 batadv_hardif_free_ref(primary_if);
596 return 0;
597}
598
599static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node,
600 int max_if_num)
601{
602 void *data_ptr;
603 size_t data_size, old_size;
604
605 data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS;
606 old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS;
607 data_ptr = kmalloc(data_size, GFP_ATOMIC);
608 if (!data_ptr)
609 return -ENOMEM;
610
611 memcpy(data_ptr, orig_node->bcast_own, old_size);
612 kfree(orig_node->bcast_own);
613 orig_node->bcast_own = data_ptr;
614
615 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
616 if (!data_ptr)
617 return -ENOMEM;
618
619 memcpy(data_ptr, orig_node->bcast_own_sum,
620 (max_if_num - 1) * sizeof(uint8_t));
621 kfree(orig_node->bcast_own_sum);
622 orig_node->bcast_own_sum = data_ptr;
623 538
624 return 0; 539 return 0;
625} 540}
@@ -628,6 +543,7 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
628 int max_if_num) 543 int max_if_num)
629{ 544{
630 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 545 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
546 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
631 struct batadv_hashtable *hash = bat_priv->orig_hash; 547 struct batadv_hashtable *hash = bat_priv->orig_hash;
632 struct hlist_head *head; 548 struct hlist_head *head;
633 struct batadv_orig_node *orig_node; 549 struct batadv_orig_node *orig_node;
@@ -642,10 +558,10 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
642 558
643 rcu_read_lock(); 559 rcu_read_lock();
644 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 560 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
645 spin_lock_bh(&orig_node->ogm_cnt_lock); 561 ret = 0;
646 ret = batadv_orig_node_add_if(orig_node, max_if_num); 562 if (bao->bat_orig_add_if)
647 spin_unlock_bh(&orig_node->ogm_cnt_lock); 563 ret = bao->bat_orig_add_if(orig_node,
648 564 max_if_num);
649 if (ret == -ENOMEM) 565 if (ret == -ENOMEM)
650 goto err; 566 goto err;
651 } 567 }
@@ -659,54 +575,6 @@ err:
659 return -ENOMEM; 575 return -ENOMEM;
660} 576}
661 577
662static int batadv_orig_node_del_if(struct batadv_orig_node *orig_node,
663 int max_if_num, int del_if_num)
664{
665 void *data_ptr = NULL;
666 int chunk_size;
667
668 /* last interface was removed */
669 if (max_if_num == 0)
670 goto free_bcast_own;
671
672 chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS;
673 data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
674 if (!data_ptr)
675 return -ENOMEM;
676
677 /* copy first part */
678 memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size);
679
680 /* copy second part */
681 memcpy((char *)data_ptr + del_if_num * chunk_size,
682 orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
683 (max_if_num - del_if_num) * chunk_size);
684
685free_bcast_own:
686 kfree(orig_node->bcast_own);
687 orig_node->bcast_own = data_ptr;
688
689 if (max_if_num == 0)
690 goto free_own_sum;
691
692 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
693 if (!data_ptr)
694 return -ENOMEM;
695
696 memcpy(data_ptr, orig_node->bcast_own_sum,
697 del_if_num * sizeof(uint8_t));
698
699 memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t),
700 orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)),
701 (max_if_num - del_if_num) * sizeof(uint8_t));
702
703free_own_sum:
704 kfree(orig_node->bcast_own_sum);
705 orig_node->bcast_own_sum = data_ptr;
706
707 return 0;
708}
709
710int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, 578int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
711 int max_if_num) 579 int max_if_num)
712{ 580{
@@ -715,6 +583,7 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
715 struct hlist_head *head; 583 struct hlist_head *head;
716 struct batadv_hard_iface *hard_iface_tmp; 584 struct batadv_hard_iface *hard_iface_tmp;
717 struct batadv_orig_node *orig_node; 585 struct batadv_orig_node *orig_node;
586 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
718 uint32_t i; 587 uint32_t i;
719 int ret; 588 int ret;
720 589
@@ -726,11 +595,11 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
726 595
727 rcu_read_lock(); 596 rcu_read_lock();
728 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 597 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
729 spin_lock_bh(&orig_node->ogm_cnt_lock); 598 ret = 0;
730 ret = batadv_orig_node_del_if(orig_node, max_if_num, 599 if (bao->bat_orig_del_if)
731 hard_iface->if_num); 600 ret = bao->bat_orig_del_if(orig_node,
732 spin_unlock_bh(&orig_node->ogm_cnt_lock); 601 max_if_num,
733 602 hard_iface->if_num);
734 if (ret == -ENOMEM) 603 if (ret == -ENOMEM)
735 goto err; 604 goto err;
736 } 605 }
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index cc6d686cfe6d..6f77d808a916 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -22,16 +22,18 @@
22 22
23#include "hash.h" 23#include "hash.h"
24 24
25int batadv_compare_orig(const struct hlist_node *node, const void *data2);
25int batadv_originator_init(struct batadv_priv *bat_priv); 26int batadv_originator_init(struct batadv_priv *bat_priv);
26void batadv_originator_free(struct batadv_priv *bat_priv); 27void batadv_originator_free(struct batadv_priv *bat_priv);
27void batadv_purge_orig_ref(struct batadv_priv *bat_priv); 28void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
28void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node); 29void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
29void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node); 30void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
30struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, 31struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
31 const uint8_t *addr); 32 const uint8_t *addr);
32struct batadv_neigh_node * 33struct batadv_neigh_node *
33batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, 34batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
34 const uint8_t *neigh_addr); 35 const uint8_t *neigh_addr,
36 struct batadv_orig_node *orig_node);
35void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node); 37void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
36struct batadv_neigh_node * 38struct batadv_neigh_node *
37batadv_orig_node_get_router(struct batadv_orig_node *orig_node); 39batadv_orig_node_get_router(struct batadv_orig_node *orig_node);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 9fbcaacc345a..207459b62966 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -110,12 +110,13 @@ enum batadv_tt_data_flags {
110 110
111/* BATADV_TT_CLIENT flags. 111/* BATADV_TT_CLIENT flags.
112 * Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to 112 * Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to
113 * BIT(15) are used for local computation only 113 * BIT(15) are used for local computation only.
114 * Flags from BIT(4) to BIT(7) are kept in sync with the rest of the network.
114 */ 115 */
115enum batadv_tt_client_flags { 116enum batadv_tt_client_flags {
116 BATADV_TT_CLIENT_DEL = BIT(0), 117 BATADV_TT_CLIENT_DEL = BIT(0),
117 BATADV_TT_CLIENT_ROAM = BIT(1), 118 BATADV_TT_CLIENT_ROAM = BIT(1),
118 BATADV_TT_CLIENT_WIFI = BIT(2), 119 BATADV_TT_CLIENT_WIFI = BIT(4),
119 BATADV_TT_CLIENT_NOPURGE = BIT(8), 120 BATADV_TT_CLIENT_NOPURGE = BIT(8),
120 BATADV_TT_CLIENT_NEW = BIT(9), 121 BATADV_TT_CLIENT_NEW = BIT(9),
121 BATADV_TT_CLIENT_PENDING = BIT(10), 122 BATADV_TT_CLIENT_PENDING = BIT(10),
@@ -238,6 +239,8 @@ struct batadv_icmp_packet_rr {
238 uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; 239 uint8_t rr[BATADV_RR_LEN][ETH_ALEN];
239}; 240};
240 241
242#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr)
243
241/* All packet headers in front of an ethernet header have to be completely 244/* All packet headers in front of an ethernet header have to be completely
242 * divisible by 2 but not by 4 to make the payload after the ethernet 245 * divisible by 2 but not by 4 to make the payload after the ethernet
243 * header again 4 bytes boundary aligned. 246 * header again 4 bytes boundary aligned.
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 4bcf22129ffe..d4114d775ad6 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -115,9 +115,19 @@ out:
115 return; 115 return;
116} 116}
117 117
118void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node, 118/**
119 * batadv_bonding_candidate_add - consider a new link for bonding mode towards
120 * the given originator
121 * @bat_priv: the bat priv with all the soft interface information
122 * @orig_node: the target node
123 * @neigh_node: the neighbor representing the new link to consider for bonding
124 * mode
125 */
126void batadv_bonding_candidate_add(struct batadv_priv *bat_priv,
127 struct batadv_orig_node *orig_node,
119 struct batadv_neigh_node *neigh_node) 128 struct batadv_neigh_node *neigh_node)
120{ 129{
130 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
121 struct batadv_neigh_node *tmp_neigh_node, *router = NULL; 131 struct batadv_neigh_node *tmp_neigh_node, *router = NULL;
122 uint8_t interference_candidate = 0; 132 uint8_t interference_candidate = 0;
123 133
@@ -132,8 +142,9 @@ void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node,
132 if (!router) 142 if (!router)
133 goto candidate_del; 143 goto candidate_del;
134 144
145
135 /* ... and is good enough to be considered */ 146 /* ... and is good enough to be considered */
136 if (neigh_node->tq_avg < router->tq_avg - BATADV_BONDING_TQ_THRESHOLD) 147 if (bao->bat_neigh_is_equiv_or_better(neigh_node, router))
137 goto candidate_del; 148 goto candidate_del;
138 149
139 /* check if we have another candidate with the same mac address or 150 /* check if we have another candidate with the same mac address or
@@ -249,47 +260,65 @@ bool batadv_check_management_packet(struct sk_buff *skb,
249 return true; 260 return true;
250} 261}
251 262
263/**
264 * batadv_recv_my_icmp_packet - receive an icmp packet locally
265 * @bat_priv: the bat priv with all the soft interface information
266 * @skb: icmp packet to process
267 *
268 * Returns NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP
269 * otherwise.
270 */
252static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, 271static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
253 struct sk_buff *skb, size_t icmp_len) 272 struct sk_buff *skb)
254{ 273{
255 struct batadv_hard_iface *primary_if = NULL; 274 struct batadv_hard_iface *primary_if = NULL;
256 struct batadv_orig_node *orig_node = NULL; 275 struct batadv_orig_node *orig_node = NULL;
257 struct batadv_icmp_packet_rr *icmp_packet; 276 struct batadv_icmp_header *icmph;
258 int ret = NET_RX_DROP; 277 int res, ret = NET_RX_DROP;
259 278
260 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 279 icmph = (struct batadv_icmp_header *)skb->data;
261 280
262 /* add data to device queue */ 281 switch (icmph->msg_type) {
263 if (icmp_packet->icmph.msg_type != BATADV_ECHO_REQUEST) { 282 case BATADV_ECHO_REPLY:
264 batadv_socket_receive_packet(icmp_packet, icmp_len); 283 case BATADV_DESTINATION_UNREACHABLE:
265 goto out; 284 case BATADV_TTL_EXCEEDED:
266 } 285 /* receive the packet */
286 if (skb_linearize(skb) < 0)
287 break;
267 288
268 primary_if = batadv_primary_if_get_selected(bat_priv); 289 batadv_socket_receive_packet(icmph, skb->len);
269 if (!primary_if) 290 break;
270 goto out; 291 case BATADV_ECHO_REQUEST:
292 /* answer echo request (ping) */
293 primary_if = batadv_primary_if_get_selected(bat_priv);
294 if (!primary_if)
295 goto out;
271 296
272 /* answer echo request (ping) */ 297 /* get routing information */
273 /* get routing information */ 298 orig_node = batadv_orig_hash_find(bat_priv, icmph->orig);
274 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.orig); 299 if (!orig_node)
275 if (!orig_node) 300 goto out;
276 goto out;
277 301
278 /* create a copy of the skb, if needed, to modify it. */ 302 /* create a copy of the skb, if needed, to modify it. */
279 if (skb_cow(skb, ETH_HLEN) < 0) 303 if (skb_cow(skb, ETH_HLEN) < 0)
280 goto out; 304 goto out;
281 305
282 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 306 icmph = (struct batadv_icmp_header *)skb->data;
283 307
284 memcpy(icmp_packet->icmph.dst, icmp_packet->icmph.orig, ETH_ALEN); 308 memcpy(icmph->dst, icmph->orig, ETH_ALEN);
285 memcpy(icmp_packet->icmph.orig, primary_if->net_dev->dev_addr, 309 memcpy(icmph->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
286 ETH_ALEN); 310 icmph->msg_type = BATADV_ECHO_REPLY;
287 icmp_packet->icmph.msg_type = BATADV_ECHO_REPLY; 311 icmph->header.ttl = BATADV_TTL;
288 icmp_packet->icmph.header.ttl = BATADV_TTL;
289 312
290 if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP) 313 res = batadv_send_skb_to_orig(skb, orig_node, NULL);
291 ret = NET_RX_SUCCESS; 314 if (res != NET_XMIT_DROP)
315 ret = NET_RX_SUCCESS;
292 316
317 break;
318 default:
319 /* drop unknown type */
320 goto out;
321 }
293out: 322out:
294 if (primary_if) 323 if (primary_if)
295 batadv_hardif_free_ref(primary_if); 324 batadv_hardif_free_ref(primary_if);
@@ -352,16 +381,13 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
352 struct batadv_hard_iface *recv_if) 381 struct batadv_hard_iface *recv_if)
353{ 382{
354 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); 383 struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
355 struct batadv_icmp_packet_rr *icmp_packet; 384 struct batadv_icmp_header *icmph;
385 struct batadv_icmp_packet_rr *icmp_packet_rr;
356 struct ethhdr *ethhdr; 386 struct ethhdr *ethhdr;
357 struct batadv_orig_node *orig_node = NULL; 387 struct batadv_orig_node *orig_node = NULL;
358 int hdr_size = sizeof(struct batadv_icmp_packet); 388 int hdr_size = sizeof(struct batadv_icmp_header);
359 int ret = NET_RX_DROP; 389 int ret = NET_RX_DROP;
360 390
361 /* we truncate all incoming icmp packets if they don't match our size */
362 if (skb->len >= sizeof(struct batadv_icmp_packet_rr))
363 hdr_size = sizeof(struct batadv_icmp_packet_rr);
364
365 /* drop packet if it has not necessary minimum size */ 391 /* drop packet if it has not necessary minimum size */
366 if (unlikely(!pskb_may_pull(skb, hdr_size))) 392 if (unlikely(!pskb_may_pull(skb, hdr_size)))
367 goto out; 393 goto out;
@@ -380,28 +406,39 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
380 if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) 406 if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
381 goto out; 407 goto out;
382 408
383 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 409 icmph = (struct batadv_icmp_header *)skb->data;
384 410
385 /* add record route information if not full */ 411 /* add record route information if not full */
386 if ((icmp_packet->icmph.msg_type == BATADV_ECHO_REPLY || 412 if ((icmph->msg_type == BATADV_ECHO_REPLY ||
387 icmp_packet->icmph.msg_type == BATADV_ECHO_REQUEST) && 413 icmph->msg_type == BATADV_ECHO_REQUEST) &&
388 (hdr_size == sizeof(struct batadv_icmp_packet_rr)) && 414 (skb->len >= sizeof(struct batadv_icmp_packet_rr))) {
389 (icmp_packet->rr_cur < BATADV_RR_LEN)) { 415 if (skb_linearize(skb) < 0)
390 memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), 416 goto out;
417
418 /* create a copy of the skb, if needed, to modify it. */
419 if (skb_cow(skb, ETH_HLEN) < 0)
420 goto out;
421
422 icmph = (struct batadv_icmp_header *)skb->data;
423 icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
424 if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
425 goto out;
426
427 memcpy(&(icmp_packet_rr->rr[icmp_packet_rr->rr_cur]),
391 ethhdr->h_dest, ETH_ALEN); 428 ethhdr->h_dest, ETH_ALEN);
392 icmp_packet->rr_cur++; 429 icmp_packet_rr->rr_cur++;
393 } 430 }
394 431
395 /* packet for me */ 432 /* packet for me */
396 if (batadv_is_my_mac(bat_priv, icmp_packet->icmph.dst)) 433 if (batadv_is_my_mac(bat_priv, icmph->dst))
397 return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); 434 return batadv_recv_my_icmp_packet(bat_priv, skb);
398 435
399 /* TTL exceeded */ 436 /* TTL exceeded */
400 if (icmp_packet->icmph.header.ttl < 2) 437 if (icmph->header.ttl < 2)
401 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb); 438 return batadv_recv_icmp_ttl_exceeded(bat_priv, skb);
402 439
403 /* get routing information */ 440 /* get routing information */
404 orig_node = batadv_orig_hash_find(bat_priv, icmp_packet->icmph.dst); 441 orig_node = batadv_orig_hash_find(bat_priv, icmph->dst);
405 if (!orig_node) 442 if (!orig_node)
406 goto out; 443 goto out;
407 444
@@ -409,10 +446,10 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
409 if (skb_cow(skb, ETH_HLEN) < 0) 446 if (skb_cow(skb, ETH_HLEN) < 0)
410 goto out; 447 goto out;
411 448
412 icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; 449 icmph = (struct batadv_icmp_header *)skb->data;
413 450
414 /* decrement ttl */ 451 /* decrement ttl */
415 icmp_packet->icmph.header.ttl--; 452 icmph->header.ttl--;
416 453
417 /* route it */ 454 /* route it */
418 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP) 455 if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
@@ -479,18 +516,25 @@ out:
479 return router; 516 return router;
480} 517}
481 518
482/* Interface Alternating: Use the best of the 519/**
483 * remaining candidates which are not using 520 * batadv_find_ifalter_router - find the best of the remaining candidates which
484 * this interface. 521 * are not using this interface
522 * @bat_priv: the bat priv with all the soft interface information
523 * @primary_orig: the destination
524 * @recv_if: the interface that the router returned by this function has to not
525 * use
485 * 526 *
486 * Increases the returned router's refcount 527 * Returns the best candidate towards primary_orig that is not using recv_if.
528 * Increases the returned neighbor's refcount
487 */ 529 */
488static struct batadv_neigh_node * 530static struct batadv_neigh_node *
489batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, 531batadv_find_ifalter_router(struct batadv_priv *bat_priv,
532 struct batadv_orig_node *primary_orig,
490 const struct batadv_hard_iface *recv_if) 533 const struct batadv_hard_iface *recv_if)
491{ 534{
492 struct batadv_neigh_node *tmp_neigh_node;
493 struct batadv_neigh_node *router = NULL, *first_candidate = NULL; 535 struct batadv_neigh_node *router = NULL, *first_candidate = NULL;
536 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
537 struct batadv_neigh_node *tmp_neigh_node;
494 538
495 rcu_read_lock(); 539 rcu_read_lock();
496 list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list, 540 list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list,
@@ -502,7 +546,7 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
502 if (tmp_neigh_node->if_incoming == recv_if) 546 if (tmp_neigh_node->if_incoming == recv_if)
503 continue; 547 continue;
504 548
505 if (router && tmp_neigh_node->tq_avg <= router->tq_avg) 549 if (router && bao->bat_neigh_cmp(tmp_neigh_node, router))
506 continue; 550 continue;
507 551
508 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) 552 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
@@ -636,7 +680,8 @@ batadv_find_router(struct batadv_priv *bat_priv,
636 if (bonding_enabled) 680 if (bonding_enabled)
637 router = batadv_find_bond_router(primary_orig_node, recv_if); 681 router = batadv_find_bond_router(primary_orig_node, recv_if);
638 else 682 else
639 router = batadv_find_ifalter_router(primary_orig_node, recv_if); 683 router = batadv_find_ifalter_router(bat_priv, primary_orig_node,
684 recv_if);
640 685
641return_router: 686return_router:
642 if (router && router->if_incoming->if_status != BATADV_IF_ACTIVE) 687 if (router && router->if_incoming->if_status != BATADV_IF_ACTIVE)
diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h
index 55d637a90621..19544ddb81b5 100644
--- a/net/batman-adv/routing.h
+++ b/net/batman-adv/routing.h
@@ -48,7 +48,8 @@ batadv_find_router(struct batadv_priv *bat_priv,
48 const struct batadv_hard_iface *recv_if); 48 const struct batadv_hard_iface *recv_if);
49void batadv_bonding_candidate_del(struct batadv_orig_node *orig_node, 49void batadv_bonding_candidate_del(struct batadv_orig_node *orig_node,
50 struct batadv_neigh_node *neigh_node); 50 struct batadv_neigh_node *neigh_node);
51void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node, 51void batadv_bonding_candidate_add(struct batadv_priv *bat_priv,
52 struct batadv_orig_node *orig_node,
52 struct batadv_neigh_node *neigh_node); 53 struct batadv_neigh_node *neigh_node);
53void batadv_bonding_save_primary(const struct batadv_orig_node *orig_node, 54void batadv_bonding_save_primary(const struct batadv_orig_node *orig_node,
54 struct batadv_orig_node *orig_neigh_node, 55 struct batadv_orig_node *orig_neigh_node,
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index e70f530d8568..36f050876f82 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -166,7 +166,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
166 unsigned int header_len = 0; 166 unsigned int header_len = 0;
167 int data_len = skb->len, ret; 167 int data_len = skb->len, ret;
168 unsigned long brd_delay = 1; 168 unsigned long brd_delay = 1;
169 bool do_bcast = false; 169 bool do_bcast = false, client_added;
170 unsigned short vid; 170 unsigned short vid;
171 uint32_t seqno; 171 uint32_t seqno;
172 172
@@ -196,9 +196,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
196 ethhdr = (struct ethhdr *)skb->data; 196 ethhdr = (struct ethhdr *)skb->data;
197 197
198 /* Register the client MAC in the transtable */ 198 /* Register the client MAC in the transtable */
199 if (!is_multicast_ether_addr(ethhdr->h_source)) 199 if (!is_multicast_ether_addr(ethhdr->h_source)) {
200 batadv_tt_local_add(soft_iface, ethhdr->h_source, vid, 200 client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source,
201 skb->skb_iif); 201 vid, skb->skb_iif);
202 if (!client_added)
203 goto dropped;
204 }
202 205
203 /* don't accept stp packets. STP does not help in meshes. 206 /* don't accept stp packets. STP does not help in meshes.
204 * better use the bridge loop avoidance ... 207 * better use the bridge loop avoidance ...
@@ -674,6 +677,7 @@ static int batadv_softif_init_late(struct net_device *dev)
674 atomic_set(&bat_priv->log_level, 0); 677 atomic_set(&bat_priv->log_level, 0);
675#endif 678#endif
676 atomic_set(&bat_priv->fragmentation, 1); 679 atomic_set(&bat_priv->fragmentation, 1);
680 atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN);
677 atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); 681 atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
678 atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); 682 atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
679 683
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 7731eaed737d..4add57d4857f 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -358,6 +358,13 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
358 goto del; 358 goto del;
359 if (del_op_requested && !del_op_entry) 359 if (del_op_requested && !del_op_entry)
360 goto del; 360 goto del;
361
362 /* this is a second add in the same originator interval. It
363 * means that flags have been changed: update them!
364 */
365 if (!del_op_requested && !del_op_entry)
366 entry->change.flags = flags;
367
361 continue; 368 continue;
362del: 369del:
363 list_del(&entry->list); 370 list_del(&entry->list);
@@ -401,6 +408,35 @@ static uint16_t batadv_tt_entries(uint16_t tt_len)
401 return tt_len / batadv_tt_len(1); 408 return tt_len / batadv_tt_len(1);
402} 409}
403 410
411/**
412 * batadv_tt_local_table_transmit_size - calculates the local translation table
413 * size when transmitted over the air
414 * @bat_priv: the bat priv with all the soft interface information
415 *
416 * Returns local translation table size in bytes.
417 */
418static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
419{
420 uint16_t num_vlan = 0, tt_local_entries = 0;
421 struct batadv_softif_vlan *vlan;
422 int hdr_size;
423
424 rcu_read_lock();
425 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
426 num_vlan++;
427 tt_local_entries += atomic_read(&vlan->tt.num_entries);
428 }
429 rcu_read_unlock();
430
431 /* header size of tvlv encapsulated tt response payload */
432 hdr_size = sizeof(struct batadv_unicast_tvlv_packet);
433 hdr_size += sizeof(struct batadv_tvlv_hdr);
434 hdr_size += sizeof(struct batadv_tvlv_tt_data);
435 hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data);
436
437 return hdr_size + batadv_tt_len(tt_local_entries);
438}
439
404static int batadv_tt_local_init(struct batadv_priv *bat_priv) 440static int batadv_tt_local_init(struct batadv_priv *bat_priv)
405{ 441{
406 if (bat_priv->tt.local_hash) 442 if (bat_priv->tt.local_hash)
@@ -439,17 +475,24 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
439 * @vid: VLAN identifier 475 * @vid: VLAN identifier
440 * @ifindex: index of the interface where the client is connected to (useful to 476 * @ifindex: index of the interface where the client is connected to (useful to
441 * identify wireless clients) 477 * identify wireless clients)
478 *
479 * Returns true if the client was successfully added, false otherwise.
442 */ 480 */
443void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 481bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
444 unsigned short vid, int ifindex) 482 unsigned short vid, int ifindex)
445{ 483{
446 struct batadv_priv *bat_priv = netdev_priv(soft_iface); 484 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
447 struct batadv_tt_local_entry *tt_local; 485 struct batadv_tt_local_entry *tt_local;
448 struct batadv_tt_global_entry *tt_global; 486 struct batadv_tt_global_entry *tt_global;
487 struct net_device *in_dev = NULL;
449 struct hlist_head *head; 488 struct hlist_head *head;
450 struct batadv_tt_orig_list_entry *orig_entry; 489 struct batadv_tt_orig_list_entry *orig_entry;
451 int hash_added; 490 int hash_added, table_size, packet_size_max;
452 bool roamed_back = false; 491 bool ret = false, roamed_back = false;
492 uint8_t remote_flags;
493
494 if (ifindex != BATADV_NULL_IFINDEX)
495 in_dev = dev_get_by_index(&init_net, ifindex);
453 496
454 tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid); 497 tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
455 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid); 498 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
@@ -484,6 +527,17 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
484 goto check_roaming; 527 goto check_roaming;
485 } 528 }
486 529
530 /* Ignore the client if we cannot send it in a full table response. */
531 table_size = batadv_tt_local_table_transmit_size(bat_priv);
532 table_size += batadv_tt_len(1);
533 packet_size_max = atomic_read(&bat_priv->packet_size_max);
534 if (table_size > packet_size_max) {
535 net_ratelimited_function(batadv_info, soft_iface,
536 "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
537 table_size, packet_size_max, addr);
538 goto out;
539 }
540
487 tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC); 541 tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
488 if (!tt_local) 542 if (!tt_local)
489 goto out; 543 goto out;
@@ -500,7 +554,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
500 */ 554 */
501 tt_local->common.flags = BATADV_TT_CLIENT_NEW; 555 tt_local->common.flags = BATADV_TT_CLIENT_NEW;
502 tt_local->common.vid = vid; 556 tt_local->common.vid = vid;
503 if (batadv_is_wifi_iface(ifindex)) 557 if (batadv_is_wifi_netdev(in_dev))
504 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; 558 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
505 atomic_set(&tt_local->common.refcount, 2); 559 atomic_set(&tt_local->common.refcount, 2);
506 tt_local->last_seen = jiffies; 560 tt_local->last_seen = jiffies;
@@ -550,11 +604,31 @@ check_roaming:
550 } 604 }
551 } 605 }
552 606
607 /* store the current remote flags before altering them. This helps
608 * understanding is flags are changing or not
609 */
610 remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
611
612 if (batadv_is_wifi_netdev(in_dev))
613 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
614 else
615 tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
616
617 /* if any "dynamic" flag has been modified, resend an ADD event for this
618 * entry so that all the nodes can get the new flags
619 */
620 if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK))
621 batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
622
623 ret = true;
553out: 624out:
625 if (in_dev)
626 dev_put(in_dev);
554 if (tt_local) 627 if (tt_local)
555 batadv_tt_local_entry_free_ref(tt_local); 628 batadv_tt_local_entry_free_ref(tt_local);
556 if (tt_global) 629 if (tt_global)
557 batadv_tt_global_entry_free_ref(tt_global); 630 batadv_tt_global_entry_free_ref(tt_global);
631 return ret;
558} 632}
559 633
560/** 634/**
@@ -926,8 +1000,16 @@ out:
926 return curr_flags; 1000 return curr_flags;
927} 1001}
928 1002
1003/**
1004 * batadv_tt_local_purge_list - purge inactive tt local entries
1005 * @bat_priv: the bat priv with all the soft interface information
1006 * @head: pointer to the list containing the local tt entries
1007 * @timeout: parameter deciding whether a given tt local entry is considered
1008 * inactive or not
1009 */
929static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, 1010static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
930 struct hlist_head *head) 1011 struct hlist_head *head,
1012 int timeout)
931{ 1013{
932 struct batadv_tt_local_entry *tt_local_entry; 1014 struct batadv_tt_local_entry *tt_local_entry;
933 struct batadv_tt_common_entry *tt_common_entry; 1015 struct batadv_tt_common_entry *tt_common_entry;
@@ -945,8 +1027,7 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
945 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) 1027 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
946 continue; 1028 continue;
947 1029
948 if (!batadv_has_timed_out(tt_local_entry->last_seen, 1030 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
949 BATADV_TT_LOCAL_TIMEOUT))
950 continue; 1031 continue;
951 1032
952 batadv_tt_local_set_pending(bat_priv, tt_local_entry, 1033 batadv_tt_local_set_pending(bat_priv, tt_local_entry,
@@ -954,7 +1035,14 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
954 } 1035 }
955} 1036}
956 1037
957static void batadv_tt_local_purge(struct batadv_priv *bat_priv) 1038/**
1039 * batadv_tt_local_purge - purge inactive tt local entries
1040 * @bat_priv: the bat priv with all the soft interface information
1041 * @timeout: parameter deciding whether a given tt local entry is considered
1042 * inactive or not
1043 */
1044static void batadv_tt_local_purge(struct batadv_priv *bat_priv,
1045 int timeout)
958{ 1046{
959 struct batadv_hashtable *hash = bat_priv->tt.local_hash; 1047 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
960 struct hlist_head *head; 1048 struct hlist_head *head;
@@ -966,7 +1054,7 @@ static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
966 list_lock = &hash->list_locks[i]; 1054 list_lock = &hash->list_locks[i];
967 1055
968 spin_lock_bh(list_lock); 1056 spin_lock_bh(list_lock);
969 batadv_tt_local_purge_list(bat_priv, head); 1057 batadv_tt_local_purge_list(bat_priv, head, timeout);
970 spin_unlock_bh(list_lock); 1058 spin_unlock_bh(list_lock);
971 } 1059 }
972} 1060}
@@ -1280,18 +1368,20 @@ out:
1280} 1368}
1281 1369
1282/* batadv_transtable_best_orig - Get best originator list entry from tt entry 1370/* batadv_transtable_best_orig - Get best originator list entry from tt entry
1371 * @bat_priv: the bat priv with all the soft interface information
1283 * @tt_global_entry: global translation table entry to be analyzed 1372 * @tt_global_entry: global translation table entry to be analyzed
1284 * 1373 *
1285 * This functon assumes the caller holds rcu_read_lock(). 1374 * This functon assumes the caller holds rcu_read_lock().
1286 * Returns best originator list entry or NULL on errors. 1375 * Returns best originator list entry or NULL on errors.
1287 */ 1376 */
1288static struct batadv_tt_orig_list_entry * 1377static struct batadv_tt_orig_list_entry *
1289batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry) 1378batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1379 struct batadv_tt_global_entry *tt_global_entry)
1290{ 1380{
1291 struct batadv_neigh_node *router = NULL; 1381 struct batadv_neigh_node *router, *best_router = NULL;
1382 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
1292 struct hlist_head *head; 1383 struct hlist_head *head;
1293 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL; 1384 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
1294 int best_tq = 0;
1295 1385
1296 head = &tt_global_entry->orig_list; 1386 head = &tt_global_entry->orig_list;
1297 hlist_for_each_entry_rcu(orig_entry, head, list) { 1387 hlist_for_each_entry_rcu(orig_entry, head, list) {
@@ -1299,26 +1389,37 @@ batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
1299 if (!router) 1389 if (!router)
1300 continue; 1390 continue;
1301 1391
1302 if (router->tq_avg > best_tq) { 1392 if (best_router &&
1303 best_entry = orig_entry; 1393 bao->bat_neigh_cmp(router, best_router) <= 0) {
1304 best_tq = router->tq_avg; 1394 batadv_neigh_node_free_ref(router);
1395 continue;
1305 } 1396 }
1306 1397
1307 batadv_neigh_node_free_ref(router); 1398 /* release the refcount for the "old" best */
1399 if (best_router)
1400 batadv_neigh_node_free_ref(best_router);
1401
1402 best_entry = orig_entry;
1403 best_router = router;
1308 } 1404 }
1309 1405
1406 if (best_router)
1407 batadv_neigh_node_free_ref(best_router);
1408
1310 return best_entry; 1409 return best_entry;
1311} 1410}
1312 1411
1313/* batadv_tt_global_print_entry - print all orig nodes who announce the address 1412/* batadv_tt_global_print_entry - print all orig nodes who announce the address
1314 * for this global entry 1413 * for this global entry
1414 * @bat_priv: the bat priv with all the soft interface information
1315 * @tt_global_entry: global translation table entry to be printed 1415 * @tt_global_entry: global translation table entry to be printed
1316 * @seq: debugfs table seq_file struct 1416 * @seq: debugfs table seq_file struct
1317 * 1417 *
1318 * This functon assumes the caller holds rcu_read_lock(). 1418 * This functon assumes the caller holds rcu_read_lock().
1319 */ 1419 */
1320static void 1420static void
1321batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, 1421batadv_tt_global_print_entry(struct batadv_priv *bat_priv,
1422 struct batadv_tt_global_entry *tt_global_entry,
1322 struct seq_file *seq) 1423 struct seq_file *seq)
1323{ 1424{
1324 struct batadv_tt_orig_list_entry *orig_entry, *best_entry; 1425 struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
@@ -1331,7 +1432,7 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
1331 tt_common_entry = &tt_global_entry->common; 1432 tt_common_entry = &tt_global_entry->common;
1332 flags = tt_common_entry->flags; 1433 flags = tt_common_entry->flags;
1333 1434
1334 best_entry = batadv_transtable_best_orig(tt_global_entry); 1435 best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
1335 if (best_entry) { 1436 if (best_entry) {
1336 vlan = batadv_orig_node_vlan_get(best_entry->orig_node, 1437 vlan = batadv_orig_node_vlan_get(best_entry->orig_node,
1337 tt_common_entry->vid); 1438 tt_common_entry->vid);
@@ -1420,7 +1521,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
1420 tt_global = container_of(tt_common_entry, 1521 tt_global = container_of(tt_common_entry,
1421 struct batadv_tt_global_entry, 1522 struct batadv_tt_global_entry,
1422 common); 1523 common);
1423 batadv_tt_global_print_entry(tt_global, seq); 1524 batadv_tt_global_print_entry(bat_priv, tt_global, seq);
1424 } 1525 }
1425 rcu_read_unlock(); 1526 rcu_read_unlock();
1426 } 1527 }
@@ -1808,7 +1909,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1808 goto out; 1909 goto out;
1809 1910
1810 rcu_read_lock(); 1911 rcu_read_lock();
1811 best_entry = batadv_transtable_best_orig(tt_global_entry); 1912 best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
1812 /* found anything? */ 1913 /* found anything? */
1813 if (best_entry) 1914 if (best_entry)
1814 orig_node = best_entry->orig_node; 1915 orig_node = best_entry->orig_node;
@@ -1858,6 +1959,7 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1858 struct batadv_tt_global_entry *tt_global; 1959 struct batadv_tt_global_entry *tt_global;
1859 struct hlist_head *head; 1960 struct hlist_head *head;
1860 uint32_t i, crc_tmp, crc = 0; 1961 uint32_t i, crc_tmp, crc = 0;
1962 uint8_t flags;
1861 1963
1862 for (i = 0; i < hash->size; i++) { 1964 for (i = 0; i < hash->size; i++) {
1863 head = &hash->table[i]; 1965 head = &hash->table[i];
@@ -1896,6 +1998,13 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1896 1998
1897 crc_tmp = crc32c(0, &tt_common->vid, 1999 crc_tmp = crc32c(0, &tt_common->vid,
1898 sizeof(tt_common->vid)); 2000 sizeof(tt_common->vid));
2001
2002 /* compute the CRC on flags that have to be kept in sync
2003 * among nodes
2004 */
2005 flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2006 crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2007
1899 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); 2008 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
1900 } 2009 }
1901 rcu_read_unlock(); 2010 rcu_read_unlock();
@@ -1921,6 +2030,7 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
1921 struct batadv_tt_common_entry *tt_common; 2030 struct batadv_tt_common_entry *tt_common;
1922 struct hlist_head *head; 2031 struct hlist_head *head;
1923 uint32_t i, crc_tmp, crc = 0; 2032 uint32_t i, crc_tmp, crc = 0;
2033 uint8_t flags;
1924 2034
1925 for (i = 0; i < hash->size; i++) { 2035 for (i = 0; i < hash->size; i++) {
1926 head = &hash->table[i]; 2036 head = &hash->table[i];
@@ -1941,6 +2051,13 @@ static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
1941 2051
1942 crc_tmp = crc32c(0, &tt_common->vid, 2052 crc_tmp = crc32c(0, &tt_common->vid,
1943 sizeof(tt_common->vid)); 2053 sizeof(tt_common->vid));
2054
2055 /* compute the CRC on flags that have to be kept in sync
2056 * among nodes
2057 */
2058 flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2059 crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2060
1944 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); 2061 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
1945 } 2062 }
1946 rcu_read_unlock(); 2063 rcu_read_unlock();
@@ -2370,6 +2487,15 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
2370 req_dst_orig_node); 2487 req_dst_orig_node);
2371 } 2488 }
2372 2489
2490 /* Don't send the response, if larger than fragmented packet. */
2491 tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
2492 if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
2493 net_ratelimited_function(batadv_info, bat_priv->soft_iface,
2494 "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
2495 res_dst_orig_node->orig);
2496 goto out;
2497 }
2498
2373 tvlv_tt_data->flags = BATADV_TT_RESPONSE; 2499 tvlv_tt_data->flags = BATADV_TT_RESPONSE;
2374 tvlv_tt_data->ttvn = req_ttvn; 2500 tvlv_tt_data->ttvn = req_ttvn;
2375 2501
@@ -2846,7 +2972,7 @@ static void batadv_tt_purge(struct work_struct *work)
2846 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); 2972 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
2847 bat_priv = container_of(priv_tt, struct batadv_priv, tt); 2973 bat_priv = container_of(priv_tt, struct batadv_priv, tt);
2848 2974
2849 batadv_tt_local_purge(bat_priv); 2975 batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT);
2850 batadv_tt_global_purge(bat_priv); 2976 batadv_tt_global_purge(bat_priv);
2851 batadv_tt_req_purge(bat_priv); 2977 batadv_tt_req_purge(bat_priv);
2852 batadv_tt_roam_purge(bat_priv); 2978 batadv_tt_roam_purge(bat_priv);
@@ -2959,18 +3085,18 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2959} 3085}
2960 3086
2961/** 3087/**
2962 * batadv_tt_local_commit_changes - commit all pending local tt changes which 3088 * batadv_tt_local_commit_changes_nolock - commit all pending local tt changes
2963 * have been queued in the time since the last commit 3089 * which have been queued in the time since the last commit
2964 * @bat_priv: the bat priv with all the soft interface information 3090 * @bat_priv: the bat priv with all the soft interface information
3091 *
3092 * Caller must hold tt->commit_lock.
2965 */ 3093 */
2966void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv) 3094static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
2967{ 3095{
2968 spin_lock_bh(&bat_priv->tt.commit_lock);
2969
2970 if (atomic_read(&bat_priv->tt.local_changes) < 1) { 3096 if (atomic_read(&bat_priv->tt.local_changes) < 1) {
2971 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt)) 3097 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
2972 batadv_tt_tvlv_container_update(bat_priv); 3098 batadv_tt_tvlv_container_update(bat_priv);
2973 goto out; 3099 return;
2974 } 3100 }
2975 3101
2976 batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true); 3102 batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
@@ -2987,8 +3113,17 @@ void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
2987 /* reset the sending counter */ 3113 /* reset the sending counter */
2988 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 3114 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2989 batadv_tt_tvlv_container_update(bat_priv); 3115 batadv_tt_tvlv_container_update(bat_priv);
3116}
2990 3117
2991out: 3118/**
3119 * batadv_tt_local_commit_changes - commit all pending local tt changes which
3120 * have been queued in the time since the last commit
3121 * @bat_priv: the bat priv with all the soft interface information
3122 */
3123void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
3124{
3125 spin_lock_bh(&bat_priv->tt.commit_lock);
3126 batadv_tt_local_commit_changes_nolock(bat_priv);
2992 spin_unlock_bh(&bat_priv->tt.commit_lock); 3127 spin_unlock_bh(&bat_priv->tt.commit_lock);
2993} 3128}
2994 3129
@@ -3184,6 +3319,47 @@ out:
3184} 3319}
3185 3320
3186/** 3321/**
3322 * batadv_tt_local_resize_to_mtu - resize the local translation table fit the
3323 * maximum packet size that can be transported through the mesh
3324 * @soft_iface: netdev struct of the mesh interface
3325 *
3326 * Remove entries older than 'timeout' and half timeout if more entries need
3327 * to be removed.
3328 */
3329void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface)
3330{
3331 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
3332 int packet_size_max = atomic_read(&bat_priv->packet_size_max);
3333 int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
3334 bool reduced = false;
3335
3336 spin_lock_bh(&bat_priv->tt.commit_lock);
3337
3338 while (true) {
3339 table_size = batadv_tt_local_table_transmit_size(bat_priv);
3340 if (packet_size_max >= table_size)
3341 break;
3342
3343 batadv_tt_local_purge(bat_priv, timeout);
3344 batadv_tt_local_purge_pending_clients(bat_priv);
3345
3346 timeout /= 2;
3347 reduced = true;
3348 net_ratelimited_function(batadv_info, soft_iface,
3349 "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
3350 packet_size_max);
3351 }
3352
3353 /* commit these changes immediately, to avoid synchronization problem
3354 * with the TTVN
3355 */
3356 if (reduced)
3357 batadv_tt_local_commit_changes_nolock(bat_priv);
3358
3359 spin_unlock_bh(&bat_priv->tt.commit_lock);
3360}
3361
3362/**
3187 * batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container 3363 * batadv_tt_tvlv_ogm_handler_v1 - process incoming tt tvlv container
3188 * @bat_priv: the bat priv with all the soft interface information 3364 * @bat_priv: the bat priv with all the soft interface information
3189 * @orig: the orig_node of the ogm 3365 * @orig: the orig_node of the ogm
@@ -3364,6 +3540,9 @@ int batadv_tt_init(struct batadv_priv *bat_priv)
3364{ 3540{
3365 int ret; 3541 int ret;
3366 3542
3543 /* synchronized flags must be remote */
3544 BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK));
3545
3367 ret = batadv_tt_local_init(bat_priv); 3546 ret = batadv_tt_local_init(bat_priv);
3368 if (ret < 0) 3547 if (ret < 0)
3369 return ret; 3548 return ret;
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index dc6db4e00a43..026b1ffa6746 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -21,7 +21,7 @@
21#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ 21#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
22 22
23int batadv_tt_init(struct batadv_priv *bat_priv); 23int batadv_tt_init(struct batadv_priv *bat_priv);
24void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, 24bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
25 unsigned short vid, int ifindex); 25 unsigned short vid, int ifindex);
26uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, 26uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
27 const uint8_t *addr, unsigned short vid, 27 const uint8_t *addr, unsigned short vid,
@@ -45,6 +45,7 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
45 uint8_t *addr, unsigned short vid); 45 uint8_t *addr, unsigned short vid);
46bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv, 46bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
47 uint8_t *addr, unsigned short vid); 47 uint8_t *addr, unsigned short vid);
48void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface);
48bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, 49bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
49 struct batadv_orig_node *orig_node, 50 struct batadv_orig_node *orig_node,
50 const unsigned char *addr, 51 const unsigned char *addr,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index ff53933b5a59..91dd369b0ff2 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -36,6 +36,18 @@
36#endif /* CONFIG_BATMAN_ADV_DAT */ 36#endif /* CONFIG_BATMAN_ADV_DAT */
37 37
38/** 38/**
39 * BATADV_TT_REMOTE_MASK - bitmask selecting the flags that are sent over the
40 * wire only
41 */
42#define BATADV_TT_REMOTE_MASK 0x00FF
43
44/**
45 * BATADV_TT_SYNC_MASK - bitmask of the flags that need to be kept in sync
46 * among the nodes. These flags are used to compute the global/local CRC
47 */
48#define BATADV_TT_SYNC_MASK 0x00F0
49
50/**
39 * struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data 51 * struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data
40 * @ogm_buff: buffer holding the OGM packet 52 * @ogm_buff: buffer holding the OGM packet
41 * @ogm_buff_len: length of the OGM packet buffer 53 * @ogm_buff_len: length of the OGM packet buffer
@@ -133,14 +145,28 @@ struct batadv_orig_node_vlan {
133}; 145};
134 146
135/** 147/**
148 * struct batadv_orig_bat_iv - B.A.T.M.A.N. IV private orig_node members
149 * @bcast_own: bitfield containing the number of our OGMs this orig_node
150 * rebroadcasted "back" to us (relative to last_real_seqno)
151 * @bcast_own_sum: counted result of bcast_own
152 * @ogm_cnt_lock: lock protecting bcast_own, bcast_own_sum,
153 * neigh_node->bat_iv.real_bits & neigh_node->bat_iv.real_packet_count
154 */
155struct batadv_orig_bat_iv {
156 unsigned long *bcast_own;
157 uint8_t *bcast_own_sum;
158 /* ogm_cnt_lock protects: bcast_own, bcast_own_sum,
159 * neigh_node->bat_iv.real_bits & neigh_node->bat_iv.real_packet_count
160 */
161 spinlock_t ogm_cnt_lock;
162};
163
164/**
136 * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh 165 * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh
137 * @orig: originator ethernet address 166 * @orig: originator ethernet address
138 * @primary_addr: hosts primary interface address 167 * @primary_addr: hosts primary interface address
139 * @router: router that should be used to reach this originator 168 * @router: router that should be used to reach this originator
140 * @batadv_dat_addr_t: address of the orig node in the distributed hash 169 * @batadv_dat_addr_t: address of the orig node in the distributed hash
141 * @bcast_own: bitfield containing the number of our OGMs this orig_node
142 * rebroadcasted "back" to us (relative to last_real_seqno)
143 * @bcast_own_sum: counted result of bcast_own
144 * @last_seen: time when last packet from this node was received 170 * @last_seen: time when last packet from this node was received
145 * @bcast_seqno_reset: time when the broadcast seqno window was reset 171 * @bcast_seqno_reset: time when the broadcast seqno window was reset
146 * @batman_seqno_reset: time when the batman seqno window was reset 172 * @batman_seqno_reset: time when the batman seqno window was reset
@@ -166,8 +192,6 @@ struct batadv_orig_node_vlan {
166 * @neigh_list_lock: lock protecting neigh_list, router and bonding_list 192 * @neigh_list_lock: lock protecting neigh_list, router and bonding_list
167 * @hash_entry: hlist node for batadv_priv::orig_hash 193 * @hash_entry: hlist node for batadv_priv::orig_hash
168 * @bat_priv: pointer to soft_iface this orig node belongs to 194 * @bat_priv: pointer to soft_iface this orig node belongs to
169 * @ogm_cnt_lock: lock protecting bcast_own, bcast_own_sum,
170 * neigh_node->real_bits & neigh_node->real_packet_count
171 * @bcast_seqno_lock: lock protecting bcast_bits & last_bcast_seqno 195 * @bcast_seqno_lock: lock protecting bcast_bits & last_bcast_seqno
172 * @bond_candidates: how many candidates are available 196 * @bond_candidates: how many candidates are available
173 * @bond_list: list of bonding candidates 197 * @bond_list: list of bonding candidates
@@ -181,6 +205,7 @@ struct batadv_orig_node_vlan {
181 * @vlan_list: a list of orig_node_vlan structs, one per VLAN served by the 205 * @vlan_list: a list of orig_node_vlan structs, one per VLAN served by the
182 * originator represented by this object 206 * originator represented by this object
183 * @vlan_list_lock: lock protecting vlan_list 207 * @vlan_list_lock: lock protecting vlan_list
208 * @bat_iv: B.A.T.M.A.N. IV private structure
184 */ 209 */
185struct batadv_orig_node { 210struct batadv_orig_node {
186 uint8_t orig[ETH_ALEN]; 211 uint8_t orig[ETH_ALEN];
@@ -189,8 +214,6 @@ struct batadv_orig_node {
189#ifdef CONFIG_BATMAN_ADV_DAT 214#ifdef CONFIG_BATMAN_ADV_DAT
190 batadv_dat_addr_t dat_addr; 215 batadv_dat_addr_t dat_addr;
191#endif 216#endif
192 unsigned long *bcast_own;
193 uint8_t *bcast_own_sum;
194 unsigned long last_seen; 217 unsigned long last_seen;
195 unsigned long bcast_seqno_reset; 218 unsigned long bcast_seqno_reset;
196 unsigned long batman_seqno_reset; 219 unsigned long batman_seqno_reset;
@@ -211,10 +234,6 @@ struct batadv_orig_node {
211 spinlock_t neigh_list_lock; 234 spinlock_t neigh_list_lock;
212 struct hlist_node hash_entry; 235 struct hlist_node hash_entry;
213 struct batadv_priv *bat_priv; 236 struct batadv_priv *bat_priv;
214 /* ogm_cnt_lock protects: bcast_own, bcast_own_sum,
215 * neigh_node->real_bits & neigh_node->real_packet_count
216 */
217 spinlock_t ogm_cnt_lock;
218 /* bcast_seqno_lock protects: bcast_bits & last_bcast_seqno */ 237 /* bcast_seqno_lock protects: bcast_bits & last_bcast_seqno */
219 spinlock_t bcast_seqno_lock; 238 spinlock_t bcast_seqno_lock;
220 atomic_t bond_candidates; 239 atomic_t bond_candidates;
@@ -230,6 +249,7 @@ struct batadv_orig_node {
230 struct batadv_frag_table_entry fragments[BATADV_FRAG_BUFFER_COUNT]; 249 struct batadv_frag_table_entry fragments[BATADV_FRAG_BUFFER_COUNT];
231 struct list_head vlan_list; 250 struct list_head vlan_list;
232 spinlock_t vlan_list_lock; /* protects vlan_list */ 251 spinlock_t vlan_list_lock; /* protects vlan_list */
252 struct batadv_orig_bat_iv bat_iv;
233}; 253};
234 254
235/** 255/**
@@ -263,40 +283,49 @@ struct batadv_gw_node {
263}; 283};
264 284
265/** 285/**
266 * struct batadv_neigh_node - structure for single hop neighbors 286 * struct batadv_neigh_bat_iv - B.A.T.M.A.N. IV specific structure for single
267 * @list: list node for batadv_orig_node::neigh_list 287 * hop neighbors
268 * @addr: mac address of neigh node
269 * @tq_recv: ring buffer of received TQ values from this neigh node 288 * @tq_recv: ring buffer of received TQ values from this neigh node
270 * @tq_index: ring buffer index 289 * @tq_index: ring buffer index
271 * @tq_avg: averaged tq of all tq values in the ring buffer (tq_recv) 290 * @tq_avg: averaged tq of all tq values in the ring buffer (tq_recv)
272 * @last_ttl: last received ttl from this neigh node
273 * @bonding_list: list node for batadv_orig_node::bond_list
274 * @last_seen: when last packet via this neighbor was received
275 * @real_bits: bitfield containing the number of OGMs received from this neigh 291 * @real_bits: bitfield containing the number of OGMs received from this neigh
276 * node (relative to orig_node->last_real_seqno) 292 * node (relative to orig_node->last_real_seqno)
277 * @real_packet_count: counted result of real_bits 293 * @real_packet_count: counted result of real_bits
294 * @lq_update_lock: lock protecting tq_recv & tq_index
295 */
296struct batadv_neigh_bat_iv {
297 uint8_t tq_recv[BATADV_TQ_GLOBAL_WINDOW_SIZE];
298 uint8_t tq_index;
299 uint8_t tq_avg;
300 DECLARE_BITMAP(real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
301 uint8_t real_packet_count;
302 spinlock_t lq_update_lock; /* protects tq_recv & tq_index */
303};
304
305/**
306 * struct batadv_neigh_node - structure for single hops neighbors
307 * @list: list node for batadv_orig_node::neigh_list
278 * @orig_node: pointer to corresponding orig_node 308 * @orig_node: pointer to corresponding orig_node
309 * @addr: the MAC address of the neighboring interface
279 * @if_incoming: pointer to incoming hard interface 310 * @if_incoming: pointer to incoming hard interface
280 * @lq_update_lock: lock protecting tq_recv & tq_index 311 * @last_seen: when last packet via this neighbor was received
312 * @last_ttl: last received ttl from this neigh node
313 * @bonding_list: list node for batadv_orig_node::bond_list
281 * @refcount: number of contexts the object is used 314 * @refcount: number of contexts the object is used
282 * @rcu: struct used for freeing in an RCU-safe manner 315 * @rcu: struct used for freeing in an RCU-safe manner
316 * @bat_iv: B.A.T.M.A.N. IV private structure
283 */ 317 */
284struct batadv_neigh_node { 318struct batadv_neigh_node {
285 struct hlist_node list; 319 struct hlist_node list;
320 struct batadv_orig_node *orig_node;
286 uint8_t addr[ETH_ALEN]; 321 uint8_t addr[ETH_ALEN];
287 uint8_t tq_recv[BATADV_TQ_GLOBAL_WINDOW_SIZE]; 322 struct batadv_hard_iface *if_incoming;
288 uint8_t tq_index; 323 unsigned long last_seen;
289 uint8_t tq_avg;
290 uint8_t last_ttl; 324 uint8_t last_ttl;
291 struct list_head bonding_list; 325 struct list_head bonding_list;
292 unsigned long last_seen;
293 DECLARE_BITMAP(real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
294 uint8_t real_packet_count;
295 struct batadv_orig_node *orig_node;
296 struct batadv_hard_iface *if_incoming;
297 spinlock_t lq_update_lock; /* protects tq_recv & tq_index */
298 atomic_t refcount; 326 atomic_t refcount;
299 struct rcu_head rcu; 327 struct rcu_head rcu;
328 struct batadv_neigh_bat_iv bat_iv;
300}; 329};
301 330
302/** 331/**
@@ -595,6 +624,8 @@ struct batadv_softif_vlan {
595 * @aggregated_ogms: bool indicating whether OGM aggregation is enabled 624 * @aggregated_ogms: bool indicating whether OGM aggregation is enabled
596 * @bonding: bool indicating whether traffic bonding is enabled 625 * @bonding: bool indicating whether traffic bonding is enabled
597 * @fragmentation: bool indicating whether traffic fragmentation is enabled 626 * @fragmentation: bool indicating whether traffic fragmentation is enabled
627 * @packet_size_max: max packet size that can be transmitted via
628 * multiple fragmented skbs or a single frame if fragmentation is disabled
598 * @frag_seqno: incremental counter to identify chains of egress fragments 629 * @frag_seqno: incremental counter to identify chains of egress fragments
599 * @bridge_loop_avoidance: bool indicating whether bridge loop avoidance is 630 * @bridge_loop_avoidance: bool indicating whether bridge loop avoidance is
600 * enabled 631 * enabled
@@ -641,6 +672,7 @@ struct batadv_priv {
641 atomic_t aggregated_ogms; 672 atomic_t aggregated_ogms;
642 atomic_t bonding; 673 atomic_t bonding;
643 atomic_t fragmentation; 674 atomic_t fragmentation;
675 atomic_t packet_size_max;
644 atomic_t frag_seqno; 676 atomic_t frag_seqno;
645#ifdef CONFIG_BATMAN_ADV_BLA 677#ifdef CONFIG_BATMAN_ADV_BLA
646 atomic_t bridge_loop_avoidance; 678 atomic_t bridge_loop_avoidance;
@@ -717,7 +749,7 @@ struct batadv_socket_client {
717struct batadv_socket_packet { 749struct batadv_socket_packet {
718 struct list_head list; 750 struct list_head list;
719 size_t icmp_len; 751 size_t icmp_len;
720 struct batadv_icmp_packet_rr icmp_packet; 752 uint8_t icmp_packet[BATADV_ICMP_MAX_PACKET_SIZE];
721}; 753};
722 754
723/** 755/**
@@ -975,6 +1007,16 @@ struct batadv_forw_packet {
975 * @bat_primary_iface_set: called when primary interface is selected / changed 1007 * @bat_primary_iface_set: called when primary interface is selected / changed
976 * @bat_ogm_schedule: prepare a new outgoing OGM for the send queue 1008 * @bat_ogm_schedule: prepare a new outgoing OGM for the send queue
977 * @bat_ogm_emit: send scheduled OGM 1009 * @bat_ogm_emit: send scheduled OGM
1010 * @bat_neigh_cmp: compare the metrics of two neighbors
1011 * @bat_neigh_is_equiv_or_better: check if neigh1 is equally good or
1012 * better than neigh2 from the metric prospective
1013 * @bat_orig_print: print the originator table (optional)
1014 * @bat_orig_free: free the resources allocated by the routing algorithm for an
1015 * orig_node object
1016 * @bat_orig_add_if: ask the routing algorithm to apply the needed changes to
1017 * the orig_node due to a new hard-interface being added into the mesh
1018 * @bat_orig_del_if: ask the routing algorithm to apply the needed changes to
1019 * the orig_node due to an hard-interface being removed from the mesh
978 */ 1020 */
979struct batadv_algo_ops { 1021struct batadv_algo_ops {
980 struct hlist_node list; 1022 struct hlist_node list;
@@ -985,6 +1027,17 @@ struct batadv_algo_ops {
985 void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface); 1027 void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface);
986 void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface); 1028 void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface);
987 void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); 1029 void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
1030 int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
1031 struct batadv_neigh_node *neigh2);
1032 bool (*bat_neigh_is_equiv_or_better)(struct batadv_neigh_node *neigh1,
1033 struct batadv_neigh_node *neigh2);
1034 /* orig_node handling API */
1035 void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq);
1036 void (*bat_orig_free)(struct batadv_orig_node *orig_node);
1037 int (*bat_orig_add_if)(struct batadv_orig_node *orig_node,
1038 int max_if_num);
1039 int (*bat_orig_del_if)(struct batadv_orig_node *orig_node,
1040 int max_if_num, int del_if_num);
988}; 1041};
989 1042
990/** 1043/**