Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
authorDavid S. Miller <davem@davemloft.net>
Thu, 30 May 2013 22:53:18 +0000 (15:53 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 30 May 2013 22:53:18 +0000 (15:53 -0700)
Included changes:
- reduce broadcast overhead on non-lossy wired links
- fix typos in kernel doc
- use eth_hdr() when possible
- use netdev_allock_skb_ip_align() and don't deal with NET_IP_ALIGN
- change VID semantic in the BLA component
- other minor cleanups and code refactoring

Signed-off-by: David S. Miller <davem@davemloft.net>
24 files changed:
net/batman-adv/Makefile
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/bridge_loop_avoidance.h
net/batman-adv/distributed-arp-table.c
net/batman-adv/hard-interface.c
net/batman-adv/icmp_socket.c
net/batman-adv/main.h
net/batman-adv/network-coding.c
net/batman-adv/network-coding.h
net/batman-adv/originator.c
net/batman-adv/originator.h
net/batman-adv/ring_buffer.c [deleted file]
net/batman-adv/ring_buffer.h [deleted file]
net/batman-adv/routing.c
net/batman-adv/routing.h
net/batman-adv/send.c
net/batman-adv/send.h
net/batman-adv/soft-interface.c
net/batman-adv/translation-table.c
net/batman-adv/translation-table.h
net/batman-adv/types.h
net/batman-adv/unicast.c
net/batman-adv/vis.c

index acbac2a..489bb36 100644 (file)
@@ -32,7 +32,6 @@ batman-adv-y += icmp_socket.o
 batman-adv-y += main.o
 batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o
 batman-adv-y += originator.o
-batman-adv-y += ring_buffer.o
 batman-adv-y += routing.o
 batman-adv-y += send.o
 batman-adv-y += soft-interface.o
index 071f288..d07323b 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "main.h"
 #include "translation-table.h"
-#include "ring_buffer.h"
 #include "originator.h"
 #include "routing.h"
 #include "gateway_common.h"
 #include "bat_algo.h"
 #include "network-coding.h"
 
+/**
+ * batadv_ring_buffer_set - update the ring buffer with the given value
+ * @lq_recv: pointer to the ring buffer
+ * @lq_index: index to store the value at
+ * @value: value to store in the ring buffer
+ */
+static void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
+                                  uint8_t value)
+{
+       lq_recv[*lq_index] = value;
+       *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
+}
+
+/**
+ * batadv_ring_buffer_set - compute the average of all non-zero values stored
+ * in the given ring buffer
+ * @lq_recv: pointer to the ring buffer
+ *
+ * Returns computed average value.
+ */
+static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
+{
+       const uint8_t *ptr;
+       uint16_t count = 0, i = 0, sum = 0;
+
+       ptr = lq_recv;
+
+       while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
+               if (*ptr != 0) {
+                       count++;
+                       sum += *ptr;
+               }
+
+               i++;
+               ptr++;
+       }
+
+       if (count == 0)
+               return 0;
+
+       return (uint8_t)(sum / count);
+}
 static struct batadv_neigh_node *
 batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
                        const uint8_t *neigh_addr,
                        struct batadv_orig_node *orig_node,
-                       struct batadv_orig_node *orig_neigh, __be32 seqno)
+                       struct batadv_orig_node *orig_neigh)
 {
        struct batadv_neigh_node *neigh_node;
 
-       neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr,
-                                          ntohl(seqno));
+       neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr);
        if (!neigh_node)
                goto out;
 
@@ -413,18 +453,16 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
        else
                skb_size = packet_len;
 
-       skb_size += ETH_HLEN + NET_IP_ALIGN;
+       skb_size += ETH_HLEN;
 
-       forw_packet_aggr->skb = dev_alloc_skb(skb_size);
+       forw_packet_aggr->skb = netdev_alloc_skb_ip_align(NULL, skb_size);
        if (!forw_packet_aggr->skb) {
                if (!own_packet)
                        atomic_inc(&bat_priv->batman_queue_left);
                kfree(forw_packet_aggr);
                goto out;
        }
-       skb_reserve(forw_packet_aggr->skb, ETH_HLEN + NET_IP_ALIGN);
-
-       INIT_HLIST_NODE(&forw_packet_aggr->list);
+       skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
 
        skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
        forw_packet_aggr->packet_len = packet_len;
@@ -590,6 +628,41 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
                                if_incoming, 0, batadv_iv_ogm_fwd_send_time());
 }
 
+/**
+ * batadv_iv_ogm_slide_own_bcast_window - bitshift own OGM broadcast windows for
+ * the given interface
+ * @hard_iface: the interface for which the windows have to be shifted
+ */
+static void
+batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
+{
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+       struct hlist_head *head;
+       struct batadv_orig_node *orig_node;
+       unsigned long *word;
+       uint32_t i;
+       size_t word_index;
+       uint8_t *w;
+
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+
+               rcu_read_lock();
+               hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       spin_lock_bh(&orig_node->ogm_cnt_lock);
+                       word_index = hard_iface->if_num * BATADV_NUM_WORDS;
+                       word = &(orig_node->bcast_own[word_index]);
+
+                       batadv_bit_get_packet(bat_priv, word, 1, 0);
+                       w = &orig_node->bcast_own_sum[hard_iface->if_num];
+                       *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
+                       spin_unlock_bh(&orig_node->ogm_cnt_lock);
+               }
+               rcu_read_unlock();
+       }
+}
+
 static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
 {
        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
@@ -634,7 +707,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
                batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
        }
 
-       batadv_slide_own_bcast_window(hard_iface);
+       batadv_iv_ogm_slide_own_bcast_window(hard_iface);
        batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
                                hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
                                batadv_iv_ogm_emit_send_time(bat_priv));
@@ -670,7 +743,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
                    tmp_neigh_node->if_incoming == if_incoming &&
                    atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
-                       if (neigh_node)
+                       if (WARN(neigh_node, "too many matching neigh_nodes"))
                                batadv_neigh_node_free_ref(neigh_node);
                        neigh_node = tmp_neigh_node;
                        continue;
@@ -696,8 +769,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
 
                neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
                                                     ethhdr->h_source,
-                                                    orig_node, orig_tmp,
-                                                    batadv_ogm_packet->seqno);
+                                                    orig_node, orig_tmp);
 
                batadv_orig_node_free_ref(orig_tmp);
                if (!neigh_node)
@@ -829,8 +901,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
                neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
                                                     orig_neigh_node->orig,
                                                     orig_neigh_node,
-                                                    orig_neigh_node,
-                                                    batadv_ogm_packet->seqno);
+                                                    orig_neigh_node);
 
        if (!neigh_node)
                goto out;
@@ -991,7 +1062,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
        struct batadv_neigh_node *orig_neigh_router = NULL;
        int has_directlink_flag;
        int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
-       int is_broadcast = 0, is_bidirect;
+       int is_bidirect;
        bool is_single_hop_neigh = false;
        bool is_from_best_next_hop = false;
        int is_duplicate, sameseq, simlar_ttl;
@@ -1054,19 +1125,9 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
                if (batadv_compare_eth(batadv_ogm_packet->prev_sender,
                                       hard_iface->net_dev->dev_addr))
                        is_my_oldorig = 1;
-
-               if (is_broadcast_ether_addr(ethhdr->h_source))
-                       is_broadcast = 1;
        }
        rcu_read_unlock();
 
-       if (batadv_ogm_packet->header.version != BATADV_COMPAT_VERSION) {
-               batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
-                          "Drop packet: incompatible batman version (%i)\n",
-                          batadv_ogm_packet->header.version);
-               return;
-       }
-
        if (is_my_addr) {
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Drop packet: received my own broadcast (sender: %pM)\n",
@@ -1074,13 +1135,6 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
                return;
        }
 
-       if (is_broadcast) {
-               batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
-                          "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n",
-                          ethhdr->h_source);
-               return;
-       }
-
        if (is_my_orig) {
                unsigned long *word;
                int offset;
@@ -1288,7 +1342,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
                           skb->len + ETH_HLEN);
 
        packet_len = skb_headlen(skb);
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
        packet_buff = skb->data;
        batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
 
index 379061c..e9d8e0b 100644 (file)
@@ -180,7 +180,7 @@ static struct batadv_bla_claim
  */
 static struct batadv_bla_backbone_gw *
 batadv_backbone_hash_find(struct batadv_priv *bat_priv,
-                         uint8_t *addr, short vid)
+                         uint8_t *addr, unsigned short vid)
 {
        struct batadv_hashtable *hash = bat_priv->bla.backbone_hash;
        struct hlist_head *head;
@@ -257,7 +257,7 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
  * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
  */
 static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
-                                 short vid, int claimtype)
+                                 unsigned short vid, int claimtype)
 {
        struct sk_buff *skb;
        struct ethhdr *ethhdr;
@@ -307,7 +307,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                 */
                memcpy(ethhdr->h_source, mac, ETH_ALEN);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
-                          "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid);
+                          "bla_send_claim(): CLAIM %pM on vid %d\n", mac,
+                          BATADV_PRINT_VID(vid));
                break;
        case BATADV_CLAIM_TYPE_UNCLAIM:
                /* unclaim frame
@@ -316,7 +317,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                memcpy(hw_src, mac, ETH_ALEN);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
-                          vid);
+                          BATADV_PRINT_VID(vid));
                break;
        case BATADV_CLAIM_TYPE_ANNOUNCE:
                /* announcement frame
@@ -325,7 +326,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                memcpy(hw_src, mac, ETH_ALEN);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
-                          ethhdr->h_source, vid);
+                          ethhdr->h_source, BATADV_PRINT_VID(vid));
                break;
        case BATADV_CLAIM_TYPE_REQUEST:
                /* request frame
@@ -335,13 +336,15 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac,
                memcpy(hw_src, mac, ETH_ALEN);
                memcpy(ethhdr->h_dest, mac, ETH_ALEN);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
-                          "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n",
-                          ethhdr->h_source, ethhdr->h_dest, vid);
+                          "bla_send_claim(): REQUEST of %pM to %pM on vid %d\n",
+                          ethhdr->h_source, ethhdr->h_dest,
+                          BATADV_PRINT_VID(vid));
                break;
        }
 
-       if (vid != -1)
-               skb = vlan_insert_tag(skb, htons(ETH_P_8021Q), vid);
+       if (vid & BATADV_VLAN_HAS_TAG)
+               skb = vlan_insert_tag(skb, htons(ETH_P_8021Q),
+                                     vid & VLAN_VID_MASK);
 
        skb_reset_mac_header(skb);
        skb->protocol = eth_type_trans(skb, soft_iface);
@@ -367,7 +370,7 @@ out:
  */
 static struct batadv_bla_backbone_gw *
 batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
-                          short vid, bool own_backbone)
+                          unsigned short vid, bool own_backbone)
 {
        struct batadv_bla_backbone_gw *entry;
        struct batadv_orig_node *orig_node;
@@ -380,7 +383,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
 
        batadv_dbg(BATADV_DBG_BLA, bat_priv,
                   "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n",
-                  orig, vid);
+                  orig, BATADV_PRINT_VID(vid));
 
        entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
        if (!entry)
@@ -434,7 +437,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
 static void
 batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
                                  struct batadv_hard_iface *primary_if,
-                                 short vid)
+                                 unsigned short vid)
 {
        struct batadv_bla_backbone_gw *backbone_gw;
 
@@ -456,7 +459,7 @@ batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
  */
 static void batadv_bla_answer_request(struct batadv_priv *bat_priv,
                                      struct batadv_hard_iface *primary_if,
-                                     short vid)
+                                     unsigned short vid)
 {
        struct hlist_head *head;
        struct batadv_hashtable *hash;
@@ -547,7 +550,7 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
  * @backbone_gw: the backbone gateway which claims it
  */
 static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
-                                const uint8_t *mac, const short vid,
+                                const uint8_t *mac, const unsigned short vid,
                                 struct batadv_bla_backbone_gw *backbone_gw)
 {
        struct batadv_bla_claim *claim;
@@ -572,7 +575,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
                atomic_set(&claim->refcount, 2);
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n",
-                          mac, vid);
+                          mac, BATADV_PRINT_VID(vid));
                hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
                                             batadv_compare_claim,
                                             batadv_choose_claim, claim,
@@ -591,7 +594,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
 
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_add_claim(): changing ownership for %pM, vid %d\n",
-                          mac, vid);
+                          mac, BATADV_PRINT_VID(vid));
 
                claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
                batadv_backbone_gw_free_ref(claim->backbone_gw);
@@ -611,7 +614,7 @@ claim_free_ref:
  * given mac address and vid.
  */
 static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
-                                const uint8_t *mac, const short vid)
+                                const uint8_t *mac, const unsigned short vid)
 {
        struct batadv_bla_claim search_claim, *claim;
 
@@ -622,7 +625,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
                return;
 
        batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n",
-                  mac, vid);
+                  mac, BATADV_PRINT_VID(vid));
 
        batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim,
                           batadv_choose_claim, claim);
@@ -637,7 +640,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
 /* check for ANNOUNCE frame, return 1 if handled */
 static int batadv_handle_announce(struct batadv_priv *bat_priv,
                                  uint8_t *an_addr, uint8_t *backbone_addr,
-                                 short vid)
+                                 unsigned short vid)
 {
        struct batadv_bla_backbone_gw *backbone_gw;
        uint16_t crc;
@@ -658,12 +661,13 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv,
 
        batadv_dbg(BATADV_DBG_BLA, bat_priv,
                   "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
-                  vid, backbone_gw->orig, crc);
+                  BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
 
        if (backbone_gw->crc != crc) {
                batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
                           "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
-                          backbone_gw->orig, backbone_gw->vid,
+                          backbone_gw->orig,
+                          BATADV_PRINT_VID(backbone_gw->vid),
                           backbone_gw->crc, crc);
 
                batadv_bla_send_request(backbone_gw);
@@ -685,7 +689,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv,
 static int batadv_handle_request(struct batadv_priv *bat_priv,
                                 struct batadv_hard_iface *primary_if,
                                 uint8_t *backbone_addr,
-                                struct ethhdr *ethhdr, short vid)
+                                struct ethhdr *ethhdr, unsigned short vid)
 {
        /* check for REQUEST frame */
        if (!batadv_compare_eth(backbone_addr, ethhdr->h_dest))
@@ -699,7 +703,7 @@ static int batadv_handle_request(struct batadv_priv *bat_priv,
 
        batadv_dbg(BATADV_DBG_BLA, bat_priv,
                   "handle_request(): REQUEST vid %d (sent by %pM)...\n",
-                  vid, ethhdr->h_source);
+                  BATADV_PRINT_VID(vid), ethhdr->h_source);
 
        batadv_bla_answer_request(bat_priv, primary_if, vid);
        return 1;
@@ -709,7 +713,7 @@ static int batadv_handle_request(struct batadv_priv *bat_priv,
 static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
                                 struct batadv_hard_iface *primary_if,
                                 uint8_t *backbone_addr,
-                                uint8_t *claim_addr, short vid)
+                                uint8_t *claim_addr, unsigned short vid)
 {
        struct batadv_bla_backbone_gw *backbone_gw;
 
@@ -727,7 +731,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
        /* this must be an UNCLAIM frame */
        batadv_dbg(BATADV_DBG_BLA, bat_priv,
                   "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n",
-                  claim_addr, vid, backbone_gw->orig);
+                  claim_addr, BATADV_PRINT_VID(vid), backbone_gw->orig);
 
        batadv_bla_del_claim(bat_priv, claim_addr, vid);
        batadv_backbone_gw_free_ref(backbone_gw);
