Merge tag 'batadv-next-pullrequest-20230127' of git://git.open-mesh.org/linux-merge
authorDavid S. Miller <davem@davemloft.net>
Mon, 30 Jan 2023 07:33:06 +0000 (07:33 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 30 Jan 2023 07:33:06 +0000 (07:33 +0000)
Simon Wunderlich says:

====================
This feature/cleanup patchset includes the following patches:

 - bump version strings, by Simon Wunderlich

 - drop prandom.h includes, by Sven Eckelmann

 - fix mailing list address, by Sven Eckelmann

 - multicast feature preparation, by Linus Lüssing (2 patches)
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
17 files changed:
Documentation/networking/batman-adv.rst
include/uapi/linux/batadv_packet.h
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bat_v_elp.c
net/batman-adv/bat_v_ogm.c
net/batman-adv/distributed-arp-table.c
net/batman-adv/gateway_common.c
net/batman-adv/main.h
net/batman-adv/multicast.c
net/batman-adv/multicast.h
net/batman-adv/network-coding.c
net/batman-adv/routing.c
net/batman-adv/soft-interface.c
net/batman-adv/translation-table.c
net/batman-adv/tvlv.c
net/batman-adv/tvlv.h
net/batman-adv/types.h

index b85563e..8a0dcb1 100644 (file)
@@ -159,7 +159,7 @@ Please send us comments, experiences, questions, anything :)
 IRC:
   #batadv on ircs://irc.hackint.org/
 Mailing-list:
-  b.a.t.m.a.n@open-mesh.org (optional subscription at
+  b.a.t.m.a.n@lists.open-mesh.org (optional subscription at
   https://lists.open-mesh.org/mailman3/postorius/lists/b.a.t.m.a.n.lists.open-mesh.org/)
 
 You can also contact the Authors:
index ea4692c..9204e44 100644 (file)
@@ -26,6 +26,7 @@
  * @BATADV_CODED: network coded packets
  * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V
  * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V
+ * @BATADV_MCAST: multicast packet with multiple destination addresses
  *
  * @BATADV_UNICAST: unicast packets carrying unicast payload traffic
  * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original
@@ -42,6 +43,7 @@ enum batadv_packettype {
        BATADV_CODED            = 0x02,
        BATADV_ELP              = 0x03,
        BATADV_OGM2             = 0x04,
+       BATADV_MCAST            = 0x05,
        /* 0x40 - 0x7f: unicast */
 #define BATADV_UNICAST_MIN     0x40
        BATADV_UNICAST          = 0x40,
index 114ee5d..828fb39 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/netdevice.h>
 #include <linux/netlink.h>
 #include <linux/pkt_sched.h>
-#include <linux/prandom.h>
 #include <linux/printk.h>
 #include <linux/random.h>
 #include <linux/rculist.h>
index f9a58fb..acff565 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/minmax.h>
 #include <linux/netdevice.h>
 #include <linux/nl80211.h>
-#include <linux/prandom.h>
 #include <linux/random.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
index addfd8c..e710e9a 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/minmax.h>
 #include <linux/mutex.h>
 #include <linux/netdevice.h>
-#include <linux/prandom.h>
 #include <linux/random.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
@@ -800,8 +799,8 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
 
        /* only unknown & newer OGMs contain TVLVs we are interested in */
        if (seqno_age > 0 && if_outgoing == BATADV_IF_DEFAULT)
-               batadv_tvlv_containers_process(bat_priv, true, orig_node,
-                                              NULL, NULL,
+               batadv_tvlv_containers_process(bat_priv, BATADV_OGM2, orig_node,
+                                              NULL,
                                               (unsigned char *)(ogm2 + 1),
                                               ntohs(ogm2->tvlv_len));
 
index fefb51a..6968e55 100644 (file)
@@ -822,7 +822,7 @@ int batadv_dat_init(struct batadv_priv *bat_priv)
        batadv_dat_start_timer(bat_priv);
 
        batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1,
-                                    NULL, BATADV_TVLV_DAT, 1,
+                                    NULL, NULL, BATADV_TVLV_DAT, 1,
                                     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
        batadv_dat_tvlv_container_update(bat_priv);
        return 0;
index 9349c76..6a964a7 100644 (file)
@@ -259,7 +259,7 @@ void batadv_gw_init(struct batadv_priv *bat_priv)
                atomic_set(&bat_priv->gw.sel_class, 1);
 
        batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
-                                    NULL, BATADV_TVLV_GW, 1,
+                                    NULL, NULL, BATADV_TVLV_GW, 1,
                                     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
 }
 
index c48803b..156ed39 100644 (file)
@@ -13,7 +13,7 @@
 #define BATADV_DRIVER_DEVICE "batman-adv"
 
 #ifndef BATADV_SOURCE_VERSION
-#define BATADV_SOURCE_VERSION "2022.3"
+#define BATADV_SOURCE_VERSION "2023.1"
 #endif
 
 /* B.A.T.M.A.N. parameters */
index b238455..315394f 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/ipv6.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
-#include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/lockdep.h>
 #include <linux/netdevice.h>
@@ -1137,222 +1136,19 @@ static int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv,
 }
 
 /**
- * batadv_mcast_forw_tt_node_get() - get a multicast tt node
- * @bat_priv: the bat priv with all the soft interface information
- * @ethhdr: the ether header containing the multicast destination
- *
- * Return: an orig_node matching the multicast address provided by ethhdr
- * via a translation table lookup. This increases the returned nodes refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
-                             struct ethhdr *ethhdr)
-{
-       return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest,
-                                       BATADV_NO_FLAGS);
-}
-
-/**
- * batadv_mcast_forw_ipv4_node_get() - get a node with an ipv4 flag
- * @bat_priv: the bat priv with all the soft interface information
- *
- * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 flag set and
- * increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv)
-{
-       struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(tmp_orig_node,
-                                &bat_priv->mcast.want_all_ipv4_list,
-                                mcast_want_all_ipv4_node) {
-               if (!kref_get_unless_zero(&tmp_orig_node->refcount))
-                       continue;
-
-               orig_node = tmp_orig_node;
-               break;
-       }
-       rcu_read_unlock();
-
-       return orig_node;
-}
-
-/**
- * batadv_mcast_forw_ipv6_node_get() - get a node with an ipv6 flag
- * @bat_priv: the bat priv with all the soft interface information
- *
- * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV6 flag set
- * and increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
-{
-       struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(tmp_orig_node,
-                                &bat_priv->mcast.want_all_ipv6_list,
-                                mcast_want_all_ipv6_node) {
-               if (!kref_get_unless_zero(&tmp_orig_node->refcount))
-                       continue;
-
-               orig_node = tmp_orig_node;
-               break;
-       }
-       rcu_read_unlock();
-
-       return orig_node;
-}
-
-/**
- * batadv_mcast_forw_ip_node_get() - get a node with an ipv4/ipv6 flag
- * @bat_priv: the bat priv with all the soft interface information
- * @ethhdr: an ethernet header to determine the protocol family from
- *
- * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
- * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, sets and
- * increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_ip_node_get(struct batadv_priv *bat_priv,
-                             struct ethhdr *ethhdr)
-{
-       switch (ntohs(ethhdr->h_proto)) {
-       case ETH_P_IP:
-               return batadv_mcast_forw_ipv4_node_get(bat_priv);
-       case ETH_P_IPV6:
-               return batadv_mcast_forw_ipv6_node_get(bat_priv);
-       default:
-               /* we shouldn't be here... */
-               return NULL;
-       }
-}
-
-/**
- * batadv_mcast_forw_unsnoop_node_get() - get a node with an unsnoopable flag
- * @bat_priv: the bat priv with all the soft interface information
- *
- * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag
- * set and increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv)
-{
-       struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(tmp_orig_node,
-                                &bat_priv->mcast.want_all_unsnoopables_list,
-                                mcast_want_all_unsnoopables_node) {
-               if (!kref_get_unless_zero(&tmp_orig_node->refcount))
-                       continue;
-
-               orig_node = tmp_orig_node;
-               break;
-       }
-       rcu_read_unlock();
-
-       return orig_node;
-}
-
-/**
- * batadv_mcast_forw_rtr4_node_get() - get a node with an ipv4 mcast router flag
- * @bat_priv: the bat priv with all the soft interface information
- *
- * Return: an orig_node which has the BATADV_MCAST_WANT_NO_RTR4 flag unset and
- * increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_rtr4_node_get(struct batadv_priv *bat_priv)
-{
-       struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(tmp_orig_node,
-                                &bat_priv->mcast.want_all_rtr4_list,
-                                mcast_want_all_rtr4_node) {
-               if (!kref_get_unless_zero(&tmp_orig_node->refcount))
-                       continue;
-
-               orig_node = tmp_orig_node;
-               break;
-       }
-       rcu_read_unlock();
-
-       return orig_node;
-}
-
-/**
- * batadv_mcast_forw_rtr6_node_get() - get a node with an ipv6 mcast router flag
- * @bat_priv: the bat priv with all the soft interface information
- *
- * Return: an orig_node which has the BATADV_MCAST_WANT_NO_RTR6 flag unset
- * and increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_rtr6_node_get(struct batadv_priv *bat_priv)
-{
-       struct batadv_orig_node *tmp_orig_node, *orig_node = NULL;
-
-       rcu_read_lock();
-       hlist_for_each_entry_rcu(tmp_orig_node,
-                                &bat_priv->mcast.want_all_rtr6_list,
-                                mcast_want_all_rtr6_node) {
-               if (!kref_get_unless_zero(&tmp_orig_node->refcount))
-                       continue;
-
-               orig_node = tmp_orig_node;
-               break;
-       }
-       rcu_read_unlock();
-
-       return orig_node;
-}
-
-/**
- * batadv_mcast_forw_rtr_node_get() - get a node with an ipv4/ipv6 router flag
- * @bat_priv: the bat priv with all the soft interface information
- * @ethhdr: an ethernet header to determine the protocol family from
- *
- * Return: an orig_node which has no BATADV_MCAST_WANT_NO_RTR4 or
- * BATADV_MCAST_WANT_NO_RTR6 flag, depending on the provided ethhdr, set and
- * increases its refcount.
- */
-static struct batadv_orig_node *
-batadv_mcast_forw_rtr_node_get(struct batadv_priv *bat_priv,
-                              struct ethhdr *ethhdr)
-{
-       switch (ntohs(ethhdr->h_proto)) {
-       case ETH_P_IP:
-               return batadv_mcast_forw_rtr4_node_get(bat_priv);
-       case ETH_P_IPV6:
-               return batadv_mcast_forw_rtr6_node_get(bat_priv);
-       default:
-               /* we shouldn't be here... */
-               return NULL;
-       }
-}
-
-/**
  * batadv_mcast_forw_mode() - check on how to forward a multicast packet
  * @bat_priv: the bat priv with all the soft interface information
- * @skb: The multicast packet to check
- * @orig: an originator to be set to forward the skb to
+ * @skb: the multicast packet to check
  * @is_routable: stores whether the destination is routable
  *
- * Return: the forwarding mode as enum batadv_forw_mode and in case of
- * BATADV_FORW_SINGLE set the orig to the single originator the skb
- * should be forwarded to.
+ * Return: The forwarding mode as enum batadv_forw_mode.
  */
 enum batadv_forw_mode
 batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
