]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/batman-adv/soft-interface.c
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / net / batman-adv / soft-interface.c
index 936b83bb02de3723a42f5eacd418cfe816c47eba..36f050876f8260245a008de079cf0974fa97b76e 100644 (file)
@@ -166,7 +166,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
        unsigned int header_len = 0;
        int data_len = skb->len, ret;
        unsigned long brd_delay = 1;
-       bool do_bcast = false;
+       bool do_bcast = false, client_added;
        unsigned short vid;
        uint32_t seqno;
 
@@ -196,9 +196,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
        ethhdr = (struct ethhdr *)skb->data;
 
        /* Register the client MAC in the transtable */
-       if (!is_multicast_ether_addr(ethhdr->h_source))
-               batadv_tt_local_add(soft_iface, ethhdr->h_source, vid,
-                                   skb->skb_iif);
+       if (!is_multicast_ether_addr(ethhdr->h_source)) {
+               client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source,
+                                                  vid, skb->skb_iif);
+               if (!client_added)
+                       goto dropped;
+       }
 
        /* don't accept stp packets. STP does not help in meshes.
         * better use the bridge loop avoidance ...
@@ -298,8 +301,12 @@ static int batadv_interface_tx(struct sk_buff *skb,
 
                batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
 
-               ret = batadv_send_skb_unicast(bat_priv, skb, vid);
-               if (ret != 0)
+               if (is_multicast_ether_addr(ethhdr->h_dest))
+                       ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
+               else
+                       ret = batadv_send_skb_via_tt(bat_priv, skb, vid);
+
+               if (ret == NET_XMIT_DROP)
                        goto dropped_freed;
        }
 
@@ -381,7 +388,8 @@ void batadv_interface_rx(struct net_device *soft_iface,
                batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
                                                     ethhdr->h_source, vid);
 
-       if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
+       if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest,
+                                 vid))
                goto dropped;
 
        netif_rx(skb);
@@ -398,7 +406,7 @@ out:
  *  possibly free it
  * @softif_vlan: the vlan object to release
  */
-static void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
+void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
 {
        if (atomic_dec_and_test(&softif_vlan->refcount))
                kfree_rcu(softif_vlan, rcu);
@@ -412,8 +420,8 @@ static void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan)
  * Returns the private data of the vlan matching the vid passed as argument or
  * NULL otherwise. The refcounter of the returned object is incremented by 1.
  */
-static struct batadv_softif_vlan *
-batadv_softif_vlan_get(struct batadv_priv *bat_priv, unsigned short vid)
+struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
+                                                 unsigned short vid)
 {
        struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
 
@@ -443,6 +451,7 @@ batadv_softif_vlan_get(struct batadv_priv *bat_priv, unsigned short vid)
 int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
 {
        struct batadv_softif_vlan *vlan;
+       int err;
 
        vlan = batadv_softif_vlan_get(bat_priv, vid);
        if (vlan) {
@@ -457,6 +466,14 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
        vlan->vid = vid;
        atomic_set(&vlan->refcount, 1);
 
+       atomic_set(&vlan->ap_isolation, 0);
+
+       err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
+       if (err) {
+               kfree(vlan);
+               return err;
+       }
+
        /* add a new TT local entry. This one will be marked with the NOPURGE
         * flag
         */
@@ -483,6 +500,8 @@ static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
        hlist_del_rcu(&vlan->list);
        spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
 
+       batadv_sysfs_del_vlan(bat_priv, vlan);
+
        /* explicitly remove the associated TT local entry because it is marked
         * with the NOPURGE flag
         */
@@ -648,7 +667,6 @@ static int batadv_softif_init_late(struct net_device *dev)
 #ifdef CONFIG_BATMAN_ADV_DAT
        atomic_set(&bat_priv->distributed_arp_table, 1);
 #endif
-       atomic_set(&bat_priv->ap_isolation, 0);
        atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
        atomic_set(&bat_priv->gw_sel_class, 20);
        atomic_set(&bat_priv->gw.bandwidth_down, 100);
@@ -659,6 +677,7 @@ static int batadv_softif_init_late(struct net_device *dev)
        atomic_set(&bat_priv->log_level, 0);
 #endif
        atomic_set(&bat_priv->fragmentation, 1);
+       atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN);
        atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
        atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);