@@ -738,7 +742,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv,
 static int batadv_handle_claim(struct batadv_priv *bat_priv,
                               struct batadv_hard_iface *primary_if,
                               uint8_t *backbone_addr, uint8_t *claim_addr,
-                              short vid)
+                              unsigned short vid)
 {
        struct batadv_bla_backbone_gw *backbone_gw;
 
@@ -861,14 +865,15 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
        struct batadv_bla_claim_dst *bla_dst;
        uint16_t proto;
        int headlen;
-       short vid = -1;
+       unsigned short vid = BATADV_NO_FLAGS;
        int ret;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
                vhdr = (struct vlan_ethhdr *)ethhdr;
                vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+               vid |= BATADV_VLAN_HAS_TAG;
                proto = ntohs(vhdr->h_vlan_encapsulated_proto);
                headlen = sizeof(*vhdr);
        } else {
@@ -885,7 +890,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
                return 0;
 
        /* pskb_may_pull() may have modified the pointers, get ethhdr again */
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
        arphdr = (struct arphdr *)((uint8_t *)ethhdr + headlen);
 
        /* Check whether the ARP frame carries a valid
@@ -910,7 +915,8 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
        if (ret == 1)
                batadv_dbg(BATADV_DBG_BLA, bat_priv,
                           "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
-                          ethhdr->h_source, vid, hw_src, hw_dst);
+                          ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src,
+                          hw_dst);
 
        if (ret < 2)
                return ret;
@@ -945,7 +951,7 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv,
 
        batadv_dbg(BATADV_DBG_BLA, bat_priv,
                   "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
-                  ethhdr->h_source, vid, hw_src, hw_dst);
+                  ethhdr->h_source, BATADV_PRINT_VID(vid), hw_src, hw_dst);
        return 1;
 }
 
@@ -1358,7 +1364,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
        struct ethhdr *ethhdr;
        struct vlan_ethhdr *vhdr;
        struct batadv_bla_backbone_gw *backbone_gw;
-       short vid = -1;
+       unsigned short vid = BATADV_NO_FLAGS;
 
        if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
                return 0;
@@ -1375,6 +1381,7 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb,
 
                vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size);
                vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+               vid |= BATADV_VLAN_HAS_TAG;
        }
 
        /* see if this originator is a backbone gw for this VLAN */
@@ -1424,15 +1431,15 @@ void batadv_bla_free(struct batadv_priv *bat_priv)
  * returns 1, otherwise it returns 0 and the caller shall further
  * process the skb.
  */
-int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid,
-                 bool is_bcast)
+int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                 unsigned short vid, bool is_bcast)
 {
        struct ethhdr *ethhdr;
        struct batadv_bla_claim search_claim, *claim = NULL;
        struct batadv_hard_iface *primary_if;
        int ret;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        primary_if = batadv_primary_if_get_selected(bat_priv);
        if (!primary_if)
@@ -1519,7 +1526,8 @@ out:
  * returns 1, otherwise it returns 0 and the caller shall further
  * process the skb.
  */
-int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid)
+int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                 unsigned short vid)
 {
        struct ethhdr *ethhdr;
        struct batadv_bla_claim search_claim, *claim = NULL;
@@ -1539,7 +1547,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid)
        if (batadv_bla_process_claim(bat_priv, primary_if, skb))
                goto handled;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
                /* don't allow broadcasts while requests are in flight */
@@ -1623,8 +1631,8 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
                hlist_for_each_entry_rcu(claim, head, hash_entry) {
                        is_own = batadv_compare_eth(claim->backbone_gw->orig,
                                                    primary_addr);
-                       seq_printf(seq, " * %pM on % 5d by %pM [%c] (%#.4x)\n",
-                                  claim->addr, claim->vid,
+                       seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n",
+                                  claim->addr, BATADV_PRINT_VID(claim->vid),
                                   claim->backbone_gw->orig,
                                   (is_own ? 'x' : ' '),
                                   claim->backbone_gw->crc);
@@ -1676,10 +1684,10 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
                        if (is_own)
                                continue;
 
-                       seq_printf(seq,
-                                  " * %pM on % 5d % 4i.%03is (%#.4x)\n",
-                                  backbone_gw->orig, backbone_gw->vid,
-                                  secs, msecs, backbone_gw->crc);
+                       seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n",
+                                  backbone_gw->orig,
+                                  BATADV_PRINT_VID(backbone_gw->vid), secs,
+                                  msecs, backbone_gw->crc);
                }
                rcu_read_unlock();
        }
index dea2fbc..4b102e7 100644 (file)
 #define _NET_BATMAN_ADV_BLA_H_
 
 #ifdef CONFIG_BATMAN_ADV_BLA
-int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid,
-                 bool is_bcast);
-int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid);
+int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                 unsigned short vid, bool is_bcast);
+int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                 unsigned short vid);
 int batadv_bla_is_backbone_gw(struct sk_buff *skb,
                              struct batadv_orig_node *orig_node, int hdr_size);
 int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
@@ -42,13 +43,14 @@ void batadv_bla_free(struct batadv_priv *bat_priv);
 #else /* ifdef CONFIG_BATMAN_ADV_BLA */
 
 static inline int batadv_bla_rx(struct batadv_priv *bat_priv,
-                               struct sk_buff *skb, short vid, bool is_bcast)
+                               struct sk_buff *skb, unsigned short vid,
+                               bool is_bcast)
 {
        return 0;
 }
 
 static inline int batadv_bla_tx(struct batadv_priv *bat_priv,
-                               struct sk_buff *skb, short vid)
+                               struct sk_buff *skb, unsigned short vid)
 {
        return 0;
 }
index 2399920..06345d4 100644 (file)
@@ -45,9 +45,9 @@ static void batadv_dat_start_timer(struct batadv_priv *bat_priv)
 }
 
 /**
- * batadv_dat_entry_free_ref - decrements the dat_entry refcounter and possibly
+ * batadv_dat_entry_free_ref - decrement the dat_entry refcounter and possibly
  * free it
- * @dat_entry: the oentry to free
+ * @dat_entry: the entry to free
  */
 static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry)
 {
@@ -56,10 +56,10 @@ static void batadv_dat_entry_free_ref(struct batadv_dat_entry *dat_entry)
 }
 
 /**
- * batadv_dat_to_purge - checks whether a dat_entry has to be purged or not
+ * batadv_dat_to_purge - check whether a dat_entry has to be purged or not
  * @dat_entry: the entry to check
  *
- * Returns true if the entry has to be purged now, false otherwise
+ * Returns true if the entry has to be purged now, false otherwise.
  */
 static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry)
 {
@@ -75,8 +75,8 @@ static bool batadv_dat_to_purge(struct batadv_dat_entry *dat_entry)
  *           returns a boolean value: true is the entry has to be deleted,
  *           false otherwise
  *
- * Loops over each entry in the DAT local storage and delete it if and only if
- * the to_purge function passed as argument returns true
+ * Loops over each entry in the DAT local storage and deletes it if and only if
+ * the to_purge function passed as argument returns true.
  */
 static void __batadv_dat_purge(struct batadv_priv *bat_priv,
                               bool (*to_purge)(struct batadv_dat_entry *))
@@ -97,7 +97,7 @@ static void __batadv_dat_purge(struct batadv_priv *bat_priv,
                spin_lock_bh(list_lock);
                hlist_for_each_entry_safe(dat_entry, node_tmp, head,
                                          hash_entry) {
-                       /* if an helper function has been passed as parameter,
+                       /* if a helper function has been passed as parameter,
                         * ask it if the entry has to be purged or not
                         */
                        if (to_purge && !to_purge(dat_entry))
@@ -134,7 +134,7 @@ static void batadv_dat_purge(struct work_struct *work)
  * @node: node in the local table
  * @data2: second object to compare the node to
  *
- * Returns 1 if the two entry are the same, 0 otherwise
+ * Returns 1 if the two entries are the same, 0 otherwise.
  */
 static int batadv_compare_dat(const struct hlist_node *node, const void *data2)
 {
@@ -149,7 +149,7 @@ static int batadv_compare_dat(const struct hlist_node *node, const void *data2)
  * @skb: ARP packet
  * @hdr_size: size of the possible header before the ARP packet
  *
- * Returns the value of the hw_src field in the ARP packet
+ * Returns the value of the hw_src field in the ARP packet.
  */
 static uint8_t *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size)
 {
@@ -166,7 +166,7 @@ static uint8_t *batadv_arp_hw_src(struct sk_buff *skb, int hdr_size)
  * @skb: ARP packet
  * @hdr_size: size of the possible header before the ARP packet
  *
- * Returns the value of the ip_src field in the ARP packet
+ * Returns the value of the ip_src field in the ARP packet.
  */
 static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size)
 {
@@ -178,7 +178,7 @@ static __be32 batadv_arp_ip_src(struct sk_buff *skb, int hdr_size)
  * @skb: ARP packet
  * @hdr_size: size of the possible header before the ARP packet
  *
- * Returns the value of the hw_dst field in the ARP packet
+ * Returns the value of the hw_dst field in the ARP packet.
  */
 static uint8_t *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size)
 {
@@ -190,7 +190,7 @@ static uint8_t *batadv_arp_hw_dst(struct sk_buff *skb, int hdr_size)
  * @skb: ARP packet
  * @hdr_size: size of the possible header before the ARP packet
  *
- * Returns the value of the ip_dst field in the ARP packet
+ * Returns the value of the ip_dst field in the ARP packet.
  */
 static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
 {
@@ -202,7 +202,7 @@ static __be32 batadv_arp_ip_dst(struct sk_buff *skb, int hdr_size)
  * @data: data to hash
  * @size: size of the hash table
  *
- * Returns the selected index in the hash table for the given data
+ * Returns the selected index in the hash table for the given data.
  */
 static uint32_t batadv_hash_dat(const void *data, uint32_t size)
 {
@@ -224,12 +224,12 @@ static uint32_t batadv_hash_dat(const void *data, uint32_t size)
 }
 
 /**
- * batadv_dat_entry_hash_find - looks for a given dat_entry in the local hash
+ * batadv_dat_entry_hash_find - look for a given dat_entry in the local hash
  * table
  * @bat_priv: the bat priv with all the soft interface information
  * @ip: search key
  *
- * Returns the dat_entry if found, NULL otherwise
+ * Returns the dat_entry if found, NULL otherwise.
  */
 static struct batadv_dat_entry *
 batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip)
@@ -343,9 +343,6 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
        if (hdr_size == 0)
                return;
 
-       /* if the ARP packet is encapsulated in a batman packet, let's print
-        * some debug messages
-        */
        unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
 
        switch (unicast_4addr_packet->u.header.packet_type) {
@@ -409,7 +406,8 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
  * @candidate: orig_node under evaluation
  * @max_orig_node: last selected candidate
  *
- * Returns true if the node has been elected as next candidate or false othrwise
+ * Returns true if the node has been elected as next candidate or false
+ * otherwise.
  */
 static bool batadv_is_orig_node_eligible(struct batadv_dat_candidate *res,
                                         int select, batadv_dat_addr_t tmp_max,
@@ -472,7 +470,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
         */
        cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND;
 
-       /* iterate over the originator list and find the node with closest
+       /* iterate over the originator list and find the node with the closest
         * dat_address which has not been selected yet
         */
        for (i = 0; i < hash->size; i++) {
@@ -480,7 +478,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
 
                rcu_read_lock();
                hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
-                       /* the dht space is a ring and addresses are unsigned */
+                       /* the dht space is a ring using unsigned addresses */
                        tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr +
                                  ip_key;
 
@@ -512,7 +510,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
 }
 
 /**
- * batadv_dat_select_candidates - selects the nodes which the DHT message has to
+ * batadv_dat_select_candidates - select the nodes which the DHT message has to
  * be sent to
  * @bat_priv: the bat priv with all the soft interface information
  * @ip_dst: ipv4 to look up in the DHT
@@ -521,7 +519,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
  * closest values (from the LEFT, with wrap around if needed) then the hash
  * value of the key. ip_dst is the key.
  *
- * Returns the candidate array of size BATADV_DAT_CANDIDATE_NUM
+ * Returns the candidate array of size BATADV_DAT_CANDIDATE_NUM.
  */
 static struct batadv_dat_candidate *
 batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
@@ -558,10 +556,11 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst)
  * @ip: the DHT key
  * @packet_subtype: unicast4addr packet subtype to use
  *
- * In this function the skb is copied by means of pskb_copy() and is sent as
- * unicast packet to each of the selected candidates
+ * This function copies the skb with pskb_copy() and is sent as unicast packet
+ * to each of the selected candidates.
  *
- * Returns true if the packet is sent to at least one candidate, false otherwise
+ * Returns true if the packet is sent to at least one candidate, false
+ * otherwise.
  */
 static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
                                 struct sk_buff *skb, __be32 ip,
@@ -727,7 +726,7 @@ out:
  * @skb: packet to analyse
  * @hdr_size: size of the possible header before the ARP packet in the skb
  *
- * Returns the ARP type if the skb contains a valid ARP packet, 0 otherwise
+ * Returns the ARP type if the skb contains a valid ARP packet, 0 otherwise.
  */
 static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv,
                                    struct sk_buff *skb, int hdr_size)
@@ -754,9 +753,7 @@ static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv,
 
        arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN);
 
-       /* Check whether the ARP packet carries a valid
-        * IP information
-        */
+       /* check whether the ARP packet carries a valid IP information */
        if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
                goto out;
 
@@ -784,7 +781,7 @@ static uint16_t batadv_arp_get_type(struct batadv_priv *bat_priv,
        if (is_zero_ether_addr(hw_src) || is_multicast_ether_addr(hw_src))
                goto out;
 
-       /* we don't care about the destination MAC address in ARP requests */
+       /* don't care about the destination MAC address in ARP requests */
        if (arphdr->ar_op != htons(ARPOP_REQUEST)) {
                hw_dst = batadv_arp_hw_dst(skb, hdr_size);
                if (is_zero_ether_addr(hw_dst) ||
@@ -804,8 +801,8 @@ out:
  * @skb: packet to check
  *
  * Returns true if the message has been sent to the dht candidates, false
- * otherwise. In case of true the message has to be enqueued to permit the
- * fallback
+ * otherwise. In case of a positive return value the message has to be enqueued
+ * to permit the fallback.
  */
 bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
                                           struct sk_buff *skb)
@@ -867,7 +864,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
                batadv_dbg(BATADV_DBG_DAT, bat_priv, "ARP request replied locally\n");
                ret = true;
        } else {
-               /* Send the request on the DHT */
+               /* Send the request to the DHT */
                ret = batadv_dat_send_data(bat_priv, skb, ip_dst,
                                           BATADV_P_DAT_DHT_GET);
        }
@@ -884,7 +881,7 @@ out:
  * @skb: packet to check
  * @hdr_size: size of the encapsulation header
  *
- * Returns true if the request has been answered, false otherwise
+ * Returns true if the request has been answered, false otherwise.
  */
 bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
                                           struct sk_buff *skb, int hdr_size)
@@ -924,10 +921,9 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
        if (!skb_new)
                goto out;
 
-       /* to preserve backwards compatibility, here the node has to answer
-        * using the same packet type it received for the request. This is due
-        * to that if a node is not using the 4addr packet format it may not
-        * support it.
+       /* To preserve backwards compatibility, the node has choose the outgoing
+        * format based on the incoming request packet type. The assumption is
+        * that a node not using the 4addr packet format doesn't support it.
         */
        if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
                err = batadv_unicast_4addr_send_skb(bat_priv, skb_new,
@@ -977,7 +973,7 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
        batadv_dat_entry_add(bat_priv, ip_dst, hw_dst);
 
        /* Send the ARP reply to the candidates for both the IP addresses that
-        * the node got within the ARP reply
+        * the node obtained from the ARP reply
         */
        batadv_dat_send_data(bat_priv, skb, ip_src, BATADV_P_DAT_DHT_PUT);
        batadv_dat_send_data(bat_priv, skb, ip_dst, BATADV_P_DAT_DHT_PUT);
@@ -987,7 +983,7 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
  * DAT storage only
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: packet to check
- * @hdr_size: siaze of the encapsulation header
+ * @hdr_size: size of the encapsulation header
  */
 bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
                                         struct sk_buff *skb, int hdr_size)
@@ -1031,11 +1027,11 @@ out:
 
 /**
  * batadv_dat_drop_broadcast_packet - check if an ARP request has to be dropped
- * (because the node has already got the reply via DAT) or not
+ * (because the node has already obtained the reply via DAT) or not
  * @bat_priv: the bat priv with all the soft interface information
  * @forw_packet: the broadcast packet
  *
- * Returns true if the node can drop the packet, false otherwise
+ * Returns true if the node can drop the packet, false otherwise.
  */
 bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
                                      struct batadv_forw_packet *forw_packet)
index b6504ea..c478e6b 100644 (file)
@@ -117,6 +117,58 @@ static int batadv_is_valid_iface(const struct net_device *net_dev)
        return 1;
 }
 
+/**
+ * batadv_is_wifi_netdev - check if the given net_device struct is a wifi
+ *  interface
+ * @net_device: the device to check
+ *
+ * Returns true if the net device is a 802.11 wireless device, false otherwise.
+ */
+static bool batadv_is_wifi_netdev(struct net_device *net_device)
+{
+#ifdef CONFIG_WIRELESS_EXT
+       /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
+        * check for wireless_handlers != NULL
+        */
+       if (net_device->wireless_handlers)
+               return true;
+#endif
+
+       /* cfg80211 drivers have to set ieee80211_ptr */
+       if (net_device->ieee80211_ptr)
+               return true;
+
+       return false;
+}
+
+/**
+ * batadv_is_wifi_iface - check if the given interface represented by ifindex
+ *  is a wifi interface
+ * @ifindex: interface index to check
+ *
+ * Returns true if the interface represented by ifindex is a 802.11 wireless
+ * device, false otherwise.
+ */
+bool batadv_is_wifi_iface(int ifindex)
+{
+       struct net_device *net_device = NULL;
+       bool ret = false;
+
+       if (ifindex == BATADV_NULL_IFINDEX)
+               goto out;
+
+       net_device = dev_get_by_index(&init_net, ifindex);
+       if (!net_device)
+               goto out;
+
+       ret = batadv_is_wifi_netdev(net_device);
+
+out:
+       if (net_device)
+               dev_put(net_device);
+       return ret;
+}
+
 static struct batadv_hard_iface *
 batadv_hardif_get_active(const struct net_device *soft_iface)
 {
@@ -525,7 +577,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
 
        dev_hold(net_dev);
 
-       hard_iface = kmalloc(sizeof(*hard_iface), GFP_ATOMIC);
+       hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
        if (!hard_iface)
                goto release_dev;
 
@@ -541,18 +593,16 @@ batadv_hardif_add_interface(struct net_device *net_dev)
        INIT_WORK(&hard_iface->cleanup_work,
                  batadv_hardif_remove_interface_finish);
 
+       hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
+       if (batadv_is_wifi_netdev(net_dev))
+               hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
+
        /* extra reference for return */
        atomic_set(&hard_iface->refcount, 2);
 
        batadv_check_known_mac_addr(hard_iface->net_dev);
        list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
 
-       /* This can't be called via a bat_priv callback because
-        * we have no bat_priv yet.
-        */
-       atomic_set(&hard_iface->bat_iv.ogm_seqno, 1);
-       hard_iface->bat_iv.ogm_buff = NULL;
-
        return hard_iface;
 
 free_if:
@@ -657,38 +707,6 @@ out:
        return NOTIFY_DONE;
 }
 
-/* This function returns true if the interface represented by ifindex is a
- * 802.11 wireless device
- */
-bool batadv_is_wifi_iface(int ifindex)
-{
-       struct net_device *net_device = NULL;
-       bool ret = false;
-
-       if (ifindex == BATADV_NULL_IFINDEX)
-               goto out;
-
-       net_device = dev_get_by_index(&init_net, ifindex);
-       if (!net_device)
-               goto out;
-
-#ifdef CONFIG_WIRELESS_EXT
-       /* pre-cfg80211 drivers have to implement WEXT, so it is possible to
-        * check for wireless_handlers != NULL
-        */
-       if (net_device->wireless_handlers)
-               ret = true;
-       else
-#endif
-               /* cfg80211 drivers have to set ieee80211_ptr */
-               if (net_device->ieee80211_ptr)
-                       ret = true;
-out:
-       if (net_device)
-               dev_put(net_device);
-       return ret;
-}
-
 struct notifier_block batadv_hard_if_notifier = {
        .notifier_call = batadv_hard_if_event,
 };
index 0ba6c89..b27508b 100644 (file)
@@ -177,13 +177,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
        if (len >= sizeof(struct batadv_icmp_packet_rr))
                packet_len = sizeof(struct batadv_icmp_packet_rr);
 
-       skb = dev_alloc_skb(packet_len + ETH_HLEN + NET_IP_ALIGN);
+       skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
        if (!skb) {
                len = -ENOMEM;
                goto out;
        }
 
-       skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
+       skb_reserve(skb, ETH_HLEN);
        icmp_packet = (struct batadv_icmp_packet_rr *)skb_put(skb, packet_len);
 
        if (copy_from_user(icmp_packet, buff, packet_len)) {
index 59a0d6a..5e9aebb 100644 (file)
@@ -26,7 +26,7 @@
 #define BATADV_DRIVER_DEVICE "batman-adv"
 
 #ifndef BATADV_SOURCE_VERSION
-#define BATADV_SOURCE_VERSION "2013.2.0"
+#define BATADV_SOURCE_VERSION "2013.3.0"
 #endif
 
 /* B.A.T.M.A.N. parameters */
 
 #define BATADV_LOG_BUF_LEN 8192          /* has to be a power of 2 */
 
+/* number of packets to send for broadcasts on different interface types */
+#define BATADV_NUM_BCASTS_DEFAULT 1
+#define BATADV_NUM_BCASTS_WIRELESS 3
+#define BATADV_NUM_BCASTS_MAX 3
+
 /* msecs after which an ARP_REQUEST is sent in broadcast as fallback */
 #define ARP_REQ_DELAY 250
 /* numbers of originator to contact for any PUT/GET DHT operation */
@@ -157,6 +162,17 @@ enum batadv_uev_type {
 #include <linux/seq_file.h>
 #include "types.h"
 
+/**
+ * batadv_vlan_flags - flags for the four MSB of any vlan ID field
+ * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
+ */
+enum batadv_vlan_flags {
+       BATADV_VLAN_HAS_TAG     = BIT(15),
+};
+
+#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \
+                              (int)(vid & VLAN_VID_MASK) : -1)
+
 extern char batadv_routing_algo[];
 extern struct list_head batadv_hardif_list;
 
index e84629e..a487d46 100644 (file)
@@ -1245,7 +1245,7 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv,
                return;
 
        /* Set the mac header as if we actually sent the packet uncoded */
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
        memcpy(ethhdr->h_source, ethhdr->h_dest, ETH_ALEN);
        memcpy(ethhdr->h_dest, eth_dst_new, ETH_ALEN);
 
@@ -1359,18 +1359,17 @@ static bool batadv_nc_skb_add_to_path(struct sk_buff *skb,
  *  buffer
  * @skb: data skb to forward
  * @neigh_node: next hop to forward packet to
- * @ethhdr: pointer to the ethernet header inside the skb
  *
  * Returns true if the skb was consumed (encoded packet sent) or false otherwise
  */
 bool batadv_nc_skb_forward(struct sk_buff *skb,
-                          struct batadv_neigh_node *neigh_node,
-                          struct ethhdr *ethhdr)
+                          struct batadv_neigh_node *neigh_node)
 {
        const struct net_device *netdev = neigh_node->if_incoming->soft_iface;
        struct batadv_priv *bat_priv = netdev_priv(netdev);
        struct batadv_unicast_packet *packet;
        struct batadv_nc_path *nc_path;
+       struct ethhdr *ethhdr = eth_hdr(skb);
        __be32 packet_id;
        u8 *payload;
 
@@ -1423,7 +1422,7 @@ void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
 {
        struct batadv_unicast_packet *packet;
        struct batadv_nc_path *nc_path;
-       struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       struct ethhdr *ethhdr = eth_hdr(skb);
        __be32 packet_id;
        u8 *payload;
 
@@ -1482,7 +1481,7 @@ out:
 void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
                                         struct sk_buff *skb)
 {
-       struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       struct ethhdr *ethhdr = eth_hdr(skb);
 
        if (batadv_is_my_mac(bat_priv, ethhdr->h_dest))
                return;
@@ -1533,7 +1532,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
        skb_reset_network_header(skb);
 
        /* Reconstruct original mac header */
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
        memcpy(ethhdr, &ethhdr_tmp, sizeof(*ethhdr));
 
        /* Select the correct unicast header information based on the location
@@ -1677,7 +1676,7 @@ static int batadv_nc_recv_coded_packet(struct sk_buff *skb,
                return NET_RX_DROP;
 
        coded_packet = (struct batadv_coded_packet *)skb->data;
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        /* Verify frame is destined for us */
        if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest) &&
@@ -1763,6 +1762,13 @@ int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset)
                /* For each orig_node in this bin */
                rcu_read_lock();
                hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+                       /* no need to print the orig node if it does not have
+                        * network coding neighbors
+                        */
+                       if (list_empty(&orig_node->in_coding_list) &&
+                           list_empty(&orig_node->out_coding_list))
+                               continue;
+
                        seq_printf(seq, "Node:      %pM\n", orig_node->orig);
 
                        seq_puts(seq, " Ingoing:  ");
index 4fa6d0c..85a4ec8 100644 (file)
@@ -36,8 +36,7 @@ void batadv_nc_purge_orig(struct batadv_priv *bat_priv,
 void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv);
 void batadv_nc_init_orig(struct batadv_orig_node *orig_node);
 bool batadv_nc_skb_forward(struct sk_buff *skb,
-                          struct batadv_neigh_node *neigh_node,
-                          struct ethhdr *ethhdr);
+                          struct batadv_neigh_node *neigh_node);
 void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
                                      struct sk_buff *skb);
 void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
@@ -87,8 +86,7 @@ static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
 }
 
 static inline bool batadv_nc_skb_forward(struct sk_buff *skb,
-                                        struct batadv_neigh_node *neigh_node,
-                                        struct ethhdr *ethhdr)
+                                        struct batadv_neigh_node *neigh_node)
 {
        return false;
 }
index fad1a20..f50553a 100644 (file)
@@ -92,7 +92,7 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
 
 struct batadv_neigh_node *
 batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
-                     const uint8_t *neigh_addr, uint32_t seqno)
+                     const uint8_t *neigh_addr)
 {
        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
        struct batadv_neigh_node *neigh_node;
@@ -110,8 +110,8 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
        atomic_set(&neigh_node->refcount, 2);
 
        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
-                  "Creating new neighbor %pM, initial seqno %d\n",
-                  neigh_addr, seqno);
+                  "Creating new neighbor %pM on interface %s\n", neigh_addr,
+                  hard_iface->net_dev->name);
 
 out:
        return neigh_node;
index 734e5a3..7887b84 100644 (file)
@@ -31,7 +31,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
                                              const uint8_t *addr);
 struct batadv_neigh_node *
 batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
-                     const uint8_t *neigh_addr, uint32_t seqno);
+                     const uint8_t *neigh_addr);
 void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
 struct batadv_neigh_node *
 batadv_orig_node_get_router(struct batadv_orig_node *orig_node);
diff --git a/net/batman-adv/ring_buffer.c b/net/batman-adv/ring_buffer.c
deleted file mode 100644 (file)
index ccab0bb..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- */
-
-#include "main.h"
-#include "ring_buffer.h"
-
-void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
-                           uint8_t value)
-{
-       lq_recv[*lq_index] = value;
-       *lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
-}
-
-uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
-{
-       const uint8_t *ptr;
-       uint16_t count = 0, i = 0, sum = 0;
-
-       ptr = lq_recv;
-
-       while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
-               if (*ptr != 0) {
-                       count++;
-                       sum += *ptr;
-               }
-
-               i++;
-               ptr++;
-       }
-
-       if (count == 0)
-               return 0;
-
-       return (uint8_t)(sum / count);
-}
diff --git a/net/batman-adv/ring_buffer.h b/net/batman-adv/ring_buffer.h
deleted file mode 100644 (file)
index 3f92ae2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- */
-
-#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_
-#define _NET_BATMAN_ADV_RING_BUFFER_H_
-
-void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
-                           uint8_t value);
-uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]);
-
-#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
index b27a4d7..2f0bd3f 100644 (file)
 static int batadv_route_unicast_packet(struct sk_buff *skb,
                                       struct batadv_hard_iface *recv_if);
 
-void batadv_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
-{
-       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
-       struct batadv_hashtable *hash = bat_priv->orig_hash;
-       struct hlist_head *head;
-       struct batadv_orig_node *orig_node;
-       unsigned long *word;
-       uint32_t i;
-       size_t word_index;
-       uint8_t *w;
-
-       for (i = 0; i < hash->size; i++) {
-               head = &hash->table[i];
-
-               rcu_read_lock();
-               hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
-                       spin_lock_bh(&orig_node->ogm_cnt_lock);
-                       word_index = hard_iface->if_num * BATADV_NUM_WORDS;
-                       word = &(orig_node->bcast_own[word_index]);
-
-                       batadv_bit_get_packet(bat_priv, word, 1, 0);
-                       w = &orig_node->bcast_own_sum[hard_iface->if_num];
-                       *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
-                       spin_unlock_bh(&orig_node->ogm_cnt_lock);
-               }
-               rcu_read_unlock();
-       }
-}
-
 static void _batadv_update_route(struct batadv_priv *bat_priv,
                                 struct batadv_orig_node *orig_node,
                                 struct batadv_neigh_node *neigh_node)