-                      struct batadv_orig_node **orig, int *is_routable)
+                      int *is_routable)
 {
        int ret, tt_count, ip_count, unsnoop_count, total_count;
        bool is_unsnoopable = false;
-       unsigned int mcast_fanout;
        struct ethhdr *ethhdr;
        int rtr_count = 0;
 
@@ -1361,7 +1157,7 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
        if (ret == -ENOMEM)
                return BATADV_FORW_NONE;
        else if (ret < 0)
-               return BATADV_FORW_ALL;
+               return BATADV_FORW_BCAST;
 
        ethhdr = eth_hdr(skb);
 
@@ -1374,32 +1170,15 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
 
        total_count = tt_count + ip_count + unsnoop_count + rtr_count;
 
-       switch (total_count) {
-       case 1:
-               if (tt_count)
-                       *orig = batadv_mcast_forw_tt_node_get(bat_priv, ethhdr);
-               else if (ip_count)
-                       *orig = batadv_mcast_forw_ip_node_get(bat_priv, ethhdr);
-               else if (unsnoop_count)
-                       *orig = batadv_mcast_forw_unsnoop_node_get(bat_priv);
-               else if (rtr_count)
-                       *orig = batadv_mcast_forw_rtr_node_get(bat_priv,
-                                                              ethhdr);
-
-               if (*orig)
-                       return BATADV_FORW_SINGLE;
-
-               fallthrough;
-       case 0:
+       if (!total_count)
                return BATADV_FORW_NONE;
-       default:
-               mcast_fanout = atomic_read(&bat_priv->multicast_fanout);
+       else if (unsnoop_count)
+               return BATADV_FORW_BCAST;
 
-               if (!unsnoop_count && total_count <= mcast_fanout)
-                       return BATADV_FORW_SOME;
-       }
+       if (total_count <= atomic_read(&bat_priv->multicast_fanout))
+               return BATADV_FORW_UCASTS;
 
-       return BATADV_FORW_ALL;
+       return BATADV_FORW_BCAST;
 }
 
 /**
@@ -1411,10 +1190,10 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
  *
  * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
  */
-int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
-                               struct sk_buff *skb,
-                               unsigned short vid,
-                               struct batadv_orig_node *orig_node)
+static int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
+                                      struct sk_buff *skb,
+                                      unsigned short vid,
+                                      struct batadv_orig_node *orig_node)
 {
        /* Avoid sending multicast-in-unicast packets to other BLA
         * gateways - they already got the frame from the LAN side
@@ -2039,7 +1818,7 @@ static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
 void batadv_mcast_init(struct batadv_priv *bat_priv)
 {
        batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
-                                    NULL, BATADV_TVLV_MCAST, 2,
+                                    NULL, NULL, BATADV_TVLV_MCAST, 2,
                                     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
 
        INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);
index 8aec818..a9770d8 100644 (file)
  */
 enum batadv_forw_mode {
        /**
-        * @BATADV_FORW_ALL: forward the packet to all nodes (currently via
-        *  classic flooding)
+        * @BATADV_FORW_BCAST: forward the packet to all nodes via a batman-adv
+        *  broadcast packet
         */
-       BATADV_FORW_ALL,
+       BATADV_FORW_BCAST,
 
        /**
-        * @BATADV_FORW_SOME: forward the packet to some nodes (currently via
-        *  a multicast-to-unicast conversion and the BATMAN unicast routing
-        *  protocol)
+        * @BATADV_FORW_UCASTS: forward the packet to some nodes via one
+        *  or more batman-adv unicast packets
         */
-       BATADV_FORW_SOME,
-
-       /**
-        * @BATADV_FORW_SINGLE: forward the packet to a single node (currently
-        *  via the BATMAN unicast routing protocol)
-        */
-       BATADV_FORW_SINGLE,
+       BATADV_FORW_UCASTS,
 
        /** @BATADV_FORW_NONE: don't forward, drop it */
        BATADV_FORW_NONE,
@@ -43,14 +36,8 @@ enum batadv_forw_mode {
 
 enum batadv_forw_mode
 batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
-                      struct batadv_orig_node **mcast_single_orig,
                       int *is_routable);
 
-int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
-                               struct sk_buff *skb,
-                               unsigned short vid,
-                               struct batadv_orig_node *orig_node);
-
 int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
                           unsigned short vid, int is_routable);
 
@@ -69,20 +56,9 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
 
 static inline enum batadv_forw_mode
 batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
-                      struct batadv_orig_node **mcast_single_orig,
                       int *is_routable)
 {
-       return BATADV_FORW_ALL;
-}
-
-static inline int
-batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
-                           struct sk_buff *skb,
-                           unsigned short vid,
-                           struct batadv_orig_node *orig_node)
-{
-       kfree_skb(skb);
-       return NET_XMIT_DROP;
+       return BATADV_FORW_BCAST;
 }
 
 static inline int
