Commit 5dd3beba authored by David S. Miller's avatar David S. Miller

Merge tag 'batadv-next-pullrequest-20230127' of git://git.open-mesh.org/linux-merge

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 5c0862c2 0c4061c0
...@@ -159,7 +159,7 @@ Please send us comments, experiences, questions, anything :) ...@@ -159,7 +159,7 @@ Please send us comments, experiences, questions, anything :)
IRC: IRC:
#batadv on ircs://irc.hackint.org/ #batadv on ircs://irc.hackint.org/
Mailing-list: 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/) https://lists.open-mesh.org/mailman3/postorius/lists/b.a.t.m.a.n.lists.open-mesh.org/)
You can also contact the Authors: You can also contact the Authors:
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* @BATADV_CODED: network coded packets * @BATADV_CODED: network coded packets
* @BATADV_ELP: echo location packets for B.A.T.M.A.N. V * @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_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: unicast packets carrying unicast payload traffic
* @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original
...@@ -42,6 +43,7 @@ enum batadv_packettype { ...@@ -42,6 +43,7 @@ enum batadv_packettype {
BATADV_CODED = 0x02, BATADV_CODED = 0x02,
BATADV_ELP = 0x03, BATADV_ELP = 0x03,
BATADV_OGM2 = 0x04, BATADV_OGM2 = 0x04,
BATADV_MCAST = 0x05,
/* 0x40 - 0x7f: unicast */ /* 0x40 - 0x7f: unicast */
#define BATADV_UNICAST_MIN 0x40 #define BATADV_UNICAST_MIN 0x40
BATADV_UNICAST = 0x40, BATADV_UNICAST = 0x40,
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/pkt_sched.h> #include <linux/pkt_sched.h>
#include <linux/prandom.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/rculist.h> #include <linux/rculist.h>
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/minmax.h> #include <linux/minmax.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/nl80211.h> #include <linux/nl80211.h>
#include <linux/prandom.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/minmax.h> #include <linux/minmax.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/prandom.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
...@@ -800,8 +799,8 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv, ...@@ -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 */ /* only unknown & newer OGMs contain TVLVs we are interested in */
if (seqno_age > 0 && if_outgoing == BATADV_IF_DEFAULT) if (seqno_age > 0 && if_outgoing == BATADV_IF_DEFAULT)
batadv_tvlv_containers_process(bat_priv, true, orig_node, batadv_tvlv_containers_process(bat_priv, BATADV_OGM2, orig_node,
NULL, NULL, NULL,
(unsigned char *)(ogm2 + 1), (unsigned char *)(ogm2 + 1),
ntohs(ogm2->tvlv_len)); ntohs(ogm2->tvlv_len));
......
...@@ -822,7 +822,7 @@ int batadv_dat_init(struct batadv_priv *bat_priv) ...@@ -822,7 +822,7 @@ int batadv_dat_init(struct batadv_priv *bat_priv)
batadv_dat_start_timer(bat_priv); batadv_dat_start_timer(bat_priv);
batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1, 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_TVLV_HANDLER_OGM_CIFNOTFND);
batadv_dat_tvlv_container_update(bat_priv); batadv_dat_tvlv_container_update(bat_priv);
return 0; return 0;
......
...@@ -259,7 +259,7 @@ void batadv_gw_init(struct batadv_priv *bat_priv) ...@@ -259,7 +259,7 @@ void batadv_gw_init(struct batadv_priv *bat_priv)
atomic_set(&bat_priv->gw.sel_class, 1); atomic_set(&bat_priv->gw.sel_class, 1);
batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, 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); BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2022.3" #define BATADV_SOURCE_VERSION "2023.1"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -1136,223 +1135,20 @@ static int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv, ...@@ -1136,223 +1135,20 @@ 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 * batadv_mcast_forw_mode() - check on how to forward a multicast packet
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: The multicast packet to check * @skb: the multicast packet to check
* @orig: an originator to be set to forward the skb to
* @is_routable: stores whether the destination is routable * @is_routable: stores whether the destination is routable
* *
* Return: the forwarding mode as enum batadv_forw_mode and in case of * Return: The forwarding mode as enum batadv_forw_mode.
* BATADV_FORW_SINGLE set the orig to the single originator the skb
* should be forwarded to.
*/ */
enum batadv_forw_mode enum batadv_forw_mode
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, 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; int ret, tt_count, ip_count, unsnoop_count, total_count;
bool is_unsnoopable = false; bool is_unsnoopable = false;
unsigned int mcast_fanout;
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
int rtr_count = 0; int rtr_count = 0;
...@@ -1361,7 +1157,7 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1361,7 +1157,7 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
if (ret == -ENOMEM) if (ret == -ENOMEM)
return BATADV_FORW_NONE; return BATADV_FORW_NONE;
else if (ret < 0) else if (ret < 0)
return BATADV_FORW_ALL; return BATADV_FORW_BCAST;
ethhdr = eth_hdr(skb); ethhdr = eth_hdr(skb);
...@@ -1374,32 +1170,15 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *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; total_count = tt_count + ip_count + unsnoop_count + rtr_count;
switch (total_count) { if (!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:
return BATADV_FORW_NONE; return BATADV_FORW_NONE;
default: else if (unsnoop_count)
mcast_fanout = atomic_read(&bat_priv->multicast_fanout); return BATADV_FORW_BCAST;
if (!unsnoop_count && total_count <= mcast_fanout) if (total_count <= atomic_read(&bat_priv->multicast_fanout))
return BATADV_FORW_SOME; 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, ...@@ -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. * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
*/ */
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, static int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
struct sk_buff *skb, struct sk_buff *skb,
unsigned short vid, unsigned short vid,
struct batadv_orig_node *orig_node) struct batadv_orig_node *orig_node)
{ {
/* Avoid sending multicast-in-unicast packets to other BLA /* Avoid sending multicast-in-unicast packets to other BLA
* gateways - they already got the frame from the LAN side * 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, ...@@ -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) void batadv_mcast_init(struct batadv_priv *bat_priv)
{ {
batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler, 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); BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update); INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);
......
...@@ -17,23 +17,16 @@ ...@@ -17,23 +17,16 @@
*/ */
enum batadv_forw_mode { enum batadv_forw_mode {
/** /**
* @BATADV_FORW_ALL: forward the packet to all nodes (currently via * @BATADV_FORW_BCAST: forward the packet to all nodes via a batman-adv
* classic flooding) * broadcast packet
*/ */
BATADV_FORW_ALL, BATADV_FORW_BCAST,
/** /**
* @BATADV_FORW_SOME: forward the packet to some nodes (currently via * @BATADV_FORW_UCASTS: forward the packet to some nodes via one
* a multicast-to-unicast conversion and the BATMAN unicast routing * or more batman-adv unicast packets
* protocol)
*/ */
BATADV_FORW_SOME, BATADV_FORW_UCASTS,
/**
* @BATADV_FORW_SINGLE: forward the packet to a single node (currently
* via the BATMAN unicast routing protocol)
*/
BATADV_FORW_SINGLE,
/** @BATADV_FORW_NONE: don't forward, drop it */ /** @BATADV_FORW_NONE: don't forward, drop it */
BATADV_FORW_NONE, BATADV_FORW_NONE,
...@@ -43,14 +36,8 @@ enum batadv_forw_mode { ...@@ -43,14 +36,8 @@ enum batadv_forw_mode {
enum batadv_forw_mode enum batadv_forw_mode
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
struct batadv_orig_node **mcast_single_orig,
int *is_routable); 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, int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
unsigned short vid, int is_routable); unsigned short vid, int is_routable);
...@@ -69,20 +56,9 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node); ...@@ -69,20 +56,9 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
static inline enum batadv_forw_mode static inline enum batadv_forw_mode
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
struct batadv_orig_node **mcast_single_orig,
int *is_routable) int *is_routable)
{ {
return BATADV_FORW_ALL; return BATADV_FORW_BCAST;
}
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;
} }
static inline int static inline int
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/prandom.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/random.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
...@@ -160,7 +160,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv) ...@@ -160,7 +160,7 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
batadv_nc_start_timer(bat_priv); batadv_nc_start_timer(bat_priv);
batadv_tvlv_handler_register(bat_priv, batadv_nc_tvlv_ogm_handler_v1, 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_TVLV_HANDLER_OGM_CIFNOTFND);
batadv_nc_tvlv_container_update(bat_priv); batadv_nc_tvlv_container_update(bat_priv);
return 0; return 0;
......
...@@ -1073,10 +1073,9 @@ int batadv_recv_unicast_tvlv(struct sk_buff *skb, ...@@ -1073,10 +1073,9 @@ int batadv_recv_unicast_tvlv(struct sk_buff *skb,
if (tvlv_buff_len > skb->len - hdr_size) if (tvlv_buff_len > skb->len - hdr_size)
goto free_skb; goto free_skb;
ret = batadv_tvlv_containers_process(bat_priv, false, NULL, ret = batadv_tvlv_containers_process(bat_priv, BATADV_UNICAST_TVLV,
unicast_tvlv_packet->src, NULL, skb, tvlv_buff,
unicast_tvlv_packet->dst, tvlv_buff_len);
tvlv_buff, tvlv_buff_len);
if (ret != NET_RX_SUCCESS) { if (ret != NET_RX_SUCCESS) {
ret = batadv_route_unicast_packet(skb, recv_if); ret = batadv_route_unicast_packet(skb, recv_if);
......
...@@ -48,7 +48,6 @@ ...@@ -48,7 +48,6 @@
#include "hard-interface.h" #include "hard-interface.h"
#include "multicast.h" #include "multicast.h"
#include "network-coding.h" #include "network-coding.h"
#include "originator.h"
#include "send.h" #include "send.h"
#include "translation-table.h" #include "translation-table.h"
...@@ -196,8 +195,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -196,8 +195,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
unsigned short vid; unsigned short vid;
u32 seqno; u32 seqno;
int gw_mode; int gw_mode;
enum batadv_forw_mode forw_mode = BATADV_FORW_SINGLE; enum batadv_forw_mode forw_mode = BATADV_FORW_BCAST;
struct batadv_orig_node *mcast_single_orig = NULL;
int mcast_is_routable = 0; int mcast_is_routable = 0;
int network_offset = ETH_HLEN; int network_offset = ETH_HLEN;
__be16 proto; __be16 proto;
...@@ -301,14 +299,18 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -301,14 +299,18 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
send: send:
if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) {
forw_mode = batadv_mcast_forw_mode(bat_priv, skb, forw_mode = batadv_mcast_forw_mode(bat_priv, skb,
&mcast_single_orig,
&mcast_is_routable); &mcast_is_routable);
if (forw_mode == BATADV_FORW_NONE) switch (forw_mode) {
goto dropped; case BATADV_FORW_BCAST:
break;
if (forw_mode == BATADV_FORW_SINGLE || case BATADV_FORW_UCASTS:
forw_mode == BATADV_FORW_SOME)
do_bcast = false; do_bcast = false;
break;
case BATADV_FORW_NONE:
fallthrough;
default:
goto dropped;
}
} }
} }
...@@ -357,10 +359,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -357,10 +359,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
if (ret) if (ret)
goto dropped; goto dropped;
ret = batadv_send_skb_via_gw(bat_priv, skb, vid); ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
} else if (mcast_single_orig) { } else if (forw_mode == BATADV_FORW_UCASTS) {
ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
mcast_single_orig);
} else if (forw_mode == BATADV_FORW_SOME) {
ret = batadv_mcast_forw_send(bat_priv, skb, vid, ret = batadv_mcast_forw_send(bat_priv, skb, vid,
mcast_is_routable); mcast_is_routable);
} else { } else {
...@@ -386,7 +385,6 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -386,7 +385,6 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
dropped_freed: dropped_freed:
batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
end: end:
batadv_orig_node_put(mcast_single_orig);
batadv_hardif_put(primary_if); batadv_hardif_put(primary_if);
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
......
...@@ -4168,11 +4168,11 @@ int batadv_tt_init(struct batadv_priv *bat_priv) ...@@ -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_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_TT, 1, BATADV_NO_FLAGS);
batadv_tvlv_handler_register(bat_priv, NULL, 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); BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
......
...@@ -352,10 +352,9 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv, ...@@ -352,10 +352,9 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
* appropriate handlers * appropriate handlers
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @tvlv_handler: tvlv callback function handling the tvlv content * @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 * @orig_node: orig node emitting the ogm packet
* @src: source mac address of the unicast packet * @skb: the skb the TVLV handler is called for
* @dst: destination mac address of the unicast packet
* @tvlv_value: tvlv content * @tvlv_value: tvlv content
* @tvlv_value_len: tvlv content length * @tvlv_value_len: tvlv content length
* *
...@@ -364,15 +363,20 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv, ...@@ -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, static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
struct batadv_tvlv_handler *tvlv_handler, struct batadv_tvlv_handler *tvlv_handler,
bool ogm_source, u8 packet_type,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
u8 *src, u8 *dst, struct sk_buff *skb, void *tvlv_value,
void *tvlv_value, u16 tvlv_value_len) u16 tvlv_value_len)
{ {
unsigned int tvlv_offset;
u8 *src, *dst;
if (!tvlv_handler) if (!tvlv_handler)
return NET_RX_SUCCESS; return NET_RX_SUCCESS;
if (ogm_source) { switch (packet_type) {
case BATADV_IV_OGM:
case BATADV_OGM2:
if (!tvlv_handler->ogm_handler) if (!tvlv_handler->ogm_handler)
return NET_RX_SUCCESS; return NET_RX_SUCCESS;
...@@ -383,19 +387,32 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, ...@@ -383,19 +387,32 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
BATADV_NO_FLAGS, BATADV_NO_FLAGS,
tvlv_value, tvlv_value_len); tvlv_value, tvlv_value_len);
tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED; tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED;
} else { break;
if (!src) case BATADV_UNICAST_TVLV:
return NET_RX_SUCCESS; if (!skb)
if (!dst)
return NET_RX_SUCCESS; return NET_RX_SUCCESS;
if (!tvlv_handler->unicast_handler) if (!tvlv_handler->unicast_handler)
return NET_RX_SUCCESS; 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, return tvlv_handler->unicast_handler(bat_priv, src,
dst, tvlv_value, dst, tvlv_value,
tvlv_value_len); 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; return NET_RX_SUCCESS;
...@@ -405,10 +422,9 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, ...@@ -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 * batadv_tvlv_containers_process() - parse the given tvlv buffer to call the
* appropriate handlers * appropriate handlers
* @bat_priv: the bat priv with all the soft interface information * @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 * @orig_node: orig node emitting the ogm packet
* @src: source mac address of the unicast packet * @skb: the skb the TVLV handler is called for
* @dst: destination mac address of the unicast packet
* @tvlv_value: tvlv content * @tvlv_value: tvlv content
* @tvlv_value_len: tvlv content length * @tvlv_value_len: tvlv content length
* *
...@@ -416,10 +432,10 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, ...@@ -416,10 +432,10 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
* handler callbacks. * handler callbacks.
*/ */
int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
bool ogm_source, u8 packet_type,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
u8 *src, u8 *dst, struct sk_buff *skb, void *tvlv_value,
void *tvlv_value, u16 tvlv_value_len) u16 tvlv_value_len)
{ {
struct batadv_tvlv_handler *tvlv_handler; struct batadv_tvlv_handler *tvlv_handler;
struct batadv_tvlv_hdr *tvlv_hdr; struct batadv_tvlv_hdr *tvlv_hdr;
...@@ -441,20 +457,24 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, ...@@ -441,20 +457,24 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
tvlv_hdr->version); tvlv_hdr->version);
ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler, ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler,
ogm_source, orig_node, packet_type, orig_node, skb,
src, dst, tvlv_value, tvlv_value,
tvlv_value_cont_len); tvlv_value_cont_len);
batadv_tvlv_handler_put(tvlv_handler); batadv_tvlv_handler_put(tvlv_handler);
tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len; tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len;
tvlv_value_len -= 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; return ret;
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(tvlv_handler, hlist_for_each_entry_rcu(tvlv_handler,
&bat_priv->tvlv.handler_list, list) { &bat_priv->tvlv.handler_list, list) {
if (!tvlv_handler->ogm_handler)
continue;
if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) && if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) &&
!(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED)) !(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED))
tvlv_handler->ogm_handler(bat_priv, orig_node, tvlv_handler->ogm_handler(bat_priv, orig_node,
...@@ -490,7 +510,7 @@ void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv, ...@@ -490,7 +510,7 @@ void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
tvlv_value = batadv_ogm_packet + 1; 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); tvlv_value, tvlv_value_len);
} }
...@@ -504,6 +524,10 @@ void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv, ...@@ -504,6 +524,10 @@ void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
* @uptr: unicast tvlv handler callback function. This function receives the * @uptr: unicast tvlv handler callback function. This function receives the
* source & destination of the unicast packet as well as the tvlv content * source & destination of the unicast packet as well as the tvlv content
* to process. * 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 * @type: tvlv handler type to be registered
* @version: tvlv handler version to be registered * @version: tvlv handler version to be registered
* @flags: flags to enable or disable TVLV API behavior * @flags: flags to enable or disable TVLV API behavior
...@@ -518,6 +542,8 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, ...@@ -518,6 +542,8 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
u8 *src, u8 *dst, u8 *src, u8 *dst,
void *tvlv_value, void *tvlv_value,
u16 tvlv_value_len), u16 tvlv_value_len),
int (*mptr)(struct batadv_priv *bat_priv,
struct sk_buff *skb),
u8 type, u8 version, u8 flags) u8 type, u8 version, u8 flags)
{ {
struct batadv_tvlv_handler *tvlv_handler; struct batadv_tvlv_handler *tvlv_handler;
...@@ -539,6 +565,7 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, ...@@ -539,6 +565,7 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
tvlv_handler->ogm_handler = optr; tvlv_handler->ogm_handler = optr;
tvlv_handler->unicast_handler = uptr; tvlv_handler->unicast_handler = uptr;
tvlv_handler->mcast_handler = mptr;
tvlv_handler->type = type; tvlv_handler->type = type;
tvlv_handler->version = version; tvlv_handler->version = version;
tvlv_handler->flags = flags; tvlv_handler->flags = flags;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "main.h" #include "main.h"
#include <linux/skbuff.h>
#include <linux/types.h> #include <linux/types.h>
#include <uapi/linux/batadv_packet.h> #include <uapi/linux/batadv_packet.h>
...@@ -34,14 +35,16 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, ...@@ -34,14 +35,16 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
u8 *src, u8 *dst, u8 *src, u8 *dst,
void *tvlv_value, void *tvlv_value,
u16 tvlv_value_len), u16 tvlv_value_len),
int (*mptr)(struct batadv_priv *bat_priv,
struct sk_buff *skb),
u8 type, u8 version, u8 flags); u8 type, u8 version, u8 flags);
void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv, void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv,
u8 type, u8 version); u8 type, u8 version);
int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
bool ogm_source, u8 packet_type,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
u8 *src, u8 *dst, struct sk_buff *skb, void *tvlv_buff,
void *tvlv_buff, u16 tvlv_buff_len); u16 tvlv_buff_len);
void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, const u8 *src, void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, const u8 *src,
const u8 *dst, u8 type, u8 version, const u8 *dst, u8 type, u8 version,
void *tvlv_value, u16 tvlv_value_len); void *tvlv_value, u16 tvlv_value_len);
......
...@@ -2335,6 +2335,12 @@ struct batadv_tvlv_handler { ...@@ -2335,6 +2335,12 @@ struct batadv_tvlv_handler {
u8 *src, u8 *dst, u8 *src, u8 *dst,
void *tvlv_value, u16 tvlv_value_len); 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 */ /** @type: tvlv type this handler feels responsible for */
u8 type; u8 type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment