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