index bf29fba..71ebd02 100644 (file)
@@ -25,8 +25,8 @@
 #include <linux/lockdep.h>
 #include <linux/net.h>
 #include <linux/netdevice.h>
-#include <linux/prandom.h>
 #include <linux/printk.h>
+#include <linux/random.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
 #include <linux/skbuff.h>
@@ -160,7 +160,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
        batadv_nc_start_timer(bat_priv);
 
        batadv_tvlv_handler_register(bat_priv, batadv_nc_tvlv_ogm_handler_v1,
-                                    NULL, BATADV_TVLV_NC, 1,
+                                    NULL, NULL, BATADV_TVLV_NC, 1,
                                     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
        batadv_nc_tvlv_container_update(bat_priv);
        return 0;
index 83f3149..163cd43 100644 (file)
@@ -1073,10 +1073,9 @@ int batadv_recv_unicast_tvlv(struct sk_buff *skb,
        if (tvlv_buff_len > skb->len - hdr_size)
                goto free_skb;
 
-       ret = batadv_tvlv_containers_process(bat_priv, false, NULL,
-                                            unicast_tvlv_packet->src,
-                                            unicast_tvlv_packet->dst,
-                                            tvlv_buff, tvlv_buff_len);
+       ret = batadv_tvlv_containers_process(bat_priv, BATADV_UNICAST_TVLV,
+                                            NULL, skb, tvlv_buff,
+                                            tvlv_buff_len);
 
        if (ret != NET_RX_SUCCESS) {
                ret = batadv_route_unicast_packet(skb, recv_if);
index 0f5c067..125f462 100644 (file)
@@ -48,7 +48,6 @@
 #include "hard-interface.h"
 #include "multicast.h"
 #include "network-coding.h"
-#include "originator.h"
 #include "send.h"
 #include "translation-table.h"
 
@@ -196,8 +195,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
        unsigned short vid;
        u32 seqno;
        int gw_mode;
-       enum batadv_forw_mode forw_mode = BATADV_FORW_SINGLE;
-       struct batadv_orig_node *mcast_single_orig = NULL;
+       enum batadv_forw_mode forw_mode = BATADV_FORW_BCAST;
        int mcast_is_routable = 0;
        int network_offset = ETH_HLEN;
        __be16 proto;
@@ -301,14 +299,18 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
 send:
                if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
                        forw_mode = batadv_mcast_forw_mode(bat_priv, skb,
-                                                          &mcast_single_orig,
                                                           &mcast_is_routable);
-                       if (forw_mode == BATADV_FORW_NONE)
-                               goto dropped;
-
-                       if (forw_mode == BATADV_FORW_SINGLE ||
-                           forw_mode == BATADV_FORW_SOME)
+                       switch (forw_mode) {
+                       case BATADV_FORW_BCAST:
+                               break;
+                       case BATADV_FORW_UCASTS:
                                do_bcast = false;
+                               break;
+                       case BATADV_FORW_NONE:
+                               fallthrough;
+                       default:
+                               goto dropped;
+                       }
                }
        }
 
@@ -357,10 +359,7 @@ send:
                        if (ret)
                                goto dropped;
                        ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
-               } else if (mcast_single_orig) {
-                       ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
-                                                         mcast_single_orig);
-               } else if (forw_mode == BATADV_FORW_SOME) {
+               } else if (forw_mode == BATADV_FORW_UCASTS) {
                        ret = batadv_mcast_forw_send(bat_priv, skb, vid,
                                                     mcast_is_routable);
                } else {
@@ -386,7 +385,6 @@ dropped:
 dropped_freed:
        batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
 end:
-       batadv_orig_node_put(mcast_single_orig);
        batadv_hardif_put(primary_if);
        return NETDEV_TX_OK;
 }
index 01d30c1..36ca312 100644 (file)
@@ -4168,11 +4168,11 @@ int batadv_tt_init(struct batadv_priv *bat_priv)
        }
 
        batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
