Skip to content

Commit

Permalink
batman-adv: tvlv: prepare for tvlv enabled multicast packet type
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Linus Lüssing authored and Simon Wunderlich committed Jan 21, 2023
1 parent e7d6127 commit 0c4061c
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 37 deletions.
2 changes: 2 additions & 0 deletions include/uapi/linux/batadv_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions net/batman-adv/bat_v_ogm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/distributed-arp-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/gateway_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/multicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion net/batman-adv/network-coding.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 3 additions & 4 deletions net/batman-adv/routing.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions net/batman-adv/translation-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
71 changes: 49 additions & 22 deletions net/batman-adv/tvlv.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,9 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
* 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
*
Expand All @@ -364,15 +363,20 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
*/
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;

Expand All @@ -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;
Expand All @@ -405,21 +422,20 @@ 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
*
* Return: success when processing an OGM or the return value of all called
* 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;
Expand All @@ -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,
Expand Down Expand Up @@ -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);
}

Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions net/batman-adv/tvlv.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "main.h"

#include <linux/skbuff.h>
#include <linux/types.h>
#include <uapi/linux/batadv_packet.h>

Expand All @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions net/batman-adv/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 0c4061c

Please sign in to comment.