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 90102631330b883ad1f3df3bc45f3494b7f06d91..1b35486349040199d8abe7d9ab1de47ed1863b2f 100644 (file)
@@ -1000,10 +1000,10 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
 
 /* find a suitable router for this originator, and use
  * bonding if possible. */
-struct neigh_node *find_router(struct orig_node *orig_node,
+struct neigh_node *find_router(struct bat_priv *bat_priv,
+                              struct orig_node *orig_node,
                               struct batman_if *recv_if)
 {
-       struct bat_priv *bat_priv;
        struct orig_node *primary_orig_node;
        struct orig_node *router_orig;
        struct neigh_node *router, *first_candidate, *best_router;
@@ -1019,13 +1019,9 @@ struct neigh_node *find_router(struct orig_node *orig_node,
        /* without bonding, the first node should
         * always choose the default router. */
 
-       if (!recv_if)
-               return orig_node->router;
-
-       bat_priv = netdev_priv(recv_if->soft_iface);
-       bonding_enabled = atomic_read(&bat_priv->bonding_enabled);
+       bonding_enabled = atomic_read(&bat_priv->bonding);
 
-       if (!bonding_enabled)
+       if ((!recv_if) && (!bonding_enabled))
                return orig_node->router;
 
        router_orig = orig_node->router->orig_node;
@@ -1121,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;
@@ -1132,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 "
@@ -1154,7 +1146,7 @@ static int route_unicast_packet(struct sk_buff *skb,
        orig_node = ((struct orig_node *)
                     hash_find(bat_priv->orig_hash, unicast_packet->dest));
 
-       router = find_router(orig_node, recv_if);
+       router = find_router(bat_priv, orig_node, recv_if);
 
        if (!router) {
                spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
@@ -1174,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--;
@@ -1197,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;
        }
 
@@ -1208,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;
@@ -1221,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));
+               ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
 
-               if (!orig_node) {
-                       pr_debug("couldn't find orig node for fragmentation\n");
-                       spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
-                                              flags);
+               if (ret == NET_RX_DROP)
                        return NET_RX_DROP;
-               }
 
-               orig_node->last_frag_packet = jiffies;
-
-               if (list_empty(&orig_node->frag_list) &&
-                       create_frag_buffer(&orig_node->frag_list)) {
-                       spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
-                                              flags);
-                       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;
        }
 
@@ -1339,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;
 }