Staging: batman-adv: Unify sysfs file names with their bat_priv atomics
[firefly-linux-kernel-4.4.55.git] / drivers / staging / batman-adv / routing.c
index 657b69e6b9573595e80fb42e9c69849ac701d7c6..1b35486349040199d8abe7d9ab1de47ed1863b2f 100644 (file)
@@ -1019,7 +1019,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv,
        /* without bonding, the first node should
         * always choose the default router. */
 
-       bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
+       bonding_enabled = atomic_read(&bat_priv->bonding);
 
        if ((!recv_if) && (!bonding_enabled))
                return orig_node->router;
@@ -1117,8 +1117,8 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
        return 0;
 }
 
-static int route_unicast_packet(struct sk_buff *skb,
-                               struct batman_if *recv_if, int hdr_size)
+int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
+                        int hdr_size)
 {
        struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
        struct orig_node *orig_node;
@@ -1128,15 +1128,11 @@ static int route_unicast_packet(struct sk_buff *skb,
        unsigned long flags;
        struct unicast_packet *unicast_packet;
        struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+       int ret;
+       struct sk_buff *new_skb;
 
        unicast_packet = (struct unicast_packet *)skb->data;
 
-       /* packet for me */
-       if (is_my_mac(unicast_packet->dest)) {
-               interface_rx(recv_if->soft_iface, skb, hdr_size);
-               return NET_RX_SUCCESS;
-       }
-
        /* TTL exceeded */
        if (unicast_packet->ttl < 2) {
                pr_debug("Warning - can't forward unicast packet from %pM to "
@@ -1170,7 +1166,28 @@ static int route_unicast_packet(struct sk_buff *skb,
                return NET_RX_DROP;
 
        unicast_packet = (struct unicast_packet *)skb->data;
-       ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+       if (unicast_packet->packet_type == BAT_UNICAST &&
+           atomic_read(&bat_priv->fragmentation) &&
+           skb->len > batman_if->net_dev->mtu)
+               return frag_send_skb(skb, bat_priv, batman_if,
+                                    dstaddr);
+
+       if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
+           2 * skb->len - hdr_size <= batman_if->net_dev->mtu) {
+
+               ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
+
+               if (ret == NET_RX_DROP)
+                       return NET_RX_DROP;
+
+               /* packet was buffered for late merge */
+               if (!new_skb)
+                       return NET_RX_SUCCESS;
+
+               skb = new_skb;
+               unicast_packet = (struct unicast_packet *)skb->data;
+       }
 
        /* decrement ttl */
        unicast_packet->ttl--;
@@ -1193,7 +1210,7 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
 
        /* packet for me */
        if (is_my_mac(unicast_packet->dest)) {
-               interface_rx(recv_if->soft_iface, skb, hdr_size);
+               interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
                return NET_RX_SUCCESS;
        }
 
@@ -1204,10 +1221,9 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
 {
        struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
        struct unicast_frag_packet *unicast_packet;
-       struct orig_node *orig_node;
-       struct frag_packet_list_entry *tmp_frag_entry;
        int hdr_size = sizeof(struct unicast_frag_packet);
-       unsigned long flags;
+       struct sk_buff *new_skb = NULL;
+       int ret;
 
        if (check_unicast_packet(skb, hdr_size) < 0)
                return NET_RX_DROP;
@@ -1217,44 +1233,17 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
        /* packet for me */
        if (is_my_mac(unicast_packet->dest)) {
 
-               spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
-               orig_node = ((struct orig_node *)
-                       hash_find(bat_priv->orig_hash, unicast_packet->orig));
-
-               if (!orig_node) {
-                       pr_debug("couldn't find orig node for fragmentation\n");
-                       spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
-                                              flags);
-                       return NET_RX_DROP;
-               }
-
-               orig_node->last_frag_packet = jiffies;
+               ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
 
-               if (list_empty(&orig_node->frag_list) &&
-                       create_frag_buffer(&orig_node->frag_list)) {
-                       spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
-                                              flags);
+               if (ret == NET_RX_DROP)
                        return NET_RX_DROP;
-               }
 
-               tmp_frag_entry =
-                       search_frag_packet(&orig_node->frag_list,
-                                          unicast_packet);
-
-               if (!tmp_frag_entry) {
-                       create_frag_entry(&orig_node->frag_list, skb);
-                       spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
-                                              flags);
+               /* packet was buffered for late merge */
+               if (!new_skb)
                        return NET_RX_SUCCESS;
-               }
-
-               skb = merge_frag_packet(&orig_node->frag_list,
-                                       tmp_frag_entry, skb);
-               spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
-               if (!skb)
-                       return NET_RX_DROP;
 
-               interface_rx(recv_if->soft_iface, skb, hdr_size);
+               interface_rx(recv_if->soft_iface, new_skb, recv_if,
+                            sizeof(struct unicast_packet));
                return NET_RX_SUCCESS;
        }
 
@@ -1335,7 +1324,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
        add_bcast_packet_to_list(bat_priv, skb);
 
        /* broadcast for me */
-       interface_rx(recv_if->soft_iface, skb, hdr_size);
+       interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
 
        return NET_RX_SUCCESS;
 }