@@ -256,7 +227,7 @@ bool batadv_check_management_packet(struct sk_buff *skb,
        if (unlikely(!pskb_may_pull(skb, header_len)))
                return false;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        /* packet with broadcast indication but unicast recipient */
        if (!is_broadcast_ether_addr(ethhdr->h_dest))
@@ -314,7 +285,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
        icmp_packet->msg_type = BATADV_ECHO_REPLY;
        icmp_packet->header.ttl = BATADV_TTL;
 
-       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = NET_RX_SUCCESS;
 
 out:
@@ -362,7 +333,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
        icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
        icmp_packet->header.ttl = BATADV_TTL;
 
-       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = NET_RX_SUCCESS;
 
 out:
@@ -392,7 +363,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        if (unlikely(!pskb_may_pull(skb, hdr_size)))
                goto out;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        /* packet with unicast indication but broadcast recipient */
        if (is_broadcast_ether_addr(ethhdr->h_dest))
@@ -439,7 +410,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        icmp_packet->header.ttl--;
 
        /* route it */
-       if (batadv_send_skb_to_orig(skb, orig_node, recv_if))
+       if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
                ret = NET_RX_SUCCESS;
 
 out:
@@ -569,7 +540,7 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
        if (unlikely(!pskb_may_pull(skb, hdr_size)))
                return -ENODATA;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        /* packet with unicast indication but broadcast recipient */
        if (is_broadcast_ether_addr(ethhdr->h_dest))
@@ -803,8 +774,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
        struct batadv_orig_node *orig_node = NULL;
        struct batadv_neigh_node *neigh_node = NULL;
        struct batadv_unicast_packet *unicast_packet;
-       struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
-       int ret = NET_RX_DROP;
+       struct ethhdr *ethhdr = eth_hdr(skb);
+       int res, ret = NET_RX_DROP;
        struct sk_buff *new_skb;
 
        unicast_packet = (struct batadv_unicast_packet *)skb->data;
@@ -864,16 +835,19 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
        /* decrement ttl */
        unicast_packet->header.ttl--;
 
-       /* network code packet if possible */
-       if (batadv_nc_skb_forward(skb, neigh_node, ethhdr)) {
-               ret = NET_RX_SUCCESS;
-       } else if (batadv_send_skb_to_orig(skb, orig_node, recv_if)) {
-               ret = NET_RX_SUCCESS;
+       res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
 
-               /* Update stats counter */
+       /* translate transmit result into receive result */
+       if (res == NET_XMIT_SUCCESS) {
+               /* skb was transmitted and consumed */
                batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
                batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
                                   skb->len + ETH_HLEN);
+
+               ret = NET_RX_SUCCESS;
+       } else if (res == NET_XMIT_POLICED) {
+               /* skb was buffered and consumed */
+               ret = NET_RX_SUCCESS;
        }
 
 out:
@@ -1165,7 +1139,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
        if (unlikely(!pskb_may_pull(skb, hdr_size)))
                goto out;
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        /* packet with broadcast indication but unicast recipient */
        if (!is_broadcast_ether_addr(ethhdr->h_dest))
@@ -1265,7 +1239,7 @@ int batadv_recv_vis_packet(struct sk_buff *skb,
                return NET_RX_DROP;
 
        vis_packet = (struct batadv_vis_packet *)skb->data;
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        /* not for me */
        if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
index 99eeafa..72a29bd 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef _NET_BATMAN_ADV_ROUTING_H_
 #define _NET_BATMAN_ADV_ROUTING_H_
 
-void batadv_slide_own_bcast_window(struct batadv_hard_iface *hard_iface);
 bool batadv_check_management_packet(struct sk_buff *skb,
                                    struct batadv_hard_iface *hard_iface,
                                    int header_len);
index 263cfd1..e9ff8d8 100644 (file)
@@ -61,7 +61,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
 
        skb_reset_mac_header(skb);
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
        memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN);
        memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
        ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
@@ -96,26 +96,37 @@ send_skb_err:
  * host, NULL can be passed as recv_if and no interface alternating is
  * attempted.
  *
- * Returns TRUE on success; FALSE otherwise.
+ * Returns NET_XMIT_SUCCESS on success, NET_XMIT_DROP on failure, or
+ * NET_XMIT_POLICED if the skb is buffered for later transmit.
  */
-bool batadv_send_skb_to_orig(struct sk_buff *skb,
-                            struct batadv_orig_node *orig_node,
-                            struct batadv_hard_iface *recv_if)
+int batadv_send_skb_to_orig(struct sk_buff *skb,
+                           struct batadv_orig_node *orig_node,
+                           struct batadv_hard_iface *recv_if)
 {
        struct batadv_priv *bat_priv = orig_node->bat_priv;
        struct batadv_neigh_node *neigh_node;
+       int ret = NET_XMIT_DROP;
 
        /* batadv_find_router() increases neigh_nodes refcount if found. */
        neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
        if (!neigh_node)
-               return false;
+               return ret;
 
-       /* route it */
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+       /* try to network code the packet, if it is received on an interface
+        * (i.e. being forwarded). If the packet originates from this node or if
+        * network coding fails, then send the packet as usual.
+        */
+       if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) {
+               ret = NET_XMIT_POLICED;
+       } else {
+               batadv_send_skb_packet(skb, neigh_node->if_incoming,
+                                      neigh_node->addr);
+               ret = NET_XMIT_SUCCESS;
+       }
 
        batadv_neigh_node_free_ref(neigh_node);
 
-       return true;
+       return ret;
 }
 
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
@@ -152,8 +163,6 @@ _batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
                                 struct batadv_forw_packet *forw_packet,
                                 unsigned long send_time)
 {
-       INIT_HLIST_NODE(&forw_packet->list);
-
        /* add new packet to packet list */
        spin_lock_bh(&bat_priv->forw_bcast_list_lock);
        hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list);
@@ -260,6 +269,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
                if (hard_iface->soft_iface != soft_iface)
                        continue;
 
+               if (forw_packet->num_packets >= hard_iface->num_bcasts)
+                       continue;
+
                /* send a copy of the saved skb */
                skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
                if (skb1)
@@ -271,7 +283,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
        forw_packet->num_packets++;
 
        /* if we still have some more bcasts to send */
-       if (forw_packet->num_packets < 3) {
+       if (forw_packet->num_packets < BATADV_NUM_BCASTS_MAX) {
                _batadv_add_bcast_packet_to_list(bat_priv, forw_packet,
                                                 msecs_to_jiffies(5));
                return;
index 38e662f..e7b1788 100644 (file)
@@ -23,9 +23,9 @@
 int batadv_send_skb_packet(struct sk_buff *skb,
                           struct batadv_hard_iface *hard_iface,
                           const uint8_t *dst_addr);
-bool batadv_send_skb_to_orig(struct sk_buff *skb,
-                            struct batadv_orig_node *orig_node,
-                            struct batadv_hard_iface *recv_if);
+int batadv_send_skb_to_orig(struct sk_buff *skb,
+                           struct batadv_orig_node *orig_node,
+                           struct batadv_hard_iface *recv_if);
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
 int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
                                    const struct sk_buff *skb,
index 819dfb0..700d0b4 100644 (file)
@@ -154,7 +154,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
                                                    0x00, 0x00};
        unsigned int header_len = 0;
        int data_len = skb->len, ret;
-       short vid __maybe_unused = -1;
+       unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
        bool do_bcast = false;
        uint32_t seqno;
        unsigned long brd_delay = 1;
@@ -303,7 +303,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
        struct ethhdr *ethhdr;
        struct vlan_ethhdr *vhdr;
        struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
-       short vid __maybe_unused = -1;
+       unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
        __be16 ethertype = __constant_htons(ETH_P_BATMAN);
        bool is_bcast;
 
@@ -316,7 +316,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
        skb_pull_rcsum(skb, hdr_size);
        skb_reset_mac_header(skb);
 
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       ethhdr = eth_hdr(skb);
 
        switch (ntohs(ethhdr->h_proto)) {
        case ETH_P_8021Q:
index 9e87485..429aeef 100644 (file)
@@ -163,10 +163,19 @@ batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
        call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
 }
 
+/**
+ * batadv_tt_local_event - store a local TT event (ADD/DEL)
+ * @bat_priv: the bat priv with all the soft interface information
+ * @tt_local_entry: the TT entry involved in the event
+ * @event_flags: flags to store in the event structure
+ */
 static void batadv_tt_local_event(struct batadv_priv *bat_priv,
-                                 const uint8_t *addr, uint8_t flags)
+                                 struct batadv_tt_local_entry *tt_local_entry,
+                                 uint8_t event_flags)
 {
        struct batadv_tt_change_node *tt_change_node, *entry, *safe;
+       struct batadv_tt_common_entry *common = &tt_local_entry->common;
+       uint8_t flags = common->flags | event_flags;
        bool event_removed = false;
        bool del_op_requested, del_op_entry;
 
@@ -176,7 +185,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
                return;
 
        tt_change_node->change.flags = flags;
-       memcpy(tt_change_node->change.addr, addr, ETH_ALEN);
+       memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
 
        del_op_requested = flags & BATADV_TT_CLIENT_DEL;
 
@@ -184,7 +193,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
        spin_lock_bh(&bat_priv->tt.changes_list_lock);
        list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
                                 list) {
-               if (!batadv_compare_eth(entry->change.addr, addr))
+               if (!batadv_compare_eth(entry->change.addr, common->addr))
                        continue;
 
                /* DEL+ADD in the same orig interval have no effect and can be
@@ -332,7 +341,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
        }
 
 add_event:
-       batadv_tt_local_event(bat_priv, addr, tt_local->common.flags);
+       batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
 
 check_roaming:
        /* Check whether it is a roaming, but don't do anything if the roaming
@@ -529,8 +538,7 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
                            struct batadv_tt_local_entry *tt_local_entry,
                            uint16_t flags, const char *message)
 {
-       batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
-                             tt_local_entry->common.flags | flags);
+       batadv_tt_local_event(bat_priv, tt_local_entry, flags);
 
        /* The local client has to be marked as "pending to be removed" but has
         * to be kept in the table in order to send it in a full table
@@ -584,8 +592,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
        /* if this client has been added right now, it is possible to
         * immediately purge it
         */
-       batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
-                             curr_flags | BATADV_TT_CLIENT_DEL);
+       batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
        hlist_del_rcu(&tt_local_entry->common.hash_entry);
        batadv_tt_local_entry_free_ref(tt_local_entry);
 
@@ -791,10 +798,25 @@ out:
                batadv_tt_orig_list_entry_free_ref(orig_entry);
 }
 
