]> git.karo-electronics.de Git - karo-tx-linux.git/blob - net/batman-adv/bat_iv_ogm.c
batman-adv: Prefix gateway-client non-static functions with batadv_
[karo-tx-linux.git] / net / batman-adv / bat_iv_ogm.c
1 /*
2  * Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
3  *
4  * Marek Lindner, Simon Wunderlich
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  *
20  */
21
22 #include "main.h"
23 #include "translation-table.h"
24 #include "ring_buffer.h"
25 #include "originator.h"
26 #include "routing.h"
27 #include "gateway_common.h"
28 #include "gateway_client.h"
29 #include "hard-interface.h"
30 #include "send.h"
31 #include "bat_algo.h"
32
33 static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface,
34                                                const uint8_t *neigh_addr,
35                                                struct orig_node *orig_node,
36                                                struct orig_node *orig_neigh,
37                                                __be32 seqno)
38 {
39         struct neigh_node *neigh_node;
40
41         neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr,
42                                            ntohl(seqno));
43         if (!neigh_node)
44                 goto out;
45
46         INIT_LIST_HEAD(&neigh_node->bonding_list);
47
48         neigh_node->orig_node = orig_neigh;
49         neigh_node->if_incoming = hard_iface;
50
51         spin_lock_bh(&orig_node->neigh_list_lock);
52         hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
53         spin_unlock_bh(&orig_node->neigh_list_lock);
54
55 out:
56         return neigh_node;
57 }
58
59 static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface)
60 {
61         struct batman_ogm_packet *batman_ogm_packet;
62         uint32_t random_seqno;
63         int res = -ENOMEM;
64
65         /* randomize initial seqno to avoid collision */
66         get_random_bytes(&random_seqno, sizeof(random_seqno));
67         atomic_set(&hard_iface->seqno, random_seqno);
68
69         hard_iface->packet_len = BATMAN_OGM_HLEN;
70         hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
71
72         if (!hard_iface->packet_buff)
73                 goto out;
74
75         batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
76         batman_ogm_packet->header.packet_type = BAT_IV_OGM;
77         batman_ogm_packet->header.version = COMPAT_VERSION;
78         batman_ogm_packet->header.ttl = 2;
79         batman_ogm_packet->flags = NO_FLAGS;
80         batman_ogm_packet->tq = TQ_MAX_VALUE;
81         batman_ogm_packet->tt_num_changes = 0;
82         batman_ogm_packet->ttvn = 0;
83
84         res = 0;
85
86 out:
87         return res;
88 }
89
90 static void bat_iv_ogm_iface_disable(struct hard_iface *hard_iface)
91 {
92         kfree(hard_iface->packet_buff);
93         hard_iface->packet_buff = NULL;
94 }
95
96 static void bat_iv_ogm_iface_update_mac(struct hard_iface *hard_iface)
97 {
98         struct batman_ogm_packet *batman_ogm_packet;
99
100         batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
101         memcpy(batman_ogm_packet->orig,
102                hard_iface->net_dev->dev_addr, ETH_ALEN);
103         memcpy(batman_ogm_packet->prev_sender,
104                hard_iface->net_dev->dev_addr, ETH_ALEN);
105 }
106
107 static void bat_iv_ogm_primary_iface_set(struct hard_iface *hard_iface)
108 {
109         struct batman_ogm_packet *batman_ogm_packet;
110
111         batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
112         batman_ogm_packet->flags = PRIMARIES_FIRST_HOP;
113         batman_ogm_packet->header.ttl = TTL;
114 }
115
116 /* when do we schedule our own ogm to be sent */
117 static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv)
118 {
119         return jiffies + msecs_to_jiffies(
120                    atomic_read(&bat_priv->orig_interval) -
121                    JITTER + (random32() % 2*JITTER));
122 }
123
124 /* when do we schedule a ogm packet to be sent */
125 static unsigned long bat_iv_ogm_fwd_send_time(void)
126 {
127         return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
128 }
129
130 /* apply hop penalty for a normal link */
131 static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
132 {
133         int hop_penalty = atomic_read(&bat_priv->hop_penalty);
134         return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE);
135 }
136
137 /* is there another aggregated packet here? */
138 static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len,
139                                   int tt_num_changes)
140 {
141         int next_buff_pos = buff_pos + BATMAN_OGM_HLEN + tt_len(tt_num_changes);
142
143         return (next_buff_pos <= packet_len) &&
144                 (next_buff_pos <= MAX_AGGREGATION_BYTES);
145 }
146
147 /* send a batman ogm to a given interface */
148 static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,
149                                   struct hard_iface *hard_iface)
150 {
151         struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
152         char *fwd_str;
153         uint8_t packet_num;
154         int16_t buff_pos;
155         struct batman_ogm_packet *batman_ogm_packet;
156         struct sk_buff *skb;
157
158         if (hard_iface->if_status != IF_ACTIVE)
159                 return;
160
161         packet_num = 0;
162         buff_pos = 0;
163         batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
164
165         /* adjust all flags and log packets */
166         while (bat_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
167                                       batman_ogm_packet->tt_num_changes)) {
168
169                 /* we might have aggregated direct link packets with an
170                  * ordinary base packet */
171                 if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
172                     (forw_packet->if_incoming == hard_iface))
173                         batman_ogm_packet->flags |= DIRECTLINK;
174                 else
175                         batman_ogm_packet->flags &= ~DIRECTLINK;
176
177                 fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
178                                                             "Sending own" :
179                                                             "Forwarding"));
180                 bat_dbg(DBG_BATMAN, bat_priv,
181                         "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
182                         fwd_str, (packet_num > 0 ? "aggregated " : ""),
183                         batman_ogm_packet->orig,
184                         ntohl(batman_ogm_packet->seqno),
185                         batman_ogm_packet->tq, batman_ogm_packet->header.ttl,
186                         (batman_ogm_packet->flags & DIRECTLINK ?
187                          "on" : "off"),
188                         batman_ogm_packet->ttvn, hard_iface->net_dev->name,
189                         hard_iface->net_dev->dev_addr);
190
191                 buff_pos += BATMAN_OGM_HLEN +
192                                 tt_len(batman_ogm_packet->tt_num_changes);
193                 packet_num++;
194                 batman_ogm_packet = (struct batman_ogm_packet *)
195                                         (forw_packet->skb->data + buff_pos);
196         }
197
198         /* create clone because function is called more than once */
199         skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
200         if (skb) {
201                 batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX);
202                 batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES,
203                                    skb->len + ETH_HLEN);
204                 send_skb_packet(skb, hard_iface, broadcast_addr);
205         }
206 }
207
208 /* send a batman ogm packet */
209 static void bat_iv_ogm_emit(struct forw_packet *forw_packet)
210 {
211         struct hard_iface *hard_iface;
212         struct net_device *soft_iface;
213         struct bat_priv *bat_priv;
214         struct hard_iface *primary_if = NULL;
215         struct batman_ogm_packet *batman_ogm_packet;
216         unsigned char directlink;
217
218         batman_ogm_packet = (struct batman_ogm_packet *)
219                                                 (forw_packet->skb->data);
220         directlink = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
221
222         if (!forw_packet->if_incoming) {
223                 pr_err("Error - can't forward packet: incoming iface not specified\n");
224                 goto out;
225         }
226
227         soft_iface = forw_packet->if_incoming->soft_iface;
228         bat_priv = netdev_priv(soft_iface);
229
230         if (forw_packet->if_incoming->if_status != IF_ACTIVE)
231                 goto out;
232
233         primary_if = primary_if_get_selected(bat_priv);
234         if (!primary_if)
235                 goto out;
236
237         /* multihomed peer assumed */
238         /* non-primary OGMs are only broadcasted on their interface */
239         if ((directlink && (batman_ogm_packet->header.ttl == 1)) ||
240             (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
241
242                 /* FIXME: what about aggregated packets ? */
243                 bat_dbg(DBG_BATMAN, bat_priv,
244                         "%s packet (originator %pM, seqno %u, TTL %d) on interface %s [%pM]\n",
245                         (forw_packet->own ? "Sending own" : "Forwarding"),
246                         batman_ogm_packet->orig,
247                         ntohl(batman_ogm_packet->seqno),
248                         batman_ogm_packet->header.ttl,
249                         forw_packet->if_incoming->net_dev->name,
250                         forw_packet->if_incoming->net_dev->dev_addr);
251
252                 /* skb is only used once and than forw_packet is free'd */
253                 send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
254                                 broadcast_addr);
255                 forw_packet->skb = NULL;
256
257                 goto out;
258         }
259
260         /* broadcast on every interface */
261         rcu_read_lock();
262         list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
263                 if (hard_iface->soft_iface != soft_iface)
264                         continue;
265
266                 bat_iv_ogm_send_to_if(forw_packet, hard_iface);
267         }
268         rcu_read_unlock();
269
270 out:
271         if (primary_if)
272                 hardif_free_ref(primary_if);
273 }
274
275 /* return true if new_packet can be aggregated with forw_packet */
276 static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet
277                                                         *new_batman_ogm_packet,
278                                      struct bat_priv *bat_priv,
279                                      int packet_len, unsigned long send_time,
280                                      bool directlink,
281                                      const struct hard_iface *if_incoming,
282                                      const struct forw_packet *forw_packet)
283 {
284         struct batman_ogm_packet *batman_ogm_packet;
285         int aggregated_bytes = forw_packet->packet_len + packet_len;
286         struct hard_iface *primary_if = NULL;
287         bool res = false;
288
289         batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
290
291         /**
292          * we can aggregate the current packet to this aggregated packet
293          * if:
294          *
295          * - the send time is within our MAX_AGGREGATION_MS time
296          * - the resulting packet wont be bigger than
297          *   MAX_AGGREGATION_BYTES
298          */
299
300         if (time_before(send_time, forw_packet->send_time) &&
301             time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
302                                         forw_packet->send_time) &&
303             (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
304
305                 /**
306                  * check aggregation compatibility
307                  * -> direct link packets are broadcasted on
308                  *    their interface only
309                  * -> aggregate packet if the current packet is
310                  *    a "global" packet as well as the base
311                  *    packet
312                  */
313
314                 primary_if = primary_if_get_selected(bat_priv);
315                 if (!primary_if)
316                         goto out;
317
318                 /* packets without direct link flag and high TTL
319                  * are flooded through the net  */
320                 if ((!directlink) &&
321                     (!(batman_ogm_packet->flags & DIRECTLINK)) &&
322                     (batman_ogm_packet->header.ttl != 1) &&
323
324                     /* own packets originating non-primary
325                      * interfaces leave only that interface */
326                     ((!forw_packet->own) ||
327                      (forw_packet->if_incoming == primary_if))) {
328                         res = true;
329                         goto out;
330                 }
331
332                 /* if the incoming packet is sent via this one
333                  * interface only - we still can aggregate */
334                 if ((directlink) &&
335                     (new_batman_ogm_packet->header.ttl == 1) &&
336                     (forw_packet->if_incoming == if_incoming) &&
337
338                     /* packets from direct neighbors or
339                      * own secondary interface packets
340                      * (= secondary interface packets in general) */
341                     (batman_ogm_packet->flags & DIRECTLINK ||
342                      (forw_packet->own &&
343                       forw_packet->if_incoming != primary_if))) {
344                         res = true;
345                         goto out;
346                 }
347         }
348
349 out:
350         if (primary_if)
351                 hardif_free_ref(primary_if);
352         return res;
353 }
354
355 /* create a new aggregated packet and add this packet to it */
356 static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff,
357                                      int packet_len, unsigned long send_time,
358                                      bool direct_link,
359                                      struct hard_iface *if_incoming,
360                                      int own_packet)
361 {
362         struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
363         struct forw_packet *forw_packet_aggr;
364         unsigned char *skb_buff;
365
366         if (!atomic_inc_not_zero(&if_incoming->refcount))
367                 return;
368
369         /* own packet should always be scheduled */
370         if (!own_packet) {
371                 if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
372                         bat_dbg(DBG_BATMAN, bat_priv,
373                                 "batman packet queue full\n");
374                         goto out;
375                 }
376         }
377
378         forw_packet_aggr = kmalloc(sizeof(*forw_packet_aggr), GFP_ATOMIC);
379         if (!forw_packet_aggr) {
380                 if (!own_packet)
381                         atomic_inc(&bat_priv->batman_queue_left);
382                 goto out;
383         }
384
385         if ((atomic_read(&bat_priv->aggregated_ogms)) &&
386             (packet_len < MAX_AGGREGATION_BYTES))
387                 forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
388                                                       ETH_HLEN);
389         else
390                 forw_packet_aggr->skb = dev_alloc_skb(packet_len + ETH_HLEN);
391
392         if (!forw_packet_aggr->skb) {
393                 if (!own_packet)
394                         atomic_inc(&bat_priv->batman_queue_left);
395                 kfree(forw_packet_aggr);
396                 goto out;
397         }
398         skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
399
400         INIT_HLIST_NODE(&forw_packet_aggr->list);
401
402         skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
403         forw_packet_aggr->packet_len = packet_len;
404         memcpy(skb_buff, packet_buff, packet_len);
405
406         forw_packet_aggr->own = own_packet;
407         forw_packet_aggr->if_incoming = if_incoming;
408         forw_packet_aggr->num_packets = 0;
409         forw_packet_aggr->direct_link_flags = NO_FLAGS;
410         forw_packet_aggr->send_time = send_time;
411
412         /* save packet direct link flag status */
413         if (direct_link)
414                 forw_packet_aggr->direct_link_flags |= 1;
415
416         /* add new packet to packet list */
417         spin_lock_bh(&bat_priv->forw_bat_list_lock);
418         hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
419         spin_unlock_bh(&bat_priv->forw_bat_list_lock);
420
421         /* start timer for this packet */
422         INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
423                           send_outstanding_bat_ogm_packet);
424         queue_delayed_work(bat_event_workqueue,
425                            &forw_packet_aggr->delayed_work,
426                            send_time - jiffies);
427
428         return;
429 out:
430         hardif_free_ref(if_incoming);
431 }
432
433 /* aggregate a new packet into the existing ogm packet */
434 static void bat_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr,
435                                  const unsigned char *packet_buff,
436                                  int packet_len, bool direct_link)
437 {
438         unsigned char *skb_buff;
439
440         skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
441         memcpy(skb_buff, packet_buff, packet_len);
442         forw_packet_aggr->packet_len += packet_len;
443         forw_packet_aggr->num_packets++;
444
445         /* save packet direct link flag status */
446         if (direct_link)
447                 forw_packet_aggr->direct_link_flags |=
448                         (1 << forw_packet_aggr->num_packets);
449 }
450
451 static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv,
452                                  unsigned char *packet_buff,
453                                  int packet_len, struct hard_iface *if_incoming,
454                                  int own_packet, unsigned long send_time)
455 {
456         /**
457          * _aggr -> pointer to the packet we want to aggregate with
458          * _pos -> pointer to the position in the queue
459          */
460         struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
461         struct hlist_node *tmp_node;
462         struct batman_ogm_packet *batman_ogm_packet;
463         bool direct_link;
464
465         batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
466         direct_link = batman_ogm_packet->flags & DIRECTLINK ? 1 : 0;
467
468         /* find position for the packet in the forward queue */
469         spin_lock_bh(&bat_priv->forw_bat_list_lock);
470         /* own packets are not to be aggregated */
471         if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
472                 hlist_for_each_entry(forw_packet_pos, tmp_node,
473                                      &bat_priv->forw_bat_list, list) {
474                         if (bat_iv_ogm_can_aggregate(batman_ogm_packet,
475                                                      bat_priv, packet_len,
476                                                      send_time, direct_link,
477                                                      if_incoming,
478                                                      forw_packet_pos)) {
479                                 forw_packet_aggr = forw_packet_pos;
480                                 break;
481                         }
482                 }
483         }
484
485         /* nothing to aggregate with - either aggregation disabled or no
486          * suitable aggregation packet found */
487         if (!forw_packet_aggr) {
488                 /* the following section can run without the lock */
489                 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
490
491                 /**
492                  * if we could not aggregate this packet with one of the others
493                  * we hold it back for a while, so that it might be aggregated
494                  * later on
495                  */
496                 if ((!own_packet) &&
497                     (atomic_read(&bat_priv->aggregated_ogms)))
498                         send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
499
500                 bat_iv_ogm_aggregate_new(packet_buff, packet_len,
501                                          send_time, direct_link,
502                                          if_incoming, own_packet);
503         } else {
504                 bat_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
505                                      packet_len, direct_link);
506                 spin_unlock_bh(&bat_priv->forw_bat_list_lock);
507         }
508 }
509
510 static void bat_iv_ogm_forward(struct orig_node *orig_node,
511                                const struct ethhdr *ethhdr,
512                                struct batman_ogm_packet *batman_ogm_packet,
513                                bool is_single_hop_neigh,
514                                bool is_from_best_next_hop,
515                                struct hard_iface *if_incoming)
516 {
517         struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
518         uint8_t tt_num_changes;
519
520         if (batman_ogm_packet->header.ttl <= 1) {
521                 bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
522                 return;
523         }
524
525         if (!is_from_best_next_hop) {
526                 /* Mark the forwarded packet when it is not coming from our
527                  * best next hop. We still need to forward the packet for our
528                  * neighbor link quality detection to work in case the packet
529                  * originated from a single hop neighbor. Otherwise we can
530                  * simply drop the ogm.
531                  */
532                 if (is_single_hop_neigh)
533                         batman_ogm_packet->flags |= NOT_BEST_NEXT_HOP;
534                 else
535                         return;
536         }
537
538         tt_num_changes = batman_ogm_packet->tt_num_changes;
539
540         batman_ogm_packet->header.ttl--;
541         memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
542
543         /* apply hop penalty */
544         batman_ogm_packet->tq = hop_penalty(batman_ogm_packet->tq, bat_priv);
545
546         bat_dbg(DBG_BATMAN, bat_priv,
547                 "Forwarding packet: tq: %i, ttl: %i\n",
548                 batman_ogm_packet->tq, batman_ogm_packet->header.ttl);
549
550         /* switch of primaries first hop flag when forwarding */
551         batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP;
552         if (is_single_hop_neigh)
553                 batman_ogm_packet->flags |= DIRECTLINK;
554         else
555                 batman_ogm_packet->flags &= ~DIRECTLINK;
556
557         bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
558                              BATMAN_OGM_HLEN + tt_len(tt_num_changes),
559                              if_incoming, 0, bat_iv_ogm_fwd_send_time());
560 }
561
562 static void bat_iv_ogm_schedule(struct hard_iface *hard_iface)
563 {
564         struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
565         struct batman_ogm_packet *batman_ogm_packet;
566         struct hard_iface *primary_if;
567         int vis_server, tt_num_changes = 0;
568
569         vis_server = atomic_read(&bat_priv->vis_mode);
570         primary_if = primary_if_get_selected(bat_priv);
571
572         if (hard_iface == primary_if)
573                 tt_num_changes = batadv_tt_append_diff(bat_priv,
574                                                        &hard_iface->packet_buff,
575                                                        &hard_iface->packet_len,
576                                                        BATMAN_OGM_HLEN);
577
578         batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
579
580         /* change sequence number to network order */
581         batman_ogm_packet->seqno =
582                         htonl((uint32_t)atomic_read(&hard_iface->seqno));
583         atomic_inc(&hard_iface->seqno);
584
585         batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn);
586         batman_ogm_packet->tt_crc = htons(bat_priv->tt_crc);
587         if (tt_num_changes >= 0)
588                 batman_ogm_packet->tt_num_changes = tt_num_changes;
589
590         if (vis_server == VIS_TYPE_SERVER_SYNC)
591                 batman_ogm_packet->flags |= VIS_SERVER;
592         else
593                 batman_ogm_packet->flags &= ~VIS_SERVER;
594
595         if ((hard_iface == primary_if) &&
596             (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER))
597                 batman_ogm_packet->gw_flags =
598                                 (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
599         else
600                 batman_ogm_packet->gw_flags = NO_FLAGS;
601
602         slide_own_bcast_window(hard_iface);
603         bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
604                              hard_iface->packet_len, hard_iface, 1,
605                              bat_iv_ogm_emit_send_time(bat_priv));
606
607         if (primary_if)
608                 hardif_free_ref(primary_if);
609 }
610
611 static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
612                                    struct orig_node *orig_node,
613                                    const struct ethhdr *ethhdr,
614                                    const struct batman_ogm_packet
615                                                         *batman_ogm_packet,
616                                    struct hard_iface *if_incoming,
617                                    const unsigned char *tt_buff,
618                                    int is_duplicate)
619 {
620         struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
621         struct neigh_node *router = NULL;
622         struct orig_node *orig_node_tmp;
623         struct hlist_node *node;
624         uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
625
626         bat_dbg(DBG_BATMAN, bat_priv,
627                 "update_originator(): Searching and updating originator entry of received packet\n");
628
629         rcu_read_lock();
630         hlist_for_each_entry_rcu(tmp_neigh_node, node,
631                                  &orig_node->neigh_list, list) {
632                 if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
633                     (tmp_neigh_node->if_incoming == if_incoming) &&
634                      atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
635                         if (neigh_node)
636                                 neigh_node_free_ref(neigh_node);
637                         neigh_node = tmp_neigh_node;
638                         continue;
639                 }
640
641                 if (is_duplicate)
642                         continue;
643
644                 spin_lock_bh(&tmp_neigh_node->lq_update_lock);
645                 ring_buffer_set(tmp_neigh_node->tq_recv,
646                                 &tmp_neigh_node->tq_index, 0);
647                 tmp_neigh_node->tq_avg =
648                         ring_buffer_avg(tmp_neigh_node->tq_recv);
649                 spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
650         }
651
652         if (!neigh_node) {
653                 struct orig_node *orig_tmp;
654
655                 orig_tmp = get_orig_node(bat_priv, ethhdr->h_source);
656                 if (!orig_tmp)
657                         goto unlock;
658
659                 neigh_node = bat_iv_ogm_neigh_new(if_incoming, ethhdr->h_source,
660                                                   orig_node, orig_tmp,
661                                                   batman_ogm_packet->seqno);
662
663                 orig_node_free_ref(orig_tmp);
664                 if (!neigh_node)
665                         goto unlock;
666         } else
667                 bat_dbg(DBG_BATMAN, bat_priv,
668                         "Updating existing last-hop neighbor of originator\n");
669
670         rcu_read_unlock();
671
672         orig_node->flags = batman_ogm_packet->flags;
673         neigh_node->last_seen = jiffies;
674
675         spin_lock_bh(&neigh_node->lq_update_lock);
676         ring_buffer_set(neigh_node->tq_recv,
677                         &neigh_node->tq_index,
678                         batman_ogm_packet->tq);
679         neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
680         spin_unlock_bh(&neigh_node->lq_update_lock);
681
682         if (!is_duplicate) {
683                 orig_node->last_ttl = batman_ogm_packet->header.ttl;
684                 neigh_node->last_ttl = batman_ogm_packet->header.ttl;
685         }
686
687         bonding_candidate_add(orig_node, neigh_node);
688
689         /* if this neighbor already is our next hop there is nothing
690          * to change */
691         router = orig_node_get_router(orig_node);
692         if (router == neigh_node)
693                 goto update_tt;
694
695         /* if this neighbor does not offer a better TQ we won't consider it */
696         if (router && (router->tq_avg > neigh_node->tq_avg))
697                 goto update_tt;
698
699         /* if the TQ is the same and the link not more symmetric we
700          * won't consider it either */
701         if (router && (neigh_node->tq_avg == router->tq_avg)) {
702                 orig_node_tmp = router->orig_node;
703                 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
704                 bcast_own_sum_orig =
705                         orig_node_tmp->bcast_own_sum[if_incoming->if_num];
706                 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
707
708                 orig_node_tmp = neigh_node->orig_node;
709                 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
710                 bcast_own_sum_neigh =
711                         orig_node_tmp->bcast_own_sum[if_incoming->if_num];
712                 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
713
714                 if (bcast_own_sum_orig >= bcast_own_sum_neigh)
715                         goto update_tt;
716         }
717
718         update_route(bat_priv, orig_node, neigh_node);
719
720 update_tt:
721         /* I have to check for transtable changes only if the OGM has been
722          * sent through a primary interface */
723         if (((batman_ogm_packet->orig != ethhdr->h_source) &&
724              (batman_ogm_packet->header.ttl > 2)) ||
725             (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
726                 tt_update_orig(bat_priv, orig_node, tt_buff,
727                                batman_ogm_packet->tt_num_changes,
728                                batman_ogm_packet->ttvn,
729                                ntohs(batman_ogm_packet->tt_crc));
730
731         if (orig_node->gw_flags != batman_ogm_packet->gw_flags)
732                 batadv_gw_node_update(bat_priv, orig_node,
733                                       batman_ogm_packet->gw_flags);
734
735         orig_node->gw_flags = batman_ogm_packet->gw_flags;
736
737         /* restart gateway selection if fast or late switching was enabled */
738         if ((orig_node->gw_flags) &&
739             (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) &&
740             (atomic_read(&bat_priv->gw_sel_class) > 2))
741                 batadv_gw_check_election(bat_priv, orig_node);
742
743         goto out;
744
745 unlock:
746         rcu_read_unlock();
747 out:
748         if (neigh_node)
749                 neigh_node_free_ref(neigh_node);
750         if (router)
751                 neigh_node_free_ref(router);
752 }
753
754 static int bat_iv_ogm_calc_tq(struct orig_node *orig_node,
755                               struct orig_node *orig_neigh_node,
756                               struct batman_ogm_packet *batman_ogm_packet,
757                               struct hard_iface *if_incoming)
758 {
759         struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
760         struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
761         struct hlist_node *node;
762         uint8_t total_count;
763         uint8_t orig_eq_count, neigh_rq_count, tq_own;
764         int tq_asym_penalty, ret = 0;
765
766         /* find corresponding one hop neighbor */
767         rcu_read_lock();
768         hlist_for_each_entry_rcu(tmp_neigh_node, node,
769                                  &orig_neigh_node->neigh_list, list) {
770
771                 if (!compare_eth(tmp_neigh_node->addr, orig_neigh_node->orig))
772                         continue;
773
774                 if (tmp_neigh_node->if_incoming != if_incoming)
775                         continue;
776
777                 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
778                         continue;
779
780                 neigh_node = tmp_neigh_node;
781                 break;
782         }
783         rcu_read_unlock();
784
785         if (!neigh_node)
786                 neigh_node = bat_iv_ogm_neigh_new(if_incoming,
787                                                   orig_neigh_node->orig,
788                                                   orig_neigh_node,
789                                                   orig_neigh_node,
790                                                   batman_ogm_packet->seqno);
791
792         if (!neigh_node)
793                 goto out;
794
795         /* if orig_node is direct neighbor update neigh_node last_seen */
796         if (orig_node == orig_neigh_node)
797                 neigh_node->last_seen = jiffies;
798
799         orig_node->last_seen = jiffies;
800
801         /* find packet count of corresponding one hop neighbor */
802         spin_lock_bh(&orig_node->ogm_cnt_lock);
803         orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
804         neigh_rq_count = neigh_node->real_packet_count;
805         spin_unlock_bh(&orig_node->ogm_cnt_lock);
806
807         /* pay attention to not get a value bigger than 100 % */
808         total_count = (orig_eq_count > neigh_rq_count ?
809                        neigh_rq_count : orig_eq_count);
810
811         /* if we have too few packets (too less data) we set tq_own to zero */
812         /* if we receive too few packets it is not considered bidirectional */
813         if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
814             (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
815                 tq_own = 0;
816         else
817                 /* neigh_node->real_packet_count is never zero as we
818                  * only purge old information when getting new
819                  * information */
820                 tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count;
821
822         /* 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
823          * affect the nearly-symmetric links only a little, but
824          * punishes asymmetric links more.  This will give a value
825          * between 0 and TQ_MAX_VALUE
826          */
827         tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE *
828                                 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
829                                 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) *
830                                 (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) /
831                                         (TQ_LOCAL_WINDOW_SIZE *
832                                          TQ_LOCAL_WINDOW_SIZE *
833                                          TQ_LOCAL_WINDOW_SIZE);
834
835         batman_ogm_packet->tq = ((batman_ogm_packet->tq * tq_own
836                                                         * tq_asym_penalty) /
837                                                 (TQ_MAX_VALUE * TQ_MAX_VALUE));
838
839         bat_dbg(DBG_BATMAN, bat_priv,
840                 "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n",
841                 orig_node->orig, orig_neigh_node->orig, total_count,
842                 neigh_rq_count, tq_own, tq_asym_penalty, batman_ogm_packet->tq);
843
844         /* if link has the minimum required transmission quality
845          * consider it bidirectional */
846         if (batman_ogm_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
847                 ret = 1;
848
849 out:
850         if (neigh_node)
851                 neigh_node_free_ref(neigh_node);
852         return ret;
853 }
854
855 /* processes a batman packet for all interfaces, adjusts the sequence number and
856  * finds out whether it is a duplicate.
857  * returns:
858  *   1 the packet is a duplicate
859  *   0 the packet has not yet been received
860  *  -1 the packet is old and has been received while the seqno window
861  *     was protected. Caller should drop it.
862  */
863 static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
864                                     const struct batman_ogm_packet
865                                                         *batman_ogm_packet,
866                                     const struct hard_iface *if_incoming)
867 {
868         struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
869         struct orig_node *orig_node;
870         struct neigh_node *tmp_neigh_node;
871         struct hlist_node *node;
872         int is_duplicate = 0;
873         int32_t seq_diff;
874         int need_update = 0;
875         int set_mark, ret = -1;
876         uint32_t seqno = ntohl(batman_ogm_packet->seqno);
877
878         orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
879         if (!orig_node)
880                 return 0;
881
882         spin_lock_bh(&orig_node->ogm_cnt_lock);
883         seq_diff = seqno - orig_node->last_real_seqno;
884
885         /* signalize caller that the packet is to be dropped. */
886         if (!hlist_empty(&orig_node->neigh_list) &&
887             window_protected(bat_priv, seq_diff,
888                              &orig_node->batman_seqno_reset))
889                 goto out;
890
891         rcu_read_lock();
892         hlist_for_each_entry_rcu(tmp_neigh_node, node,
893                                  &orig_node->neigh_list, list) {
894
895                 is_duplicate |= bat_test_bit(tmp_neigh_node->real_bits,
896                                              orig_node->last_real_seqno,
897                                              seqno);
898
899                 if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
900                     (tmp_neigh_node->if_incoming == if_incoming))
901                         set_mark = 1;
902                 else
903                         set_mark = 0;
904
905                 /* if the window moved, set the update flag. */
906                 need_update |= batadv_bit_get_packet(bat_priv,
907                                                      tmp_neigh_node->real_bits,
908                                                      seq_diff, set_mark);
909
910                 tmp_neigh_node->real_packet_count =
911                         bitmap_weight(tmp_neigh_node->real_bits,
912                                       TQ_LOCAL_WINDOW_SIZE);
913         }
914         rcu_read_unlock();
915
916         if (need_update) {
917                 bat_dbg(DBG_BATMAN, bat_priv,
918                         "updating last_seqno: old %u, new %u\n",
919                         orig_node->last_real_seqno, seqno);
920                 orig_node->last_real_seqno = seqno;
921         }
922
923         ret = is_duplicate;
924
925 out:
926         spin_unlock_bh(&orig_node->ogm_cnt_lock);
927         orig_node_free_ref(orig_node);
928         return ret;
929 }
930
931 static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
932                                struct batman_ogm_packet *batman_ogm_packet,
933                                const unsigned char *tt_buff,
934                                struct hard_iface *if_incoming)
935 {
936         struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
937         struct hard_iface *hard_iface;
938         struct orig_node *orig_neigh_node, *orig_node;
939         struct neigh_node *router = NULL, *router_router = NULL;
940         struct neigh_node *orig_neigh_router = NULL;
941         int has_directlink_flag;
942         int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
943         int is_broadcast = 0, is_bidirectional;
944         bool is_single_hop_neigh = false;
945         bool is_from_best_next_hop = false;
946         int is_duplicate;
947         uint32_t if_incoming_seqno;
948
949         /* Silently drop when the batman packet is actually not a
950          * correct packet.
951          *
952          * This might happen if a packet is padded (e.g. Ethernet has a
953          * minimum frame length of 64 byte) and the aggregation interprets
954          * it as an additional length.
955          *
956          * TODO: A more sane solution would be to have a bit in the
957          * batman_ogm_packet to detect whether the packet is the last
958          * packet in an aggregation.  Here we expect that the padding
959          * is always zero (or not 0x01)
960          */
961         if (batman_ogm_packet->header.packet_type != BAT_IV_OGM)
962                 return;
963
964         /* could be changed by schedule_own_packet() */
965         if_incoming_seqno = atomic_read(&if_incoming->seqno);
966
967         has_directlink_flag = (batman_ogm_packet->flags & DIRECTLINK ? 1 : 0);
968
969         if (compare_eth(ethhdr->h_source, batman_ogm_packet->orig))
970                 is_single_hop_neigh = true;
971
972         bat_dbg(DBG_BATMAN, bat_priv,
973                 "Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
974                 ethhdr->h_source, if_incoming->net_dev->name,
975                 if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
976                 batman_ogm_packet->prev_sender, ntohl(batman_ogm_packet->seqno),
977                 batman_ogm_packet->ttvn, ntohs(batman_ogm_packet->tt_crc),
978                 batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
979                 batman_ogm_packet->header.ttl,
980                 batman_ogm_packet->header.version, has_directlink_flag);
981
982         rcu_read_lock();
983         list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
984                 if (hard_iface->if_status != IF_ACTIVE)
985                         continue;
986
987                 if (hard_iface->soft_iface != if_incoming->soft_iface)
988                         continue;
989
990                 if (compare_eth(ethhdr->h_source,
991                                 hard_iface->net_dev->dev_addr))
992                         is_my_addr = 1;
993
994                 if (compare_eth(batman_ogm_packet->orig,
995                                 hard_iface->net_dev->dev_addr))
996                         is_my_orig = 1;
997
998                 if (compare_eth(batman_ogm_packet->prev_sender,
999                                 hard_iface->net_dev->dev_addr))
1000                         is_my_oldorig = 1;
1001
1002                 if (is_broadcast_ether_addr(ethhdr->h_source))
1003                         is_broadcast = 1;
1004         }
1005         rcu_read_unlock();
1006
1007         if (batman_ogm_packet->header.version != COMPAT_VERSION) {
1008                 bat_dbg(DBG_BATMAN, bat_priv,
1009                         "Drop packet: incompatible batman version (%i)\n",
1010                         batman_ogm_packet->header.version);
1011                 return;
1012         }
1013
1014         if (is_my_addr) {
1015                 bat_dbg(DBG_BATMAN, bat_priv,
1016                         "Drop packet: received my own broadcast (sender: %pM)\n",
1017                         ethhdr->h_source);
1018                 return;
1019         }
1020
1021         if (is_broadcast) {
1022                 bat_dbg(DBG_BATMAN, bat_priv,
1023                         "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n",
1024                         ethhdr->h_source);
1025                 return;
1026         }
1027
1028         if (is_my_orig) {
1029                 unsigned long *word;
1030                 int offset;
1031
1032                 orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source);
1033                 if (!orig_neigh_node)
1034                         return;
1035
1036                 /* neighbor has to indicate direct link and it has to
1037                  * come via the corresponding interface */
1038                 /* save packet seqno for bidirectional check */
1039                 if (has_directlink_flag &&
1040                     compare_eth(if_incoming->net_dev->dev_addr,
1041                                 batman_ogm_packet->orig)) {
1042                         offset = if_incoming->if_num * NUM_WORDS;
1043
1044                         spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
1045                         word = &(orig_neigh_node->bcast_own[offset]);
1046                         bat_set_bit(word,
1047                                     if_incoming_seqno -
1048                                         ntohl(batman_ogm_packet->seqno) - 2);
1049                         orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
1050                                 bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE);
1051                         spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
1052                 }
1053
1054                 bat_dbg(DBG_BATMAN, bat_priv,
1055                         "Drop packet: originator packet from myself (via neighbor)\n");
1056                 orig_node_free_ref(orig_neigh_node);
1057                 return;
1058         }
1059
1060         if (is_my_oldorig) {
1061                 bat_dbg(DBG_BATMAN, bat_priv,
1062                         "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n",
1063                         ethhdr->h_source);
1064                 return;
1065         }
1066
1067         if (batman_ogm_packet->flags & NOT_BEST_NEXT_HOP) {
1068                 bat_dbg(DBG_BATMAN, bat_priv,
1069                         "Drop packet: ignoring all packets not forwarded from the best next hop (sender: %pM)\n",
1070                         ethhdr->h_source);
1071                 return;
1072         }
1073
1074         orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
1075         if (!orig_node)
1076                 return;
1077
1078         is_duplicate = bat_iv_ogm_update_seqnos(ethhdr, batman_ogm_packet,
1079                                                 if_incoming);
1080
1081         if (is_duplicate == -1) {
1082                 bat_dbg(DBG_BATMAN, bat_priv,
1083                         "Drop packet: packet within seqno protection time (sender: %pM)\n",
1084                         ethhdr->h_source);
1085                 goto out;
1086         }
1087
1088         if (batman_ogm_packet->tq == 0) {
1089                 bat_dbg(DBG_BATMAN, bat_priv,
1090                         "Drop packet: originator packet with tq equal 0\n");
1091                 goto out;
1092         }
1093
1094         router = orig_node_get_router(orig_node);
1095         if (router)
1096                 router_router = orig_node_get_router(router->orig_node);
1097
1098         if ((router && router->tq_avg != 0) &&
1099             (compare_eth(router->addr, ethhdr->h_source)))
1100                 is_from_best_next_hop = true;
1101
1102         /* avoid temporary routing loops */
1103         if (router && router_router &&
1104             (compare_eth(router->addr, batman_ogm_packet->prev_sender)) &&
1105             !(compare_eth(batman_ogm_packet->orig,
1106                           batman_ogm_packet->prev_sender)) &&
1107             (compare_eth(router->addr, router_router->addr))) {
1108                 bat_dbg(DBG_BATMAN, bat_priv,
1109                         "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n",
1110                         ethhdr->h_source);
1111                 goto out;
1112         }
1113
1114         /* if sender is a direct neighbor the sender mac equals
1115          * originator mac */
1116         orig_neigh_node = (is_single_hop_neigh ?
1117                            orig_node :
1118                            get_orig_node(bat_priv, ethhdr->h_source));
1119         if (!orig_neigh_node)
1120                 goto out;
1121
1122         orig_neigh_router = orig_node_get_router(orig_neigh_node);
1123
1124         /* drop packet if sender is not a direct neighbor and if we
1125          * don't route towards it */
1126         if (!is_single_hop_neigh && (!orig_neigh_router)) {
1127                 bat_dbg(DBG_BATMAN, bat_priv,
1128                         "Drop packet: OGM via unknown neighbor!\n");
1129                 goto out_neigh;
1130         }
1131
1132         is_bidirectional = bat_iv_ogm_calc_tq(orig_node, orig_neigh_node,
1133                                               batman_ogm_packet, if_incoming);
1134
1135         bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
1136
1137         /* update ranking if it is not a duplicate or has the same
1138          * seqno and similar ttl as the non-duplicate */
1139         if (is_bidirectional &&
1140             (!is_duplicate ||
1141              ((orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno)) &&
1142               (orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl))))
1143                 bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
1144                                        batman_ogm_packet, if_incoming,
1145                                        tt_buff, is_duplicate);
1146
1147         /* is single hop (direct) neighbor */
1148         if (is_single_hop_neigh) {
1149
1150                 /* mark direct link on incoming interface */
1151                 bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
1152                                    is_single_hop_neigh, is_from_best_next_hop,
1153                                    if_incoming);
1154
1155                 bat_dbg(DBG_BATMAN, bat_priv,
1156                         "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
1157                 goto out_neigh;
1158         }
1159
1160         /* multihop originator */
1161         if (!is_bidirectional) {
1162                 bat_dbg(DBG_BATMAN, bat_priv,
1163                         "Drop packet: not received via bidirectional link\n");
1164                 goto out_neigh;
1165         }
1166
1167         if (is_duplicate) {
1168                 bat_dbg(DBG_BATMAN, bat_priv,
1169                         "Drop packet: duplicate packet received\n");
1170                 goto out_neigh;
1171         }
1172
1173         bat_dbg(DBG_BATMAN, bat_priv,
1174                 "Forwarding packet: rebroadcast originator packet\n");
1175         bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
1176                            is_single_hop_neigh, is_from_best_next_hop,
1177                            if_incoming);
1178
1179 out_neigh:
1180         if ((orig_neigh_node) && (!is_single_hop_neigh))
1181                 orig_node_free_ref(orig_neigh_node);
1182 out:
1183         if (router)
1184                 neigh_node_free_ref(router);
1185         if (router_router)
1186                 neigh_node_free_ref(router_router);
1187         if (orig_neigh_router)
1188                 neigh_node_free_ref(orig_neigh_router);
1189
1190         orig_node_free_ref(orig_node);
1191 }
1192
1193 static int bat_iv_ogm_receive(struct sk_buff *skb,
1194                               struct hard_iface *if_incoming)
1195 {
1196         struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
1197         struct batman_ogm_packet *batman_ogm_packet;
1198         struct ethhdr *ethhdr;
1199         int buff_pos = 0, packet_len;
1200         unsigned char *tt_buff, *packet_buff;
1201         bool ret;
1202
1203         ret = check_management_packet(skb, if_incoming, BATMAN_OGM_HLEN);
1204         if (!ret)
1205                 return NET_RX_DROP;
1206
1207         /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
1208          * that does not have B.A.T.M.A.N. IV enabled ?
1209          */
1210         if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit)
1211                 return NET_RX_DROP;
1212
1213         batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX);
1214         batadv_add_counter(bat_priv, BAT_CNT_MGMT_RX_BYTES,
1215                            skb->len + ETH_HLEN);
1216
1217         packet_len = skb_headlen(skb);
1218         ethhdr = (struct ethhdr *)skb_mac_header(skb);
1219         packet_buff = skb->data;
1220         batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
1221
1222         /* unpack the aggregated packets and process them one by one */
1223         do {
1224                 tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN;
1225
1226                 bat_iv_ogm_process(ethhdr, batman_ogm_packet,
1227                                    tt_buff, if_incoming);
1228
1229                 buff_pos += BATMAN_OGM_HLEN +
1230                                 tt_len(batman_ogm_packet->tt_num_changes);
1231
1232                 batman_ogm_packet = (struct batman_ogm_packet *)
1233                                                 (packet_buff + buff_pos);
1234         } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len,
1235                                         batman_ogm_packet->tt_num_changes));
1236
1237         kfree_skb(skb);
1238         return NET_RX_SUCCESS;
1239 }
1240
1241 static struct bat_algo_ops batman_iv __read_mostly = {
1242         .name = "BATMAN_IV",
1243         .bat_iface_enable = bat_iv_ogm_iface_enable,
1244         .bat_iface_disable = bat_iv_ogm_iface_disable,
1245         .bat_iface_update_mac = bat_iv_ogm_iface_update_mac,
1246         .bat_primary_iface_set = bat_iv_ogm_primary_iface_set,
1247         .bat_ogm_schedule = bat_iv_ogm_schedule,
1248         .bat_ogm_emit = bat_iv_ogm_emit,
1249 };
1250
1251 int __init batadv_iv_init(void)
1252 {
1253         int ret;
1254
1255         /* batman originator packet */
1256         ret = recv_handler_register(BAT_IV_OGM, bat_iv_ogm_receive);
1257         if (ret < 0)
1258                 goto out;
1259
1260         ret = bat_algo_register(&batman_iv);
1261         if (ret < 0)
1262                 goto handler_unregister;
1263
1264         goto out;
1265
1266 handler_unregister:
1267         recv_handler_unregister(BAT_IV_OGM);
1268 out:
1269         return ret;
1270 }