batman-adv: tvlv: prepare for tvlv enabled multicast packet type
authorLinus Lüssing <linus.luessing@c0d3.blue>
Tue, 27 Dec 2022 19:34:06 +0000 (20:34 +0100)
committerSimon Wunderlich <sw@simonwunderlich.de>
Sat, 21 Jan 2023 18:01:59 +0000 (19:01 +0100)
Prepare TVLV infrastructure for more packet types, in particular the
upcoming batman-adv multicast packet type.

For that swap the OGM vs. unicast-tvlv packet boolean indicator to an
explicit unsigned integer packet type variable. And provide the skb
to a call to batadv_tvlv_containers_process(), as later the multicast
packet's TVLV handler will need to have access not only to the TVLV but
the full skb for forwarding. Forwarding will be invoked from the
multicast packet's TVLVs' contents later.

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
include/uapi/linux/batadv_packet.h
net/batman-adv/bat_v_ogm.c
net/batman-adv/distributed-arp-table.c
net/batman-adv/gateway_common.c
net/batman-adv/multicast.c
net/batman-adv/network-coding.c
net/batman-adv/routing.c
net/batman-adv/translation-table.c
net/batman-adv/tvlv.c
net/batman-adv/tvlv.h
net/batman-adv/types.h

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 96e0273..e710e9a 100644 (file)
@@ -799,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 7e2822c..315394f 100644 (file)
@@ -1818,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 ecd871a..71ebd02 100644 (file)
@@ -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 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;