-/* caller must hold orig_node refcount */
+/**
+ * batadv_tt_global_add - add a new TT global entry or update an existing one
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig_node: the originator announcing the client
+ * @tt_addr: the mac address of the non-mesh client
+ * @flags: TT flags that have to be set for this non-mesh client
+ * @ttvn: the tt version number ever announcing this non-mesh client
+ *
+ * Add a new TT global entry for the given originator. If the entry already
+ * exists add a new reference to the given originator (a global entry can have
+ * references to multiple originators) and adjust the flags attribute to reflect
+ * the function argument.
+ * If a TT local entry exists for this non-mesh client remove it.
+ *
+ * The caller must hold orig_node refcount.
+ */
 int batadv_tt_global_add(struct batadv_priv *bat_priv,
                         struct batadv_orig_node *orig_node,
-                        const unsigned char *tt_addr, uint8_t flags,
+                        const unsigned char *tt_addr, uint16_t flags,
                         uint8_t ttvn)
 {
        struct batadv_tt_global_entry *tt_global_entry;
@@ -1600,11 +1622,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn,
        tt_tot = tt_len / sizeof(struct batadv_tt_change);
 
        len = tt_query_size + tt_len;
-       skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
+       skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
        if (!skb)
                goto out;
 
-       skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
+       skb_reserve(skb, ETH_HLEN);
        tt_response = (struct batadv_tt_query_packet *)skb_put(skb, len);
        tt_response->ttvn = ttvn;
 
@@ -1665,11 +1687,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
        if (!tt_req_node)
                goto out;
 
-       skb = dev_alloc_skb(sizeof(*tt_request) + ETH_HLEN + NET_IP_ALIGN);
+       skb = netdev_alloc_skb_ip_align(NULL, sizeof(*tt_request) + ETH_HLEN);
        if (!skb)
                goto out;
 
-       skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
+       skb_reserve(skb, ETH_HLEN);
 
        tt_req_len = sizeof(*tt_request);
        tt_request = (struct batadv_tt_query_packet *)skb_put(skb, tt_req_len);
@@ -1691,7 +1713,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
 
-       if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL) != NET_XMIT_DROP)
                ret = 0;
 
 out:
@@ -1715,7 +1737,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
        struct batadv_orig_node *req_dst_orig_node;
        struct batadv_orig_node *res_dst_orig_node = NULL;
        uint8_t orig_ttvn, req_ttvn, ttvn;
-       int ret = false;
+       int res, ret = false;
        unsigned char *tt_buff;
        bool full_table;
        uint16_t tt_len, tt_tot;
@@ -1762,11 +1784,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
                tt_tot = tt_len / sizeof(struct batadv_tt_change);
 
                len = sizeof(*tt_response) + tt_len;
-               skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
+               skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
                if (!skb)
                        goto unlock;
 
-               skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
+               skb_reserve(skb, ETH_HLEN);
                packet_pos = skb_put(skb, len);
                tt_response = (struct batadv_tt_query_packet *)packet_pos;
                tt_response->ttvn = req_ttvn;
@@ -1810,8 +1832,10 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
 
-       if (batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL))
+       res = batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL);
+       if (res != NET_XMIT_DROP)
                ret = true;
+
        goto out;
 
 unlock:
@@ -1878,11 +1902,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
                tt_tot = tt_len / sizeof(struct batadv_tt_change);
 
                len = sizeof(*tt_response) + tt_len;
-               skb = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
+               skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
                if (!skb)
                        goto unlock;
 
-               skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
+               skb_reserve(skb, ETH_HLEN);
                packet_pos = skb_put(skb, len);
                tt_response = (struct batadv_tt_query_packet *)packet_pos;
                tt_response->ttvn = req_ttvn;
@@ -1925,7 +1949,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
 
-       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = true;
        goto out;
 
@@ -2212,11 +2236,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
        if (!batadv_tt_check_roam_count(bat_priv, client))
                goto out;
 
-       skb = dev_alloc_skb(sizeof(*roam_adv_packet) + ETH_HLEN + NET_IP_ALIGN);
+       skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
        if (!skb)
                goto out;
 
-       skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN);
+       skb_reserve(skb, ETH_HLEN);
 
        roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
 
@@ -2238,7 +2262,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
 
-       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = 0;
 
 out:
index ab8e683..659a3bb 100644 (file)
@@ -33,7 +33,7 @@ void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
                               const unsigned char *tt_buff, int tt_buff_len);
 int batadv_tt_global_add(struct batadv_priv *bat_priv,
                         struct batadv_orig_node *orig_node,
-                        const unsigned char *addr, uint8_t flags,
+                        const unsigned char *addr, uint16_t flags,
                         uint8_t ttvn);
 int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
 void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
index aba8364..b2c94e1 100644 (file)
@@ -61,6 +61,7 @@ struct batadv_hard_iface_bat_iv {
  * @if_status: status of the interface for batman-adv
  * @net_dev: pointer to the net_device
  * @frag_seqno: last fragment sequence number sent by this interface
+ * @num_bcasts: number of payload re-broadcasts on this interface (ARQ)
  * @hardif_obj: kobject of the per interface sysfs "mesh" directory
  * @refcount: number of contexts the object is used
  * @batman_adv_ptype: packet type describing packets that should be processed by
@@ -76,6 +77,7 @@ struct batadv_hard_iface {
        char if_status;
        struct net_device *net_dev;
        atomic_t frag_seqno;
+       uint8_t num_bcasts;
        struct kobject *hardif_obj;
        atomic_t refcount;
        struct packet_type batman_adv_ptype;
@@ -640,7 +642,7 @@ struct batadv_socket_packet {
 #ifdef CONFIG_BATMAN_ADV_BLA
 struct batadv_bla_backbone_gw {
        uint8_t orig[ETH_ALEN];
-       short vid;
+       unsigned short vid;
        struct hlist_node hash_entry;
        struct batadv_priv *bat_priv;
        unsigned long lasttime;
@@ -663,7 +665,7 @@ struct batadv_bla_backbone_gw {
  */
 struct batadv_bla_claim {
        uint8_t addr[ETH_ALEN];
-       short vid;
+       unsigned short vid;
        struct batadv_bla_backbone_gw *backbone_gw;
        unsigned long lasttime;
        struct hlist_node hash_entry;
index 0bb3b59..dc8b5d4 100644 (file)
@@ -464,7 +464,7 @@ find_router:
                goto out;
        }
 
-       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
                ret = 0;
 
 out:
index 1625e57..4983340 100644 (file)
@@ -392,12 +392,12 @@ batadv_add_packet(struct batadv_priv *bat_priv,
                return NULL;
 
        len = sizeof(*packet) + vis_info_len;
-       info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
+       info->skb_packet = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
        if (!info->skb_packet) {
                kfree(info);
                return NULL;
        }
-       skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
+       skb_reserve(info->skb_packet, ETH_HLEN);
        packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);
 
        kref_init(&info->refcount);
@@ -697,7 +697,7 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
        struct batadv_orig_node *orig_node;
        struct batadv_vis_packet *packet;
        struct sk_buff *skb;
-       uint32_t i;
+       uint32_t i, res;
 
 
        packet = (struct batadv_vis_packet *)info->skb_packet->data;
@@ -724,7 +724,8 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
                        if (!skb)
                                continue;
 
-                       if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
+                       res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+                       if (res == NET_XMIT_DROP)
                                kfree_skb(skb);
                }
                rcu_read_unlock();
@@ -748,7 +749,7 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
        if (!skb)
                goto out;
 
-       if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP)
                kfree_skb(skb);
 
 out:
@@ -854,13 +855,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
        if (!bat_priv->vis.my_info)
                goto err;
 
-       len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE;
-       len += ETH_HLEN + NET_IP_ALIGN;
-       bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
+       len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
+       bat_priv->vis.my_info->skb_packet = netdev_alloc_skb_ip_align(NULL,
+                                                                     len);
        if (!bat_priv->vis.my_info->skb_packet)
                goto free_info;
 
-       skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
+       skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
        tmp_skb = bat_priv->vis.my_info->skb_packet;
        packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));