-                                    batadv_tt_tvlv_unicast_handler_v1,
+                                    batadv_tt_tvlv_unicast_handler_v1, NULL,
                                     BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
 
        batadv_tvlv_handler_register(bat_priv, NULL,
-                                    batadv_roam_tvlv_unicast_handler_v1,
+                                    batadv_roam_tvlv_unicast_handler_v1, NULL,
                                     BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
 
        INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
index 7ec2e23..2a58321 100644 (file)
@@ -352,10 +352,9 @@ end:
  *  appropriate handlers
  * @bat_priv: the bat priv with all the soft interface information
  * @tvlv_handler: tvlv callback function handling the tvlv content
- * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet
+ * @packet_type: indicates for which packet type the TVLV handler is called
  * @orig_node: orig node emitting the ogm packet
- * @src: source mac address of the unicast packet
- * @dst: destination mac address of the unicast packet
+ * @skb: the skb the TVLV handler is called for
  * @tvlv_value: tvlv content
  * @tvlv_value_len: tvlv content length
  *
@@ -364,15 +363,20 @@ end:
  */
 static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
                                    struct batadv_tvlv_handler *tvlv_handler,
-                                   bool ogm_source,
+                                   u8 packet_type,
                                    struct batadv_orig_node *orig_node,
-                                   u8 *src, u8 *dst,
-                                   void *tvlv_value, u16 tvlv_value_len)
+                                   struct sk_buff *skb, void *tvlv_value,
+                                   u16 tvlv_value_len)
 {
+       unsigned int tvlv_offset;
+       u8 *src, *dst;
+
        if (!tvlv_handler)
                return NET_RX_SUCCESS;
 
-       if (ogm_source) {
+       switch (packet_type) {
+       case BATADV_IV_OGM:
+       case BATADV_OGM2:
                if (!tvlv_handler->ogm_handler)
                        return NET_RX_SUCCESS;
 
@@ -383,19 +387,32 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
                                          BATADV_NO_FLAGS,
                                          tvlv_value, tvlv_value_len);
                tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED;
-       } else {
-               if (!src)
-                       return NET_RX_SUCCESS;
-
-               if (!dst)
+               break;
+       case BATADV_UNICAST_TVLV:
+               if (!skb)
                        return NET_RX_SUCCESS;
 
                if (!tvlv_handler->unicast_handler)
                        return NET_RX_SUCCESS;
 
+               src = ((struct batadv_unicast_tvlv_packet *)skb->data)->src;
+               dst = ((struct batadv_unicast_tvlv_packet *)skb->data)->dst;
+
                return tvlv_handler->unicast_handler(bat_priv, src,
                                                     dst, tvlv_value,
                                                     tvlv_value_len);
+       case BATADV_MCAST:
+               if (!skb)
+                       return NET_RX_SUCCESS;
+
+               if (!tvlv_handler->mcast_handler)
+                       return NET_RX_SUCCESS;
+
+               tvlv_offset = (unsigned char *)tvlv_value - skb->data;
+               skb_set_network_header(skb, tvlv_offset);
+               skb_set_transport_header(skb, tvlv_offset + tvlv_value_len);
+
+               return tvlv_handler->mcast_handler(bat_priv, skb);
        }
 
        return NET_RX_SUCCESS;
@@ -405,10 +422,9 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
  * batadv_tvlv_containers_process() - parse the given tvlv buffer to call the
  *  appropriate handlers
  * @bat_priv: the bat priv with all the soft interface information
- * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet
+ * @packet_type: indicates for which packet type the TVLV handler is called
  * @orig_node: orig node emitting the ogm packet
- * @src: source mac address of the unicast packet
- * @dst: destination mac address of the unicast packet
+ * @skb: the skb the TVLV handler is called for
  * @tvlv_value: tvlv content
  * @tvlv_value_len: tvlv content length
  *
@@ -416,10 +432,10 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
  * handler callbacks.
  */
 int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
-                                  bool ogm_source,
+                                  u8 packet_type,
                                   struct batadv_orig_node *orig_node,
-                                  u8 *src, u8 *dst,
-                                  void *tvlv_value, u16 tvlv_value_len)
+                                  struct sk_buff *skb, void *tvlv_value,
+                                  u16 tvlv_value_len)
 {
        struct batadv_tvlv_handler *tvlv_handler;
        struct batadv_tvlv_hdr *tvlv_hdr;
@@ -441,20 +457,24 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
                                                       tvlv_hdr->version);
 
                ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler,
-                                               ogm_source, orig_node,
-                                               src, dst, tvlv_value,
+                                               packet_type, orig_node, skb,
+                                               tvlv_value,
                                                tvlv_value_cont_len);
                batadv_tvlv_handler_put(tvlv_handler);
                tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len;
                tvlv_value_len -= tvlv_value_cont_len;
        }
 
-       if (!ogm_source)
+       if (packet_type != BATADV_IV_OGM &&
+           packet_type != BATADV_OGM2)
                return ret;
 
        rcu_read_lock();
        hlist_for_each_entry_rcu(tvlv_handler,
                                 &bat_priv->tvlv.handler_list, list) {
+               if (!tvlv_handler->ogm_handler)
+                       continue;
+
                if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) &&
                    !(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED))
                        tvlv_handler->ogm_handler(bat_priv, orig_node,
@@ -490,7 +510,7 @@ void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
 
        tvlv_value = batadv_ogm_packet + 1;
 
-       batadv_tvlv_containers_process(bat_priv, true, orig_node, NULL, NULL,
+       batadv_tvlv_containers_process(bat_priv, BATADV_IV_OGM, orig_node, NULL,
                                       tvlv_value, tvlv_value_len);
 }
 
@@ -504,6 +524,10 @@ void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
  * @uptr: unicast tvlv handler callback function. This function receives the
  *  source & destination of the unicast packet as well as the tvlv content
  *  to process.
+ * @mptr: multicast packet tvlv handler callback function. This function
+ *  receives the full skb to process, with the skb network header pointing
+ *  to the current tvlv and the skb transport header pointing to the first
+ *  byte after the current tvlv.
  * @type: tvlv handler type to be registered
  * @version: tvlv handler version to be registered
  * @flags: flags to enable or disable TVLV API behavior
@@ -518,6 +542,8 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
                                              u8 *src, u8 *dst,
                                              void *tvlv_value,
                                              u16 tvlv_value_len),
+                                 int (*mptr)(struct batadv_priv *bat_priv,
+                                             struct sk_buff *skb),
                                  u8 type, u8 version, u8 flags)
 {
        struct batadv_tvlv_handler *tvlv_handler;
@@ -539,6 +565,7 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
 
        tvlv_handler->ogm_handler = optr;
        tvlv_handler->unicast_handler = uptr;
+       tvlv_handler->mcast_handler = mptr;
        tvlv_handler->type = type;
        tvlv_handler->version = version;
        tvlv_handler->flags = flags;
index 4cf8af0..e569723 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "main.h"
 
+#include <linux/skbuff.h>
 #include <linux/types.h>
 #include <uapi/linux/batadv_packet.h>
 
@@ -34,14 +35,16 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
                                              u8 *src, u8 *dst,
                                              void *tvlv_value,
                                              u16 tvlv_value_len),
+                                 int (*mptr)(struct batadv_priv *bat_priv,
+                                             struct sk_buff *skb),
                                  u8 type, u8 version, u8 flags);
 void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv,
                                    u8 type, u8 version);
 int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
-                                  bool ogm_source,
+                                  u8 packet_type,
                                   struct batadv_orig_node *orig_node,
-                                  u8 *src, u8 *dst,
-                                  void *tvlv_buff, u16 tvlv_buff_len);
+                                  struct sk_buff *skb, void *tvlv_buff,
+                                  u16 tvlv_buff_len);
 void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, const u8 *src,
                              const u8 *dst, u8 type, u8 version,
                              void *tvlv_value, u16 tvlv_value_len);
index 758cd79..ca9449e 100644 (file)
@@ -2335,6 +2335,12 @@ struct batadv_tvlv_handler {
                               u8 *src, u8 *dst,
                               void *tvlv_value, u16 tvlv_value_len);
 
+       /**
+        * @mcast_handler: handler callback which is given the tvlv payload to
+        *  process on incoming mcast packet
+        */
+       int (*mcast_handler)(struct batadv_priv *bat_priv, struct sk_buff *skb);
+
        /** @type: tvlv type this handler feels responsible for */
        u8 type;