mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
This batman-adv cleanup patchset includes the following patches, all by
Sven Eckelmann:
- drop batman-adv specific version
- MAINTAINERS housekeeping for batman-adv (two patches)
- add missing includes
- use atomic_xchg() for gw.reselect check
- extract netdev wifi detection information object
- replace inappropriate atomic access with (READ|WRITE)_ONCE
(six patches)
- tt: replace open-coded overflow check with helper
- tvlv: avoid unnecessary OGM buffer reallocations
- use neigh_node's orig_node only as id
-----BEGIN PGP SIGNATURE-----
iQJKBAABCgA0FiEE1ilQI7G+y+fdhnrfoSvjmEKSnqEFAmodehcWHHN3QHNpbW9u
d3VuZGVybGljaC5kZQAKCRChK+OYQpKeoVWXD/9Z4kRbjVRr7ZkdiQ6hf/ZXh83s
iEmnec6bEpKdn9/bvQxFC0i87Ngf0XBeJQedGjrAuL5eEOPw50u3AZGX8uRKa9M/
BGuYvmd97vNPnHPv5yPIqQ5DuApv4CJ0BUpG4WpzL2SbizybudNIZ5gQk4FyPvQw
mjJ8WZXHh3ntfoUiDW2TOkRH1xA/wdV9Q5uEmJnhYKhyNvzK7K6/GhIsZ+vO+puO
gcFcFjxNqQ0w37fclYP8RU8/6YqPaDdzxwv/1sT4L0eDbZR5Ex2VPT0DmiJk73tE
ZX83gMvXR3qVFjVr9e2MWHjm3aEfufdKyd7n4XNapcRUR2eCfeLsnJ9wzuJFx49X
4w/eoBdj9cgrpYpn1ptG+mZe8gzvS0Wz8Uy4OdReQV8DvT0ajMYKCfshhmeIWJrv
qjLKDPqtCPbq9paBkjChiS+/QABJQYkHMdoTUZKyOHITY8s2/9zRrQCOD9j1VYzo
0vAnz7jZny/5Z47b5w6ddgS3ecU9eaAAjr4g+3ZfAJ1iXBTedxDOqL96iZZVblIH
gFIxyinlmxh8xkRNpvb5RpoYtiI0aBSFnPExmxSTlWqFLGAQDi9MvaWvR/Yvnwso
nntU1nJBG2cF/Tta7onZJzAbGwfZRDbqOt8+TbY3XtytTamOoTkuilPpMLg7XiMZ
Q5nZJEwOGIVwevAtPg==
=bwmN
-----END PGP SIGNATURE-----
Merge tag 'batadv-next-pullrequest-20260601' of https://git.open-mesh.org/batadv
Simon Wunderlich says:
====================
This batman-adv cleanup patchset includes the following patches, all by
Sven Eckelmann:
- drop batman-adv specific version
- MAINTAINERS housekeeping for batman-adv (two patches)
- add missing includes
- use atomic_xchg() for gw.reselect check
- extract netdev wifi detection information object
- replace inappropriate atomic access with (READ|WRITE)_ONCE
(six patches)
- tt: replace open-coded overflow check with helper
- tvlv: avoid unnecessary OGM buffer reallocations
- use neigh_node's orig_node only as id
* tag 'batadv-next-pullrequest-20260601' of https://git.open-mesh.org/batadv:
batman-adv: use neigh_node's orig_node only as id
batman-adv: tvlv: avoid unnecessary OGM buffer reallocations
batman-adv: tt: replace open-coded overflow check with helper
batman-adv: replace non-atomic last_ttvn with (READ|WRITE)_ONCE
batman-adv: replace non-atomic packet_size_max with (READ|WRITE)_ONCE
batman-adv: replace non-atomic mesh state with (READ|WRITE)_ONCE
batman-adv: replace non-atomic vlan config fields with (READ|WRITE)_ONCE
batman-adv: replace non-atomic hardif config fields with (READ|WRITE)_ONCE
batman-adv: replace non-atomic meshif config fields with (READ|WRITE)_ONCE
batman-adv: extract netdev wifi detection information object
batman-adv: use atomic_xchg() for gw.reselect check
batman-adv: add missing includes
MAINTAINERS: Don't send batman-adv patches to netdev
MAINTAINERS: Rename batman-adv T(ree)
batman-adv: drop batman-adv specific version
====================
Link: https://patch.msgid.link/20260601123629.707089-1-sw@simonwunderlich.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
f8524d16e2
|
|
@ -4449,7 +4449,7 @@ W: https://www.open-mesh.org/
|
|||
Q: https://patchwork.open-mesh.org/project/batman/list/
|
||||
B: https://www.open-mesh.org/projects/batman-adv/issues
|
||||
C: ircs://irc.hackint.org/batadv
|
||||
T: git https://git.open-mesh.org/linux-merge.git
|
||||
T: git https://git.open-mesh.org/batadv.git
|
||||
F: Documentation/networking/batman-adv.rst
|
||||
F: include/uapi/linux/batadv_packet.h
|
||||
F: include/uapi/linux/batman_adv.h
|
||||
|
|
@ -18642,6 +18642,7 @@ F: net/
|
|||
F: samples/pktgen/
|
||||
F: tools/net/
|
||||
F: tools/testing/selftests/net/
|
||||
X: Documentation/networking/batman-adv.rst
|
||||
X: Documentation/networking/mac80211-injection.rst
|
||||
X: Documentation/networking/mac80211_hwsim/
|
||||
X: Documentation/networking/regulatory.rst
|
||||
|
|
@ -18652,6 +18653,7 @@ X: include/net/iw_handler.h
|
|||
X: include/net/mac80211.h
|
||||
X: include/net/wext.h
|
||||
X: net/9p/
|
||||
X: net/batman-adv/
|
||||
X: net/bluetooth/
|
||||
X: net/can/
|
||||
X: net/ceph/
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ batman-adv-$(CONFIG_BATMAN_ADV_TRACING) += trace.o
|
|||
batman-adv-y += tp_meter.o
|
||||
batman-adv-y += translation-table.o
|
||||
batman-adv-y += tvlv.o
|
||||
batman-adv-y += version.o
|
||||
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
@ -194,14 +195,17 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
|
|||
get_random_bytes(&random_seqno, sizeof(random_seqno));
|
||||
atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
|
||||
|
||||
hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
|
||||
ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
|
||||
hard_iface->bat_iv.ogm_buff.len = BATADV_OGM_HLEN;
|
||||
hard_iface->bat_iv.ogm_buff.capacity = BATADV_OGM_HLEN;
|
||||
hard_iface->bat_iv.ogm_buff.header_length = BATADV_OGM_HLEN;
|
||||
|
||||
ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff.capacity, GFP_ATOMIC);
|
||||
if (!ogm_buff) {
|
||||
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hard_iface->bat_iv.ogm_buff = ogm_buff;
|
||||
hard_iface->bat_iv.ogm_buff.buf = ogm_buff;
|
||||
|
||||
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||
batadv_ogm_packet->packet_type = BATADV_IV_OGM;
|
||||
|
|
@ -220,8 +224,9 @@ static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
|
|||
{
|
||||
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||
|
||||
kfree(hard_iface->bat_iv.ogm_buff);
|
||||
hard_iface->bat_iv.ogm_buff = NULL;
|
||||
kfree(hard_iface->bat_iv.ogm_buff.buf);
|
||||
memset(&hard_iface->bat_iv.ogm_buff, 0,
|
||||
sizeof(hard_iface->bat_iv.ogm_buff));
|
||||
|
||||
mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||
|
||||
|
|
@ -235,7 +240,7 @@ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
|
|||
|
||||
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||
|
||||
ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||
ogm_buff = hard_iface->bat_iv.ogm_buff.buf;
|
||||
if (!ogm_buff)
|
||||
goto unlock;
|
||||
|
||||
|
|
@ -257,7 +262,7 @@ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
|
|||
|
||||
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||
|
||||
ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||
ogm_buff = hard_iface->bat_iv.ogm_buff.buf;
|
||||
if (!ogm_buff)
|
||||
goto unlock;
|
||||
|
||||
|
|
@ -274,7 +279,7 @@ batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
|
|||
{
|
||||
unsigned int msecs;
|
||||
|
||||
msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
|
||||
msecs = READ_ONCE(bat_priv->orig_interval) - BATADV_JITTER;
|
||||
msecs += get_random_u32_below(2 * BATADV_JITTER);
|
||||
|
||||
return jiffies + msecs_to_jiffies(msecs);
|
||||
|
|
@ -289,7 +294,7 @@ static unsigned long batadv_iv_ogm_fwd_send_time(void)
|
|||
/* apply hop penalty for a normal link */
|
||||
static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
|
||||
{
|
||||
int hop_penalty = atomic_read(&bat_priv->hop_penalty);
|
||||
int hop_penalty = READ_ONCE(bat_priv->hop_penalty);
|
||||
int new_tq;
|
||||
|
||||
new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
|
||||
|
|
@ -555,7 +560,7 @@ static bool batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
|
|||
unsigned int skb_size;
|
||||
atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
|
||||
|
||||
if (atomic_read(&bat_priv->aggregated_ogms))
|
||||
if (READ_ONCE(bat_priv->aggregated_ogms))
|
||||
skb_size = max_t(unsigned int, BATADV_MAX_AGGREGATION_BYTES,
|
||||
packet_len);
|
||||
else
|
||||
|
|
@ -641,6 +646,7 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
|
|||
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||
bool direct_link;
|
||||
unsigned long max_aggregation_jiffies;
|
||||
bool aggregated_ogms;
|
||||
|
||||
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
|
||||
direct_link = !!(batadv_ogm_packet->flags & BATADV_DIRECTLINK);
|
||||
|
|
@ -648,8 +654,10 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
|
|||
|
||||
/* find position for the packet in the forward queue */
|
||||
spin_lock_bh(&bat_priv->forw_bat_list_lock);
|
||||
aggregated_ogms = READ_ONCE(bat_priv->aggregated_ogms);
|
||||
|
||||
/* own packets are not to be aggregated */
|
||||
if (atomic_read(&bat_priv->aggregated_ogms) && !own_packet) {
|
||||
if (aggregated_ogms && !own_packet) {
|
||||
hlist_for_each_entry(forw_packet_pos,
|
||||
&bat_priv->forw_bat_list, list) {
|
||||
if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
|
||||
|
|
@ -675,7 +683,7 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
|
|||
* we hold it back for a while, so that it might be aggregated
|
||||
* later on
|
||||
*/
|
||||
if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
|
||||
if (!own_packet && aggregated_ogms)
|
||||
send_time += max_aggregation_jiffies;
|
||||
|
||||
return batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
|
||||
|
|
@ -792,10 +800,9 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
|
|||
static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
|
||||
unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
|
||||
struct batadv_ogm_buf *ogm_buff = &hard_iface->bat_iv.ogm_buff;
|
||||
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||
struct batadv_hard_iface *primary_if, *tmp_hard_iface;
|
||||
int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
|
||||
struct list_head *iter;
|
||||
u32 seqno;
|
||||
u16 tvlv_len = 0;
|
||||
|
|
@ -807,7 +814,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
|||
lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
|
||||
|
||||
/* interface already disabled by batadv_iv_ogm_iface_disable */
|
||||
if (!*ogm_buff)
|
||||
if (!ogm_buff->buf)
|
||||
return;
|
||||
|
||||
/* the interface gets activated here to avoid race conditions between
|
||||
|
|
@ -826,9 +833,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
|||
* appended as it may alter the tt tvlv container
|
||||
*/
|
||||
batadv_tt_local_commit_changes(bat_priv);
|
||||
ret = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
|
||||
ogm_buff_len,
|
||||
BATADV_OGM_HLEN);
|
||||
ret = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff);
|
||||
if (ret < 0) {
|
||||
reschedule = true;
|
||||
goto out;
|
||||
|
|
@ -837,7 +842,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
|||
tvlv_len = ret;
|
||||
}
|
||||
|
||||
batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
|
||||
batadv_ogm_packet = ogm_buff->buf;
|
||||
batadv_ogm_packet->tvlv_len = htons(tvlv_len);
|
||||
|
||||
/* change sequence number to network order */
|
||||
|
|
@ -853,7 +858,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
|||
/* OGMs from secondary interfaces are only scheduled on their
|
||||
* respective interfaces.
|
||||
*/
|
||||
scheduled = batadv_iv_ogm_queue_add(bat_priv, *ogm_buff, *ogm_buff_len,
|
||||
scheduled = batadv_iv_ogm_queue_add(bat_priv, ogm_buff->buf, ogm_buff->len,
|
||||
hard_iface, hard_iface, 1, send_time);
|
||||
if (!scheduled)
|
||||
reschedule = true;
|
||||
|
|
@ -869,8 +874,8 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
|||
if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
|
||||
continue;
|
||||
|
||||
scheduled = batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
|
||||
*ogm_buff_len, hard_iface,
|
||||
scheduled = batadv_iv_ogm_queue_add(bat_priv, ogm_buff->buf,
|
||||
ogm_buff->len, hard_iface,
|
||||
tmp_hard_iface, 1, send_time);
|
||||
batadv_hardif_put(tmp_hard_iface);
|
||||
|
||||
|
|
@ -888,7 +893,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
|
|||
*/
|
||||
queue_delayed_work(batadv_event_workqueue,
|
||||
&hard_iface->bat_iv.reschedule_work,
|
||||
msecs_to_jiffies(atomic_read(&bat_priv->orig_interval)));
|
||||
msecs_to_jiffies(READ_ONCE(bat_priv->orig_interval)));
|
||||
}
|
||||
|
||||
batadv_hardif_put(primary_if);
|
||||
|
|
@ -1214,7 +1219,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
|
|||
inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
|
||||
inv_asym_penalty /= neigh_rq_max_cube;
|
||||
tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
|
||||
tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty);
|
||||
tq_iface_hop_penalty -= READ_ONCE(if_incoming->hop_penalty);
|
||||
|
||||
/* penalize if the OGM is forwarded on the same interface. WiFi
|
||||
* interfaces and other half duplex devices suffer from throughput
|
||||
|
|
@ -1773,7 +1778,7 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
|
|||
delayed_work);
|
||||
bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface);
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||
if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||
dropped = true;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -2321,7 +2326,7 @@ static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
|
|||
static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
|
||||
{
|
||||
/* set default TQ difference threshold to 20 */
|
||||
atomic_set(&bat_priv->gw.sel_class, 20);
|
||||
WRITE_ONCE(bat_priv->gw.sel_class, 20);
|
||||
}
|
||||
|
||||
static struct batadv_gw_node *
|
||||
|
|
@ -2353,7 +2358,7 @@ batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
|
|||
|
||||
tq_avg = router_ifinfo->bat_iv.tq_avg;
|
||||
|
||||
switch (atomic_read(&bat_priv->gw.sel_class)) {
|
||||
switch (READ_ONCE(bat_priv->gw.sel_class)) {
|
||||
case 1: /* fast connection */
|
||||
tmp_gw_factor = tq_avg * tq_avg;
|
||||
tmp_gw_factor *= gw_node->bandwidth_down;
|
||||
|
|
@ -2407,13 +2412,14 @@ static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
|
|||
{
|
||||
struct batadv_neigh_ifinfo *router_orig_ifinfo = NULL;
|
||||
struct batadv_neigh_ifinfo *router_gw_ifinfo = NULL;
|
||||
u32 sel_class = READ_ONCE(bat_priv->gw.sel_class);
|
||||
struct batadv_neigh_node *router_gw = NULL;
|
||||
struct batadv_neigh_node *router_orig = NULL;
|
||||
u8 gw_tq_avg, orig_tq_avg;
|
||||
bool ret = false;
|
||||
|
||||
/* dynamic re-election is performed only on fast or late switch */
|
||||
if (atomic_read(&bat_priv->gw.sel_class) <= 2)
|
||||
if (sel_class <= 2)
|
||||
return false;
|
||||
|
||||
router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
|
||||
|
|
@ -2448,8 +2454,7 @@ static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
|
|||
/* if the routing class is greater than 3 the value tells us how much
|
||||
* greater the TQ value of the new gateway must be
|
||||
*/
|
||||
if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
|
||||
(orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
|
||||
if (sel_class > 3 && orig_tq_avg - gw_tq_avg < sel_class)
|
||||
goto out;
|
||||
|
||||
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#include "bat_v.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -505,7 +505,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
|
|||
static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
|
||||
{
|
||||
/* set default throughput difference threshold to 5Mbps */
|
||||
atomic_set(&bat_priv->gw.sel_class, 50);
|
||||
WRITE_ONCE(bat_priv->gw.sel_class, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -602,7 +602,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
|
|||
u32 gw_throughput, orig_throughput, threshold;
|
||||
bool ret = false;
|
||||
|
||||
threshold = atomic_read(&bat_priv->gw.sel_class);
|
||||
threshold = READ_ONCE(bat_priv->gw.sel_class);
|
||||
|
||||
curr_gw = batadv_gw_node_get(bat_priv, curr_gw_orig);
|
||||
if (!curr_gw) {
|
||||
|
|
@ -812,8 +812,8 @@ void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface)
|
|||
/* enable link throughput auto-detection by setting the throughput
|
||||
* override to zero
|
||||
*/
|
||||
atomic_set(&hard_iface->bat_v.throughput_override, 0);
|
||||
atomic_set(&hard_iface->bat_v.elp_interval, 500);
|
||||
WRITE_ONCE(hard_iface->bat_v.throughput_override, 0);
|
||||
WRITE_ONCE(hard_iface->bat_v.elp_interval, 500);
|
||||
|
||||
hard_iface->bat_v.aggr_len = 0;
|
||||
skb_queue_head_init(&hard_iface->bat_v.aggr_list);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
@ -62,7 +63,7 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
|
|||
{
|
||||
unsigned int msecs;
|
||||
|
||||
msecs = atomic_read(&hard_iface->bat_v.elp_interval) - BATADV_JITTER;
|
||||
msecs = READ_ONCE(hard_iface->bat_v.elp_interval) - BATADV_JITTER;
|
||||
msecs += get_random_u32_below(2 * BATADV_JITTER);
|
||||
|
||||
queue_delayed_work(batadv_event_workqueue, &hard_iface->bat_v.elp_wq,
|
||||
|
|
@ -85,6 +86,7 @@ static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh,
|
|||
struct ethtool_link_ksettings link_settings;
|
||||
struct net_device *real_netdev;
|
||||
struct station_info sinfo;
|
||||
u32 wifi_flags;
|
||||
u32 throughput;
|
||||
int ret;
|
||||
|
||||
|
|
@ -97,7 +99,7 @@ static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh,
|
|||
/* if the user specified a customised value for this interface, then
|
||||
* return it directly
|
||||
*/
|
||||
throughput = atomic_read(&hard_iface->bat_v.throughput_override);
|
||||
throughput = READ_ONCE(hard_iface->bat_v.throughput_override);
|
||||
if (throughput != 0) {
|
||||
*pthroughput = throughput;
|
||||
return true;
|
||||
|
|
@ -106,8 +108,9 @@ static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh,
|
|||
/* if this is a wireless device, then ask its throughput through
|
||||
* cfg80211 API
|
||||
*/
|
||||
if (batadv_is_wifi_hardif(hard_iface)) {
|
||||
if (!batadv_is_cfg80211_hardif(hard_iface))
|
||||
wifi_flags = batadv_hardif_get_wifi_flags(hard_iface);
|
||||
if (batadv_is_wifi(wifi_flags)) {
|
||||
if (!batadv_is_cfg80211(wifi_flags))
|
||||
/* unsupported WiFi driver version */
|
||||
goto default_throughput;
|
||||
|
||||
|
|
@ -304,7 +307,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
|
|||
hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
|
||||
bat_priv = netdev_priv(hard_iface->mesh_iface);
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||
if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||
goto out;
|
||||
|
||||
/* we are in the process of shutting this interface down */
|
||||
|
|
@ -322,7 +325,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
|
|||
|
||||
elp_packet = (struct batadv_elp_packet *)skb->data;
|
||||
elp_packet->seqno = htonl(atomic_read(&hard_iface->bat_v.elp_seqno));
|
||||
elp_interval = atomic_read(&hard_iface->bat_v.elp_interval);
|
||||
elp_interval = READ_ONCE(hard_iface->bat_v.elp_interval);
|
||||
elp_packet->elp_interval = htonl(elp_interval);
|
||||
|
||||
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
@ -105,7 +107,7 @@ static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)
|
|||
if (delayed_work_pending(&bat_priv->bat_v.ogm_wq))
|
||||
return;
|
||||
|
||||
msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
|
||||
msecs = READ_ONCE(bat_priv->orig_interval) - BATADV_JITTER;
|
||||
msecs += get_random_u32_below(2 * BATADV_JITTER);
|
||||
queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq,
|
||||
msecs_to_jiffies(msecs));
|
||||
|
|
@ -246,7 +248,7 @@ static void batadv_v_ogm_queue_on_if(struct batadv_priv *bat_priv,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!atomic_read(&bat_priv->aggregated_ogms)) {
|
||||
if (!READ_ONCE(bat_priv->aggregated_ogms)) {
|
||||
batadv_v_ogm_send_to_if(bat_priv, skb, hard_iface);
|
||||
return;
|
||||
}
|
||||
|
|
@ -268,39 +270,35 @@ static void batadv_v_ogm_send_meshif(struct batadv_priv *bat_priv)
|
|||
{
|
||||
struct batadv_hard_iface *hard_iface;
|
||||
struct batadv_ogm2_packet *ogm_packet;
|
||||
struct batadv_ogm_buf *ogm_buff;
|
||||
struct sk_buff *skb, *skb_tmp;
|
||||
unsigned char **ogm_buff;
|
||||
struct list_head *iter;
|
||||
int *ogm_buff_len;
|
||||
u16 tvlv_len;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||
if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
|
||||
goto out;
|
||||
|
||||
ogm_buff = &bat_priv->bat_v.ogm_buff;
|
||||
ogm_buff_len = &bat_priv->bat_v.ogm_buff_len;
|
||||
|
||||
/* tt changes have to be committed before the tvlv data is
|
||||
* appended as it may alter the tt tvlv container
|
||||
*/
|
||||
batadv_tt_local_commit_changes(bat_priv);
|
||||
ret = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff,
|
||||
ogm_buff_len,
|
||||
BATADV_OGM2_HLEN);
|
||||
ret = batadv_tvlv_container_ogm_append(bat_priv, ogm_buff);
|
||||
if (ret < 0)
|
||||
goto reschedule;
|
||||
|
||||
tvlv_len = ret;
|
||||
|
||||
skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + *ogm_buff_len);
|
||||
skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + ogm_buff->len);
|
||||
if (!skb)
|
||||
goto reschedule;
|
||||
|
||||
skb_reserve(skb, ETH_HLEN);
|
||||
skb_put_data(skb, *ogm_buff, *ogm_buff_len);
|
||||
skb_put_data(skb, ogm_buff->buf, ogm_buff->len);
|
||||
|
||||
ogm_packet = (struct batadv_ogm2_packet *)skb->data;
|
||||
ogm_packet->seqno = htonl(atomic_read(&bat_priv->bat_v.ogm_seqno));
|
||||
|
|
@ -446,10 +444,10 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
|
|||
struct batadv_ogm2_packet *ogm_packet;
|
||||
|
||||
mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||
if (!bat_priv->bat_v.ogm_buff)
|
||||
if (!bat_priv->bat_v.ogm_buff.buf)
|
||||
goto unlock;
|
||||
|
||||
ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
|
||||
ogm_packet = bat_priv->bat_v.ogm_buff.buf;
|
||||
ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
|
||||
|
||||
unlock:
|
||||
|
|
@ -484,9 +482,9 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
|
|||
struct batadv_hard_iface *if_outgoing,
|
||||
u32 throughput)
|
||||
{
|
||||
int if_hop_penalty = atomic_read(&if_incoming->hop_penalty);
|
||||
int hop_penalty = atomic_read(&bat_priv->hop_penalty);
|
||||
int hop_penalty_max = BATADV_TQ_MAX_VALUE;
|
||||
u32 if_hop_penalty = READ_ONCE(if_incoming->hop_penalty);
|
||||
u32 hop_penalty = READ_ONCE(bat_priv->hop_penalty);
|
||||
u32 hop_penalty_max = BATADV_TQ_MAX_VALUE;
|
||||
|
||||
/* Apply per hardif hop penalty */
|
||||
throughput = throughput * (hop_penalty_max - if_hop_penalty) /
|
||||
|
|
@ -721,7 +719,7 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
|
|||
* don't route towards it
|
||||
*/
|
||||
router = batadv_orig_router_get(orig_node, if_outgoing);
|
||||
if (router && router->orig_node != orig_node && !orig_neigh_router) {
|
||||
if (router && ACCESS_PRIVATE(router, orig_node_id) != orig_node && !orig_neigh_router) {
|
||||
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||
"Drop packet: OGM via unknown neighbor!\n");
|
||||
goto out;
|
||||
|
|
@ -1050,12 +1048,15 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
|
|||
unsigned char *ogm_buff;
|
||||
u32 random_seqno;
|
||||
|
||||
bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
|
||||
ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
|
||||
bat_priv->bat_v.ogm_buff.len = BATADV_OGM2_HLEN;
|
||||
bat_priv->bat_v.ogm_buff.capacity = BATADV_OGM2_HLEN;
|
||||
bat_priv->bat_v.ogm_buff.header_length = BATADV_OGM2_HLEN;
|
||||
|
||||
ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff.capacity, GFP_ATOMIC);
|
||||
if (!ogm_buff)
|
||||
return -ENOMEM;
|
||||
|
||||
bat_priv->bat_v.ogm_buff = ogm_buff;
|
||||
bat_priv->bat_v.ogm_buff.buf = ogm_buff;
|
||||
ogm_packet = (struct batadv_ogm2_packet *)ogm_buff;
|
||||
ogm_packet->packet_type = BATADV_OGM2;
|
||||
ogm_packet->version = BATADV_COMPAT_VERSION;
|
||||
|
|
@ -1083,9 +1084,8 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv)
|
|||
|
||||
mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||
|
||||
kfree(bat_priv->bat_v.ogm_buff);
|
||||
bat_priv->bat_v.ogm_buff = NULL;
|
||||
bat_priv->bat_v.ogm_buff_len = 0;
|
||||
kfree(bat_priv->bat_v.ogm_buff.buf);
|
||||
memset(&bat_priv->bat_v.ogm_buff, 0, sizeof(bat_priv->bat_v.ogm_buff));
|
||||
|
||||
mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/container_of.h>
|
||||
|
|
@ -1379,7 +1380,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
|
|||
bat_priv->bla.claim_dest.group = group;
|
||||
|
||||
/* purge everything when bridge loop avoidance is turned off */
|
||||
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
|
||||
oldif = NULL;
|
||||
|
||||
if (!oldif) {
|
||||
|
|
@ -1483,7 +1484,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)
|
|||
batadv_bla_purge_claims(bat_priv, primary_if, 0);
|
||||
batadv_bla_purge_backbone_gw(bat_priv, 0);
|
||||
|
||||
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
|
||||
goto out;
|
||||
|
||||
if (atomic_dec_and_test(&bat_priv->bla.loopdetect_next)) {
|
||||
|
|
@ -1782,7 +1783,7 @@ bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
|
|||
struct batadv_bla_backbone_gw *backbone_gw;
|
||||
int i;
|
||||
|
||||
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
|
||||
return false;
|
||||
|
||||
if (!hash)
|
||||
|
|
@ -1820,7 +1821,7 @@ bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
|
|||
struct batadv_bla_backbone_gw *backbone_gw;
|
||||
unsigned short vid;
|
||||
|
||||
if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(orig_node->bat_priv->bridge_loop_avoidance))
|
||||
return false;
|
||||
|
||||
/* first, find out the vid. */
|
||||
|
|
@ -1952,7 +1953,7 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||
if (!primary_if)
|
||||
goto handled;
|
||||
|
||||
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
|
||||
goto allow;
|
||||
|
||||
if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid))
|
||||
|
|
@ -2084,7 +2085,7 @@ bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||
if (!primary_if)
|
||||
goto out;
|
||||
|
||||
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
|
||||
goto allow;
|
||||
|
||||
if (batadv_bla_process_claim(bat_priv, primary_if, skb))
|
||||
|
|
@ -2504,7 +2505,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv,
|
|||
struct batadv_hard_iface *primary_if = NULL;
|
||||
bool ret = true;
|
||||
|
||||
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
|
||||
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
|
||||
return ret;
|
||||
|
||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/err.h>
|
||||
|
|
@ -742,7 +743,7 @@ static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv)
|
|||
{
|
||||
char dat_mode;
|
||||
|
||||
dat_mode = atomic_read(&bat_priv->distributed_arp_table);
|
||||
dat_mode = READ_ONCE(bat_priv->distributed_arp_table);
|
||||
|
||||
switch (dat_mode) {
|
||||
case 0:
|
||||
|
|
@ -1138,7 +1139,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
|||
int hdr_size = 0;
|
||||
unsigned short vid;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
|
@ -1233,7 +1234,7 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
|||
unsigned short vid;
|
||||
int err;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
|
@ -1295,7 +1296,7 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
|
|||
int hdr_size = 0;
|
||||
unsigned short vid;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
return;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
|
@ -1343,7 +1344,7 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
|
|||
bool dropped = false;
|
||||
unsigned short vid;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
|
@ -1713,7 +1714,7 @@ void batadv_dat_snoop_outgoing_dhcp_ack(struct batadv_priv *bat_priv,
|
|||
u8 chaddr[BATADV_DHCP_CHADDR_LEN];
|
||||
__be32 ip_src, yiaddr;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
return;
|
||||
|
||||
if (!batadv_dat_check_dhcp_ack(skb, proto, &ip_src, chaddr, &yiaddr))
|
||||
|
|
@ -1743,7 +1744,7 @@ void batadv_dat_snoop_incoming_dhcp_ack(struct batadv_priv *bat_priv,
|
|||
__be16 proto;
|
||||
u8 *hw_src;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
return;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN)))
|
||||
|
|
@ -1788,7 +1789,7 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
|
|||
int hdr_size = sizeof(struct batadv_bcast_packet);
|
||||
unsigned short vid;
|
||||
|
||||
if (!atomic_read(&bat_priv->distributed_arp_table))
|
||||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
/* If this packet is an ARP_REQUEST and the node already has the
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/err.h>
|
||||
|
|
@ -170,7 +171,7 @@ void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
|
|||
{
|
||||
struct batadv_gw_node *curr_gw;
|
||||
|
||||
if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
|
||||
if (READ_ONCE(bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
|
||||
return;
|
||||
|
||||
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
|
||||
|
|
@ -202,7 +203,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
|
|||
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
|
||||
char gw_addr[18] = { '\0' };
|
||||
|
||||
if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
|
||||
if (READ_ONCE(bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
|
||||
goto out;
|
||||
|
||||
if (!bat_priv->algo_ops->gw.get_best_gw_node)
|
||||
|
|
@ -210,7 +211,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
|
|||
|
||||
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
|
||||
|
||||
if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw)
|
||||
if (atomic_xchg(&bat_priv->gw.reselect, 0) == 0 && curr_gw)
|
||||
goto out;
|
||||
|
||||
/* if gw.reselect is set to 1 it means that a previous call to
|
||||
|
|
@ -702,7 +703,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
|
|||
if (!gw_node)
|
||||
goto out;
|
||||
|
||||
switch (atomic_read(&bat_priv->gw.mode)) {
|
||||
switch (READ_ONCE(bat_priv->gw.mode)) {
|
||||
case BATADV_GW_MODE_SERVER:
|
||||
/* If we are a GW then we are our best GW. We can artificially
|
||||
* set the tq towards ourself as the maximum value
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#include "gateway_common.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <uapi/linux/batadv_packet.h>
|
||||
|
|
@ -25,10 +25,10 @@
|
|||
void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
|
||||
{
|
||||
struct batadv_tvlv_gateway_data gw;
|
||||
enum batadv_gw_modes gw_mode;
|
||||
u32 down, up;
|
||||
char gw_mode;
|
||||
|
||||
gw_mode = atomic_read(&bat_priv->gw.mode);
|
||||
gw_mode = READ_ONCE(bat_priv->gw.mode);
|
||||
|
||||
switch (gw_mode) {
|
||||
case BATADV_GW_MODE_OFF:
|
||||
|
|
@ -36,8 +36,8 @@ void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
|
|||
batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
|
||||
break;
|
||||
case BATADV_GW_MODE_SERVER:
|
||||
down = atomic_read(&bat_priv->gw.bandwidth_down);
|
||||
up = atomic_read(&bat_priv->gw.bandwidth_up);
|
||||
down = READ_ONCE(bat_priv->gw.bandwidth_down);
|
||||
up = READ_ONCE(bat_priv->gw.bandwidth_up);
|
||||
gw.bandwidth_down = htonl(down);
|
||||
gw.bandwidth_up = htonl(up);
|
||||
batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
|
||||
|
|
@ -83,7 +83,7 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
|
|||
|
||||
/* restart gateway selection */
|
||||
if (gateway.bandwidth_down != 0 &&
|
||||
atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT)
|
||||
READ_ONCE(bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT)
|
||||
batadv_gw_check_election(bat_priv, orig);
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ void batadv_gw_init(struct batadv_priv *bat_priv)
|
|||
if (bat_priv->algo_ops->gw.init_sel_class)
|
||||
bat_priv->algo_ops->gw.init_sel_class(bat_priv);
|
||||
else
|
||||
atomic_set(&bat_priv->gw.sel_class, 1);
|
||||
WRITE_ONCE(bat_priv->gw.sel_class, 1);
|
||||
|
||||
batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
|
||||
NULL, NULL, BATADV_TVLV_GW, 1,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include "hard-interface.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/container_of.h>
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
#include <linux/notifier.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/rhashtable-types.h>
|
||||
#include <linux/rhashtable.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
|
@ -42,6 +44,15 @@
|
|||
#include "send.h"
|
||||
#include "translation-table.h"
|
||||
|
||||
static const struct rhashtable_params batadv_wifi_net_devices_params = {
|
||||
.key_len = sizeof(struct net_device *),
|
||||
.key_offset = offsetof(struct batadv_wifi_net_device_state, netdev),
|
||||
.head_offset = offsetof(struct batadv_wifi_net_device_state, l),
|
||||
.automatic_shrinking = true,
|
||||
};
|
||||
|
||||
static struct rhashtable batadv_wifi_net_devices;
|
||||
|
||||
/**
|
||||
* batadv_hardif_release() - release hard interface from lists and queue for
|
||||
* free after rcu grace period
|
||||
|
|
@ -355,21 +366,28 @@ static u32 batadv_wifi_flags_evaluate(struct net_device *net_device)
|
|||
}
|
||||
|
||||
/**
|
||||
* batadv_is_cfg80211_hardif() - check if the given hardif is a cfg80211 wifi
|
||||
* interface
|
||||
* batadv_hardif_get_wifi_flags() - retrieve wifi flags for hard_iface
|
||||
* @hard_iface: the device to check
|
||||
*
|
||||
* Return: true if the net device is a cfg80211 wireless device, false
|
||||
* otherwise.
|
||||
* Return: batadv_hard_iface_wifi_flags flags of the device
|
||||
*/
|
||||
bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
|
||||
u32 batadv_hardif_get_wifi_flags(struct batadv_hard_iface *hard_iface)
|
||||
{
|
||||
u32 allowed_flags = 0;
|
||||
struct batadv_wifi_net_device_state *device_state;
|
||||
u32 wifi_flags = 0;
|
||||
|
||||
allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
|
||||
allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
|
||||
if (!hard_iface)
|
||||
return 0;
|
||||
|
||||
return !!(hard_iface->wifi_flags & allowed_flags);
|
||||
rcu_read_lock();
|
||||
device_state = rhashtable_lookup_fast(&batadv_wifi_net_devices,
|
||||
&hard_iface->net_dev,
|
||||
batadv_wifi_net_devices_params);
|
||||
if (device_state)
|
||||
wifi_flags = READ_ONCE(device_state->wifi_flags);
|
||||
rcu_read_unlock();
|
||||
|
||||
return wifi_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -380,10 +398,9 @@ bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
|
|||
*/
|
||||
bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
|
||||
{
|
||||
if (!hard_iface)
|
||||
return false;
|
||||
u32 wifi_flags = batadv_hardif_get_wifi_flags(hard_iface);
|
||||
|
||||
return hard_iface->wifi_flags != 0;
|
||||
return batadv_is_wifi(wifi_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -594,7 +611,7 @@ int batadv_hardif_min_mtu(struct net_device *mesh_iface)
|
|||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (atomic_read(&bat_priv->fragmentation) == 0)
|
||||
if (READ_ONCE(bat_priv->fragmentation) == 0)
|
||||
goto out;
|
||||
|
||||
/* with fragmentation enabled the maximum size of internally generated
|
||||
|
|
@ -611,7 +628,7 @@ int batadv_hardif_min_mtu(struct net_device *mesh_iface)
|
|||
* overhead). For example, this value is used by TT to compute the
|
||||
* maximum local table size
|
||||
*/
|
||||
atomic_set(&bat_priv->packet_size_max, min_mtu);
|
||||
WRITE_ONCE(bat_priv->packet_size_max, min_mtu);
|
||||
|
||||
/* the real mesh-interface MTU is computed by removing the payload
|
||||
* overhead from the maximum amount of bytes that was just computed.
|
||||
|
|
@ -709,6 +726,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
|
|||
int max_header_len = batadv_max_header_len();
|
||||
unsigned int required_mtu;
|
||||
unsigned int hardif_mtu;
|
||||
bool fragmentation;
|
||||
int ret;
|
||||
|
||||
hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
|
||||
|
|
@ -746,15 +764,14 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
|
|||
batadv_info(hard_iface->mesh_iface, "Adding interface: %s\n",
|
||||
hard_iface->net_dev->name);
|
||||
|
||||
if (atomic_read(&bat_priv->fragmentation) &&
|
||||
hardif_mtu < required_mtu)
|
||||
fragmentation = READ_ONCE(bat_priv->fragmentation);
|
||||
if (fragmentation && hardif_mtu < required_mtu)
|
||||
batadv_info(hard_iface->mesh_iface,
|
||||
"The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to %i would solve the problem.\n",
|
||||
hard_iface->net_dev->name, hardif_mtu,
|
||||
required_mtu);
|
||||
|
||||
if (!atomic_read(&bat_priv->fragmentation) &&
|
||||
hardif_mtu < required_mtu)
|
||||
if (!fragmentation && hardif_mtu < required_mtu)
|
||||
batadv_info(hard_iface->mesh_iface,
|
||||
"The MTU of interface %s is too small (%i) to handle the transport of batman-adv packets. If you experience problems getting traffic through try increasing the MTU to %i.\n",
|
||||
hard_iface->net_dev->name, hardif_mtu,
|
||||
|
|
@ -889,11 +906,10 @@ batadv_hardif_add_interface(struct net_device *net_dev)
|
|||
kref_init(&hard_iface->refcount);
|
||||
|
||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
|
||||
hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
|
||||
if (batadv_is_wifi_hardif(hard_iface))
|
||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
|
||||
|
||||
atomic_set(&hard_iface->hop_penalty, 0);
|
||||
WRITE_ONCE(hard_iface->hop_penalty, 0);
|
||||
|
||||
batadv_v_hardif_init(hard_iface);
|
||||
|
||||
|
|
@ -941,6 +957,131 @@ static int batadv_hard_if_event_meshif(unsigned long event,
|
|||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_device_insert() - save information about wifi net_device
|
||||
* @net_dev: net_device to add to batadv_wifi_net_devices
|
||||
* @wifi_flags: net_device which generated an event
|
||||
*
|
||||
* Return: 0 on result, negative value on error
|
||||
*/
|
||||
static int
|
||||
batadv_wifi_net_device_insert(struct net_device *net_dev, u32 wifi_flags)
|
||||
{
|
||||
struct batadv_wifi_net_device_state *device_state;
|
||||
int ret;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
device_state = kzalloc_obj(*device_state, GFP_ATOMIC);
|
||||
if (!device_state)
|
||||
return -ENOMEM;
|
||||
|
||||
device_state->wifi_flags = wifi_flags;
|
||||
netdev_hold(net_dev, &device_state->dev_tracker, GFP_ATOMIC);
|
||||
device_state->netdev = net_dev;
|
||||
WRITE_ONCE(device_state->wifi_flags, wifi_flags);
|
||||
|
||||
ret = rhashtable_insert_fast(&batadv_wifi_net_devices, &device_state->l,
|
||||
batadv_wifi_net_devices_params);
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
netdev_put(device_state->netdev, &device_state->dev_tracker);
|
||||
kfree(device_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_device_remove() - remove information about wifi net_device
|
||||
* @device_state: wifi net_device state to remove from batadv_wifi_net_device_state
|
||||
*/
|
||||
static void
|
||||
batadv_wifi_net_device_remove(struct batadv_wifi_net_device_state *device_state)
|
||||
{
|
||||
ASSERT_RTNL();
|
||||
|
||||
rhashtable_remove_fast(&batadv_wifi_net_devices, &device_state->l,
|
||||
batadv_wifi_net_devices_params);
|
||||
netdev_put(device_state->netdev, &device_state->dev_tracker);
|
||||
kfree_rcu(device_state, rcu);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_device_update() - update wifi state of net_device
|
||||
* @net_dev: net_device to update in batadv_wifi_net_devices
|
||||
*
|
||||
* The device will only be stored in batadv_wifi_net_devices when
|
||||
* it could be identified as wifi device. If the net_device is no
|
||||
* longer a wifi device, it is automatically removed from
|
||||
* batadv_wifi_net_devices.
|
||||
*/
|
||||
static void
|
||||
batadv_wifi_net_device_update(struct net_device *net_dev)
|
||||
{
|
||||
struct batadv_wifi_net_device_state *device_state;
|
||||
u32 wifi_flags;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
wifi_flags = batadv_wifi_flags_evaluate(net_dev);
|
||||
device_state = rhashtable_lookup_fast(&batadv_wifi_net_devices,
|
||||
&net_dev,
|
||||
batadv_wifi_net_devices_params);
|
||||
|
||||
if (device_state) {
|
||||
if (batadv_is_wifi(wifi_flags))
|
||||
WRITE_ONCE(device_state->wifi_flags, wifi_flags);
|
||||
else
|
||||
batadv_wifi_net_device_remove(device_state);
|
||||
} else if (batadv_is_wifi(wifi_flags)) {
|
||||
batadv_wifi_net_device_insert(net_dev, wifi_flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_device_unregister() - remove wifi state of net_device
|
||||
* @net_dev: net_device to remove from batadv_wifi_net_devices
|
||||
*/
|
||||
static void
|
||||
batadv_wifi_net_device_unregister(struct net_device *net_dev)
|
||||
{
|
||||
struct batadv_wifi_net_device_state *device_state;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
device_state = rhashtable_lookup_fast(&batadv_wifi_net_devices,
|
||||
&net_dev,
|
||||
batadv_wifi_net_devices_params);
|
||||
if (!device_state)
|
||||
return;
|
||||
|
||||
batadv_wifi_net_device_remove(device_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_device_event() - handle network events for batadv_wifi_net_devices
|
||||
* @event: enum netdev_cmd event to handle
|
||||
* @net_dev: net_device to update in batadv_wifi_net_devices
|
||||
*/
|
||||
static void batadv_wifi_net_device_event(unsigned long event,
|
||||
struct net_device *net_dev)
|
||||
{
|
||||
switch (event) {
|
||||
case NETDEV_REGISTER:
|
||||
case NETDEV_POST_TYPE_CHANGE:
|
||||
case NETDEV_CHANGEUPPER:
|
||||
batadv_wifi_net_device_update(net_dev);
|
||||
break;
|
||||
case NETDEV_UNREGISTER:
|
||||
case NETDEV_PRE_TYPE_CHANGE:
|
||||
batadv_wifi_net_device_unregister(net_dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int batadv_hard_if_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
|
|
@ -952,6 +1093,8 @@ static int batadv_hard_if_event(struct notifier_block *this,
|
|||
if (batadv_meshif_is_valid(net_dev))
|
||||
return batadv_hard_if_event_meshif(event, net_dev);
|
||||
|
||||
batadv_wifi_net_device_event(event, net_dev);
|
||||
|
||||
hard_iface = batadv_hardif_get_by_netdev(net_dev);
|
||||
if (!hard_iface && (event == NETDEV_REGISTER ||
|
||||
event == NETDEV_POST_TYPE_CHANGE))
|
||||
|
|
@ -995,8 +1138,9 @@ static int batadv_hard_if_event(struct notifier_block *this,
|
|||
if (hard_iface == primary_if)
|
||||
batadv_primary_if_update_addr(bat_priv, NULL);
|
||||
break;
|
||||
case NETDEV_REGISTER:
|
||||
case NETDEV_POST_TYPE_CHANGE:
|
||||
case NETDEV_CHANGEUPPER:
|
||||
hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
|
||||
if (batadv_is_wifi_hardif(hard_iface))
|
||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
|
||||
break;
|
||||
|
|
@ -1014,3 +1158,22 @@ static int batadv_hard_if_event(struct notifier_block *this,
|
|||
struct notifier_block batadv_hard_if_notifier = {
|
||||
.notifier_call = batadv_hard_if_event,
|
||||
};
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_devices_init() - Initialize wifi devices cache
|
||||
*
|
||||
* Return: 0 on success, negative error code on failure
|
||||
*/
|
||||
int __init batadv_wifi_net_devices_init(void)
|
||||
{
|
||||
return rhashtable_init(&batadv_wifi_net_devices,
|
||||
&batadv_wifi_net_devices_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_wifi_net_devices_deinit() - Deinitialize wifi devices cache
|
||||
*/
|
||||
void batadv_wifi_net_devices_deinit(void)
|
||||
{
|
||||
rhashtable_destroy(&batadv_wifi_net_devices);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
|
@ -69,7 +70,7 @@ extern struct notifier_block batadv_hard_if_notifier;
|
|||
|
||||
struct net_device *__batadv_get_real_netdev(struct net_device *net_device);
|
||||
struct net_device *batadv_get_real_netdev(struct net_device *net_device);
|
||||
bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface);
|
||||
u32 batadv_hardif_get_wifi_flags(struct batadv_hard_iface *hard_iface);
|
||||
bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface);
|
||||
struct batadv_hard_iface*
|
||||
batadv_hardif_get_by_netdev(const struct net_device *net_dev);
|
||||
|
|
@ -81,6 +82,8 @@ void batadv_update_min_mtu(struct net_device *mesh_iface);
|
|||
void batadv_hardif_release(struct kref *ref);
|
||||
int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
|
||||
u8 *orig_addr, u8 *orig_neigh);
|
||||
int __init batadv_wifi_net_devices_init(void);
|
||||
void batadv_wifi_net_devices_deinit(void);
|
||||
|
||||
/**
|
||||
* batadv_hardif_put() - decrement the hard interface refcounter and possibly
|
||||
|
|
@ -119,4 +122,33 @@ batadv_primary_if_get_selected(struct batadv_priv *bat_priv)
|
|||
return hard_iface;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_is_cfg80211() - check if the given hardif is a cfg80211
|
||||
* wifi interface
|
||||
* @wifi_flags: extracted batadv_hard_iface_wifi_flagss of an net_device
|
||||
*
|
||||
* Return: true if the net device is a cfg80211 wireless device, false
|
||||
* otherwise.
|
||||
*/
|
||||
static inline bool batadv_is_cfg80211(u32 wifi_flags)
|
||||
{
|
||||
u32 allowed_flags = 0;
|
||||
|
||||
allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
|
||||
allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
|
||||
|
||||
return !!(wifi_flags & allowed_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_is_wifi() - check if flags belong to wifi interface
|
||||
* @wifi_flags: extracted batadv_hard_iface_wifi_flagss of an net_device
|
||||
*
|
||||
* Return: true if the net device is a 802.11 wireless device, false otherwise.
|
||||
*/
|
||||
static inline bool batadv_is_wifi(u32 wifi_flags)
|
||||
{
|
||||
return wifi_flags != 0;
|
||||
}
|
||||
|
||||
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ __printf(2, 3);
|
|||
#define _batadv_dbg(type, bat_priv, ratelimited, fmt, arg...) \
|
||||
do { \
|
||||
struct batadv_priv *__batpriv = (bat_priv); \
|
||||
if (atomic_read(&__batpriv->log_level) & (type) && \
|
||||
if (READ_ONCE(__batpriv->log_level) & (type) && \
|
||||
(!(ratelimited) || net_ratelimit())) \
|
||||
batadv_debug_log(__batpriv, fmt, ## arg); \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/sprintf.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/dsfield.h>
|
||||
#include <net/genetlink.h>
|
||||
|
|
@ -104,22 +105,33 @@ static int __init batadv_init(void)
|
|||
batadv_tp_meter_init();
|
||||
|
||||
batadv_event_workqueue = create_singlethread_workqueue("bat_events");
|
||||
if (!batadv_event_workqueue)
|
||||
if (!batadv_event_workqueue) {
|
||||
ret = -ENOMEM;
|
||||
goto err_create_wq;
|
||||
}
|
||||
|
||||
ret = batadv_wifi_net_devices_init();
|
||||
if (ret < 0)
|
||||
goto err_init_wifi;
|
||||
|
||||
register_netdevice_notifier(&batadv_hard_if_notifier);
|
||||
rtnl_link_register(&batadv_link_ops);
|
||||
batadv_netlink_register();
|
||||
|
||||
pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
|
||||
BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
|
||||
init_utsname()->release, BATADV_COMPAT_VERSION);
|
||||
|
||||
return 0;
|
||||
|
||||
err_init_wifi:
|
||||
destroy_workqueue(batadv_event_workqueue);
|
||||
batadv_event_workqueue = NULL;
|
||||
rcu_barrier();
|
||||
|
||||
err_create_wq:
|
||||
batadv_tt_cache_destroy();
|
||||
|
||||
return -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit batadv_exit(void)
|
||||
|
|
@ -133,6 +145,7 @@ static void __exit batadv_exit(void)
|
|||
|
||||
rcu_barrier();
|
||||
|
||||
batadv_wifi_net_devices_deinit();
|
||||
batadv_tt_cache_destroy();
|
||||
}
|
||||
|
||||
|
|
@ -187,31 +200,31 @@ int batadv_mesh_init(struct net_device *mesh_iface)
|
|||
|
||||
ret = batadv_originator_init(bat_priv);
|
||||
if (ret < 0) {
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
goto err_orig;
|
||||
}
|
||||
|
||||
ret = batadv_tt_init(bat_priv);
|
||||
if (ret < 0) {
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
goto err_tt;
|
||||
}
|
||||
|
||||
ret = batadv_v_mesh_init(bat_priv);
|
||||
if (ret < 0) {
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
goto err_v;
|
||||
}
|
||||
|
||||
ret = batadv_bla_init(bat_priv);
|
||||
if (ret < 0) {
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
goto err_bla;
|
||||
}
|
||||
|
||||
ret = batadv_dat_init(bat_priv);
|
||||
if (ret < 0) {
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
goto err_dat;
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +232,7 @@ int batadv_mesh_init(struct net_device *mesh_iface)
|
|||
batadv_mcast_init(bat_priv);
|
||||
|
||||
atomic_set(&bat_priv->gw.reselect, 0);
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_ACTIVE);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -233,7 +246,7 @@ int batadv_mesh_init(struct net_device *mesh_iface)
|
|||
batadv_originator_free(bat_priv);
|
||||
err_orig:
|
||||
batadv_purge_outstanding_packets(bat_priv, NULL);
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -246,7 +259,7 @@ void batadv_mesh_free(struct net_device *mesh_iface)
|
|||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
|
||||
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
|
||||
|
||||
batadv_purge_outstanding_packets(bat_priv, NULL);
|
||||
batadv_tp_stop_all(bat_priv);
|
||||
|
|
@ -277,7 +290,7 @@ void batadv_mesh_free(struct net_device *mesh_iface)
|
|||
free_percpu(bat_priv->bat_counters);
|
||||
bat_priv->bat_counters = NULL;
|
||||
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -441,7 +454,7 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
|||
|
||||
bat_priv = netdev_priv(hard_iface->mesh_iface);
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
goto err_free;
|
||||
|
||||
/* discard frames on not active interfaces */
|
||||
|
|
@ -614,7 +627,7 @@ bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid)
|
|||
*/
|
||||
vlan = batadv_meshif_vlan_get(bat_priv, vid);
|
||||
if (vlan) {
|
||||
ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
|
||||
ap_isolation_enabled = READ_ONCE(vlan->ap_isolation);
|
||||
batadv_meshif_vlan_put(vlan);
|
||||
}
|
||||
|
||||
|
|
@ -684,6 +697,5 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
MODULE_AUTHOR(BATADV_DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(BATADV_DRIVER_DESC);
|
||||
MODULE_VERSION(BATADV_SOURCE_VERSION);
|
||||
MODULE_ALIAS_RTNL_LINK("batadv");
|
||||
MODULE_ALIAS_GENL_FAMILY(BATADV_NL_NAME);
|
||||
|
|
|
|||
|
|
@ -12,10 +12,6 @@
|
|||
#define BATADV_DRIVER_DESC "B.A.T.M.A.N. advanced"
|
||||
#define BATADV_DRIVER_DEVICE "batman-adv"
|
||||
|
||||
#ifndef BATADV_SOURCE_VERSION
|
||||
#define BATADV_SOURCE_VERSION "2025.5"
|
||||
#endif
|
||||
|
||||
/* B.A.T.M.A.N. parameters */
|
||||
|
||||
#define BATADV_TQ_MAX_VALUE 255
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/compiler.h>
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
#include <linux/stddef.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/rtnetlink.h>
|
||||
#include <uapi/linux/batadv_packet.h>
|
||||
|
|
@ -123,7 +125,7 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
|
|||
eth_hw_addr_set(dev, addr->sa_data);
|
||||
|
||||
/* only modify transtable if it has been initialized before */
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
return 0;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
@ -190,7 +192,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
|
|||
int network_offset = ETH_HLEN;
|
||||
__be16 proto;
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
goto dropped;
|
||||
|
||||
/* reset control block to avoid left overs from previous users */
|
||||
|
|
@ -255,7 +257,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
|
|||
if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
|
||||
goto dropped;
|
||||
|
||||
gw_mode = atomic_read(&bat_priv->gw.mode);
|
||||
gw_mode = READ_ONCE(bat_priv->gw.mode);
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest)) {
|
||||
/* if gw mode is off, broadcast every packet */
|
||||
if (gw_mode == BATADV_GW_MODE_OFF) {
|
||||
|
|
@ -565,7 +567,7 @@ int batadv_meshif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
|
|||
vlan->vid = vid;
|
||||
kref_init(&vlan->refcount);
|
||||
|
||||
atomic_set(&vlan->ap_isolation, 0);
|
||||
WRITE_ONCE(vlan->ap_isolation, 0);
|
||||
|
||||
kref_get(&vlan->refcount);
|
||||
hlist_add_head_rcu(&vlan->list, &bat_priv->meshif_vlan_list);
|
||||
|
|
@ -752,36 +754,36 @@ static int batadv_meshif_init_late(struct net_device *dev)
|
|||
if (!bat_priv->bat_counters)
|
||||
return -ENOMEM;
|
||||
|
||||
atomic_set(&bat_priv->aggregated_ogms, 1);
|
||||
atomic_set(&bat_priv->bonding, 0);
|
||||
WRITE_ONCE(bat_priv->aggregated_ogms, 1);
|
||||
WRITE_ONCE(bat_priv->bonding, 0);
|
||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
atomic_set(&bat_priv->bridge_loop_avoidance, 1);
|
||||
WRITE_ONCE(bat_priv->bridge_loop_avoidance, 1);
|
||||
#endif
|
||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||
atomic_set(&bat_priv->distributed_arp_table, 1);
|
||||
WRITE_ONCE(bat_priv->distributed_arp_table, 1);
|
||||
#endif
|
||||
#ifdef CONFIG_BATMAN_ADV_MCAST
|
||||
atomic_set(&bat_priv->multicast_mode, 1);
|
||||
atomic_set(&bat_priv->multicast_fanout, 16);
|
||||
WRITE_ONCE(bat_priv->multicast_mode, 1);
|
||||
WRITE_ONCE(bat_priv->multicast_fanout, 16);
|
||||
atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0);
|
||||
atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0);
|
||||
atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
|
||||
atomic_set(&bat_priv->mcast.num_no_mc_ptype_capa, 0);
|
||||
#endif
|
||||
atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
|
||||
atomic_set(&bat_priv->gw.bandwidth_down, 100);
|
||||
atomic_set(&bat_priv->gw.bandwidth_up, 20);
|
||||
atomic_set(&bat_priv->orig_interval, 1000);
|
||||
atomic_set(&bat_priv->hop_penalty, 30);
|
||||
WRITE_ONCE(bat_priv->gw.mode, BATADV_GW_MODE_OFF);
|
||||
WRITE_ONCE(bat_priv->gw.bandwidth_down, 100);
|
||||
WRITE_ONCE(bat_priv->gw.bandwidth_up, 20);
|
||||
WRITE_ONCE(bat_priv->orig_interval, 1000);
|
||||
WRITE_ONCE(bat_priv->hop_penalty, 30);
|
||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||
atomic_set(&bat_priv->log_level, 0);
|
||||
WRITE_ONCE(bat_priv->log_level, 0);
|
||||
#endif
|
||||
atomic_set(&bat_priv->fragmentation, 1);
|
||||
atomic_set(&bat_priv->packet_size_max, BATADV_MAX_MTU);
|
||||
WRITE_ONCE(bat_priv->fragmentation, 1);
|
||||
WRITE_ONCE(bat_priv->packet_size_max, BATADV_MAX_MTU);
|
||||
atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
|
||||
atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
|
||||
|
||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||
atomic_set(&bat_priv->bcast_seqno, 1);
|
||||
atomic_set(&bat_priv->tt.vn, 0);
|
||||
atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
|
||||
|
|
@ -892,7 +894,7 @@ static void batadv_get_drvinfo(struct net_device *dev,
|
|||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
strscpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver));
|
||||
strscpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version));
|
||||
strscpy(info->version, init_utsname()->release, sizeof(info->version));
|
||||
strscpy(info->fw_version, "N/A", sizeof(info->fw_version));
|
||||
strscpy(info->bus_info, "batman", sizeof(info->bus_info));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1099,7 +1099,7 @@ static int batadv_mcast_forw_mode_check(struct batadv_priv *bat_priv,
|
|||
{
|
||||
struct ethhdr *ethhdr = eth_hdr(skb);
|
||||
|
||||
if (!atomic_read(&bat_priv->multicast_mode))
|
||||
if (!READ_ONCE(bat_priv->multicast_mode))
|
||||
return -EINVAL;
|
||||
|
||||
switch (ntohs(ethhdr->h_proto)) {
|
||||
|
|
@ -1204,7 +1204,7 @@ batadv_mcast_forw_mode_by_count(struct batadv_priv *bat_priv,
|
|||
batadv_mcast_forw_push(bat_priv, skb, vid, is_routable, count))
|
||||
return BATADV_FORW_MCAST;
|
||||
|
||||
if (count <= atomic_read(&bat_priv->multicast_fanout))
|
||||
if (count <= READ_ONCE(bat_priv->multicast_fanout))
|
||||
return BATADV_FORW_UCASTS;
|
||||
|
||||
return BATADV_FORW_BCAST;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gfp.h>
|
||||
|
|
@ -28,6 +29,7 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netlink.h>
|
||||
|
|
@ -179,7 +181,7 @@ static int batadv_netlink_mesh_fill_ap_isolation(struct sk_buff *msg,
|
|||
if (!vlan)
|
||||
return 0;
|
||||
|
||||
ap_isolation = atomic_read(&vlan->ap_isolation);
|
||||
ap_isolation = READ_ONCE(vlan->ap_isolation);
|
||||
batadv_meshif_vlan_put(vlan);
|
||||
|
||||
return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED,
|
||||
|
|
@ -202,7 +204,7 @@ static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr,
|
|||
if (!vlan)
|
||||
return -ENOENT;
|
||||
|
||||
atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
|
||||
WRITE_ONCE(vlan->ap_isolation, !!nla_get_u8(attr));
|
||||
batadv_meshif_vlan_put(vlan);
|
||||
|
||||
return 0;
|
||||
|
|
@ -233,7 +235,7 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
|
|||
if (!hdr)
|
||||
return -ENOBUFS;
|
||||
|
||||
if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) ||
|
||||
if (nla_put_string(msg, BATADV_ATTR_VERSION, init_utsname()->release) ||
|
||||
nla_put_string(msg, BATADV_ATTR_ALGO_NAME,
|
||||
bat_priv->algo_ops->name) ||
|
||||
nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, mesh_iface->ifindex) ||
|
||||
|
|
@ -267,7 +269,7 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
|
|||
}
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS_ENABLED,
|
||||
!!atomic_read(&bat_priv->aggregated_ogms)))
|
||||
!!READ_ONCE(bat_priv->aggregated_ogms)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (batadv_netlink_mesh_fill_ap_isolation(msg, bat_priv))
|
||||
|
|
@ -282,35 +284,35 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
|
|||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_BONDING_ENABLED,
|
||||
!!atomic_read(&bat_priv->bonding)))
|
||||
!!READ_ONCE(bat_priv->bonding)))
|
||||
goto nla_put_failure;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED,
|
||||
!!atomic_read(&bat_priv->bridge_loop_avoidance)))
|
||||
!!READ_ONCE(bat_priv->bridge_loop_avoidance)))
|
||||
goto nla_put_failure;
|
||||
#endif /* CONFIG_BATMAN_ADV_BLA */
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||
if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED,
|
||||
!!atomic_read(&bat_priv->distributed_arp_table)))
|
||||
!!READ_ONCE(bat_priv->distributed_arp_table)))
|
||||
goto nla_put_failure;
|
||||
#endif /* CONFIG_BATMAN_ADV_DAT */
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED,
|
||||
!!atomic_read(&bat_priv->fragmentation)))
|
||||
!!READ_ONCE(bat_priv->fragmentation)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_DOWN,
|
||||
atomic_read(&bat_priv->gw.bandwidth_down)))
|
||||
READ_ONCE(bat_priv->gw.bandwidth_down)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_UP,
|
||||
atomic_read(&bat_priv->gw.bandwidth_up)))
|
||||
READ_ONCE(bat_priv->gw.bandwidth_up)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_GW_MODE,
|
||||
atomic_read(&bat_priv->gw.mode)))
|
||||
READ_ONCE(bat_priv->gw.mode)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (bat_priv->algo_ops->gw.get_best_gw_node &&
|
||||
|
|
@ -319,32 +321,32 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
|
|||
* in use does not implement the GW API
|
||||
*/
|
||||
if (nla_put_u32(msg, BATADV_ATTR_GW_SEL_CLASS,
|
||||
atomic_read(&bat_priv->gw.sel_class)))
|
||||
READ_ONCE(bat_priv->gw.sel_class)))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY,
|
||||
atomic_read(&bat_priv->hop_penalty)))
|
||||
READ_ONCE(bat_priv->hop_penalty)))
|
||||
goto nla_put_failure;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||
if (nla_put_u32(msg, BATADV_ATTR_LOG_LEVEL,
|
||||
atomic_read(&bat_priv->log_level)))
|
||||
READ_ONCE(bat_priv->log_level)))
|
||||
goto nla_put_failure;
|
||||
#endif /* CONFIG_BATMAN_ADV_DEBUG */
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_MCAST
|
||||
if (nla_put_u8(msg, BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED,
|
||||
!atomic_read(&bat_priv->multicast_mode)))
|
||||
!READ_ONCE(bat_priv->multicast_mode)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, BATADV_ATTR_MULTICAST_FANOUT,
|
||||
atomic_read(&bat_priv->multicast_fanout)))
|
||||
READ_ONCE(bat_priv->multicast_fanout)))
|
||||
goto nla_put_failure;
|
||||
#endif /* CONFIG_BATMAN_ADV_MCAST */
|
||||
|
||||
if (nla_put_u32(msg, BATADV_ATTR_ORIG_INTERVAL,
|
||||
atomic_read(&bat_priv->orig_interval)))
|
||||
READ_ONCE(bat_priv->orig_interval)))
|
||||
goto nla_put_failure;
|
||||
|
||||
batadv_hardif_put(primary_if);
|
||||
|
|
@ -432,7 +434,7 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr));
|
||||
WRITE_ONCE(bat_priv->aggregated_ogms, !!nla_get_u8(attr));
|
||||
}
|
||||
|
||||
if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) {
|
||||
|
|
@ -456,14 +458,14 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_BONDING_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_BONDING_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->bonding, !!nla_get_u8(attr));
|
||||
WRITE_ONCE(bat_priv->bonding, !!nla_get_u8(attr));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
if (info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->bridge_loop_avoidance,
|
||||
WRITE_ONCE(bat_priv->bridge_loop_avoidance,
|
||||
!!nla_get_u8(attr));
|
||||
batadv_bla_status_update(bat_priv->mesh_iface);
|
||||
}
|
||||
|
|
@ -473,7 +475,7 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->distributed_arp_table,
|
||||
WRITE_ONCE(bat_priv->distributed_arp_table,
|
||||
!!nla_get_u8(attr));
|
||||
batadv_dat_status_update(bat_priv->mesh_iface);
|
||||
}
|
||||
|
|
@ -482,7 +484,7 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
|
||||
WRITE_ONCE(bat_priv->fragmentation, !!nla_get_u8(attr));
|
||||
|
||||
rtnl_lock();
|
||||
batadv_update_min_mtu(bat_priv->mesh_iface);
|
||||
|
|
@ -492,14 +494,14 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {
|
||||
attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN];
|
||||
|
||||
atomic_set(&bat_priv->gw.bandwidth_down, nla_get_u32(attr));
|
||||
WRITE_ONCE(bat_priv->gw.bandwidth_down, nla_get_u32(attr));
|
||||
batadv_gw_tvlv_container_update(bat_priv);
|
||||
}
|
||||
|
||||
if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]) {
|
||||
attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP];
|
||||
|
||||
atomic_set(&bat_priv->gw.bandwidth_up, nla_get_u32(attr));
|
||||
WRITE_ONCE(bat_priv->gw.bandwidth_up, nla_get_u32(attr));
|
||||
batadv_gw_tvlv_container_update(bat_priv);
|
||||
}
|
||||
|
||||
|
|
@ -527,7 +529,7 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
* changing the gateway state
|
||||
*/
|
||||
batadv_gw_check_client_stop(bat_priv);
|
||||
atomic_set(&bat_priv->gw.mode, gw_mode);
|
||||
WRITE_ONCE(bat_priv->gw.mode, gw_mode);
|
||||
batadv_gw_tvlv_container_update(bat_priv);
|
||||
}
|
||||
}
|
||||
|
|
@ -546,7 +548,7 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
sel_class = nla_get_u32(attr);
|
||||
|
||||
if (sel_class >= 1 && sel_class <= sel_class_max) {
|
||||
atomic_set(&bat_priv->gw.sel_class, sel_class);
|
||||
WRITE_ONCE(bat_priv->gw.sel_class, sel_class);
|
||||
batadv_gw_reselect(bat_priv);
|
||||
}
|
||||
}
|
||||
|
|
@ -554,14 +556,14 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_HOP_PENALTY]) {
|
||||
attr = info->attrs[BATADV_ATTR_HOP_PENALTY];
|
||||
|
||||
atomic_set(&bat_priv->hop_penalty, nla_get_u8(attr));
|
||||
WRITE_ONCE(bat_priv->hop_penalty, nla_get_u8(attr));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||
if (info->attrs[BATADV_ATTR_LOG_LEVEL]) {
|
||||
attr = info->attrs[BATADV_ATTR_LOG_LEVEL];
|
||||
|
||||
atomic_set(&bat_priv->log_level,
|
||||
WRITE_ONCE(bat_priv->log_level,
|
||||
nla_get_u32(attr) & BATADV_DBG_ALL);
|
||||
}
|
||||
#endif /* CONFIG_BATMAN_ADV_DEBUG */
|
||||
|
|
@ -570,13 +572,13 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED];
|
||||
|
||||
atomic_set(&bat_priv->multicast_mode, !nla_get_u8(attr));
|
||||
WRITE_ONCE(bat_priv->multicast_mode, !nla_get_u8(attr));
|
||||
}
|
||||
|
||||
if (info->attrs[BATADV_ATTR_MULTICAST_FANOUT]) {
|
||||
attr = info->attrs[BATADV_ATTR_MULTICAST_FANOUT];
|
||||
|
||||
atomic_set(&bat_priv->multicast_fanout, nla_get_u32(attr));
|
||||
WRITE_ONCE(bat_priv->multicast_fanout, nla_get_u32(attr));
|
||||
}
|
||||
#endif /* CONFIG_BATMAN_ADV_MCAST */
|
||||
|
||||
|
|
@ -589,7 +591,7 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
|
|||
orig_interval = min_t(u32, orig_interval, INT_MAX);
|
||||
orig_interval = max_t(u32, orig_interval, 2 * BATADV_JITTER);
|
||||
|
||||
atomic_set(&bat_priv->orig_interval, orig_interval);
|
||||
WRITE_ONCE(bat_priv->orig_interval, orig_interval);
|
||||
}
|
||||
|
||||
batadv_netlink_notify_mesh(bat_priv);
|
||||
|
|
@ -809,16 +811,16 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg,
|
|||
}
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY,
|
||||
atomic_read(&hard_iface->hop_penalty)))
|
||||
READ_ONCE(hard_iface->hop_penalty)))
|
||||
goto nla_put_failure;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BATMAN_V
|
||||
if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,
|
||||
atomic_read(&hard_iface->bat_v.elp_interval)))
|
||||
READ_ONCE(hard_iface->bat_v.elp_interval)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE,
|
||||
atomic_read(&hard_iface->bat_v.throughput_override)))
|
||||
READ_ONCE(hard_iface->bat_v.throughput_override)))
|
||||
goto nla_put_failure;
|
||||
#endif /* CONFIG_BATMAN_ADV_BATMAN_V */
|
||||
|
||||
|
|
@ -911,7 +913,7 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb,
|
|||
if (info->attrs[BATADV_ATTR_HOP_PENALTY]) {
|
||||
attr = info->attrs[BATADV_ATTR_HOP_PENALTY];
|
||||
|
||||
atomic_set(&hard_iface->hop_penalty, nla_get_u8(attr));
|
||||
WRITE_ONCE(hard_iface->hop_penalty, nla_get_u8(attr));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BATMAN_V
|
||||
|
|
@ -919,13 +921,13 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb,
|
|||
if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) {
|
||||
attr = info->attrs[BATADV_ATTR_ELP_INTERVAL];
|
||||
|
||||
atomic_set(&hard_iface->bat_v.elp_interval, nla_get_u32(attr));
|
||||
WRITE_ONCE(hard_iface->bat_v.elp_interval, nla_get_u32(attr));
|
||||
}
|
||||
|
||||
if (info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]) {
|
||||
attr = info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE];
|
||||
|
||||
atomic_set(&hard_iface->bat_v.throughput_override,
|
||||
WRITE_ONCE(hard_iface->bat_v.throughput_override,
|
||||
nla_get_u32(attr));
|
||||
}
|
||||
#endif /* CONFIG_BATMAN_ADV_BATMAN_V */
|
||||
|
|
@ -1020,7 +1022,7 @@ static int batadv_netlink_vlan_fill(struct sk_buff *msg,
|
|||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED,
|
||||
!!atomic_read(&vlan->ap_isolation)))
|
||||
!!READ_ONCE(vlan->ap_isolation)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
|
@ -1108,7 +1110,7 @@ static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED]) {
|
||||
attr = info->attrs[BATADV_ATTR_AP_ISOLATION_ENABLED];
|
||||
|
||||
atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
|
||||
WRITE_ONCE(vlan->ap_isolation, !!nla_get_u8(attr));
|
||||
}
|
||||
|
||||
batadv_netlink_notify_vlan(bat_priv, vlan);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "originator.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
|
|
@ -694,9 +693,12 @@ batadv_neigh_node_create(struct batadv_orig_node *orig_node,
|
|||
kref_get(&hard_iface->refcount);
|
||||
ether_addr_copy(neigh_node->addr, neigh_addr);
|
||||
neigh_node->if_incoming = hard_iface;
|
||||
neigh_node->orig_node = orig_node;
|
||||
neigh_node->last_seen = jiffies;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BATMAN_V
|
||||
ACCESS_PRIVATE(neigh_node, orig_node_id) = orig_node;
|
||||
#endif
|
||||
|
||||
/* increment unique neighbor refcount */
|
||||
kref_get(&hardif_neigh->refcount);
|
||||
neigh_node->hardif_neigh = hardif_neigh;
|
||||
|
|
@ -966,7 +968,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
|
|||
orig_node->bat_priv = bat_priv;
|
||||
ether_addr_copy(orig_node->orig, addr);
|
||||
batadv_dat_init_orig_node_addr(orig_node);
|
||||
atomic_set(&orig_node->last_ttvn, 0);
|
||||
WRITE_ONCE(orig_node->last_ttvn, 0);
|
||||
orig_node->tt_buff = NULL;
|
||||
orig_node->tt_buff_len = 0;
|
||||
orig_node->last_seen = jiffies;
|
||||
|
|
|
|||
|
|
@ -543,7 +543,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
|
|||
/* only consider bonding for recv_if == BATADV_IF_DEFAULT (first hop)
|
||||
* and if activated.
|
||||
*/
|
||||
if (!(recv_if == BATADV_IF_DEFAULT && atomic_read(&bat_priv->bonding)))
|
||||
if (!(recv_if == BATADV_IF_DEFAULT && READ_ONCE(bat_priv->bonding)))
|
||||
return router;
|
||||
|
||||
/* bonding: loop through the list of possible routers found
|
||||
|
|
@ -765,7 +765,7 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
|||
goto out;
|
||||
|
||||
orig_addr = orig_node->orig;
|
||||
orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn);
|
||||
orig_ttvn = READ_ONCE(orig_node->last_ttvn);
|
||||
}
|
||||
|
||||
/* update the packet header */
|
||||
|
|
@ -845,7 +845,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
|||
if (!orig_node)
|
||||
return false;
|
||||
|
||||
curr_ttvn = (u8)atomic_read(&orig_node->last_ttvn);
|
||||
curr_ttvn = READ_ONCE(orig_node->last_ttvn);
|
||||
batadv_orig_node_put(orig_node);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
|
|||
/* Check if the skb is too large to send in one piece and fragment
|
||||
* it if needed.
|
||||
*/
|
||||
if (atomic_read(&bat_priv->fragmentation) &&
|
||||
if (READ_ONCE(bat_priv->fragmentation) &&
|
||||
skb->len > neigh_node->if_incoming->net_dev->mtu) {
|
||||
/* Fragment and send packet. */
|
||||
ret = batadv_frag_send_packet(skb, orig_node, neigh_node);
|
||||
|
|
@ -222,7 +222,7 @@ batadv_send_skb_push_fill_unicast(struct sk_buff *skb, int hdr_size,
|
|||
struct batadv_orig_node *orig_node)
|
||||
{
|
||||
struct batadv_unicast_packet *unicast_packet;
|
||||
u8 ttvn = (u8)atomic_read(&orig_node->last_ttvn);
|
||||
u8 ttvn = READ_ONCE(orig_node->last_ttvn);
|
||||
|
||||
if (batadv_skb_head_push(skb, hdr_size) < 0)
|
||||
return false;
|
||||
|
|
@ -1047,7 +1047,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
|
|||
delayed_work);
|
||||
bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface);
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||
if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||
dropped = true;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -999,7 +999,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
|
|||
|
||||
/* look for an already existing test towards this node */
|
||||
spin_lock_bh(&bat_priv->tp_list_lock);
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) {
|
||||
if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) {
|
||||
spin_unlock_bh(&bat_priv->tp_list_lock);
|
||||
batadv_tp_batctl_error_notify(BATADV_TP_REASON_DST_UNREACHABLE,
|
||||
dst, bat_priv, session_cookie);
|
||||
|
|
@ -1387,7 +1387,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
|
|||
struct batadv_tp_vars *tp_vars = NULL;
|
||||
|
||||
spin_lock_bh(&bat_priv->tp_list_lock);
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
goto out_unlock;
|
||||
|
||||
tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig,
|
||||
|
|
@ -1518,7 +1518,7 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
|
|||
{
|
||||
struct batadv_icmp_tp_packet *icmp;
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
|
||||
goto out;
|
||||
|
||||
icmp = (struct batadv_icmp_tp_packet *)skb->data;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/cache.h>
|
||||
|
|
@ -648,7 +649,7 @@ bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
|
|||
/* Ignore the client if we cannot send it in a full table response. */
|
||||
table_size = batadv_tt_local_table_transmit_size(bat_priv);
|
||||
table_size += batadv_tt_len(1);
|
||||
packet_size_max = atomic_read(&bat_priv->packet_size_max);
|
||||
packet_size_max = READ_ONCE(bat_priv->packet_size_max);
|
||||
if (table_size > packet_size_max) {
|
||||
net_ratelimited_function(batadv_info, mesh_iface,
|
||||
"Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
|
||||
|
|
@ -798,10 +799,10 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
|
|||
{
|
||||
u16 num_vlan = 0;
|
||||
u16 tvlv_len = 0;
|
||||
unsigned int change_offset;
|
||||
struct batadv_tvlv_tt_vlan_data *tt_vlan;
|
||||
struct batadv_orig_node_vlan *vlan;
|
||||
u16 total_entries = 0;
|
||||
size_t change_offset;
|
||||
u8 *tt_change_ptr;
|
||||
int vlan_entries;
|
||||
u16 sum_entries;
|
||||
|
|
@ -825,14 +826,11 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
|
|||
if (*tt_len < 0)
|
||||
*tt_len = batadv_tt_len(total_entries);
|
||||
|
||||
if (change_offset > U16_MAX || *tt_len > U16_MAX - change_offset) {
|
||||
if (check_add_overflow(*tt_len, change_offset, &tvlv_len)) {
|
||||
*tt_len = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tvlv_len = *tt_len;
|
||||
tvlv_len += change_offset;
|
||||
|
||||
*tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
|
||||
if (!*tt_data) {
|
||||
*tt_len = 0;
|
||||
|
|
@ -840,7 +838,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
|
|||
}
|
||||
|
||||
(*tt_data)->flags = BATADV_NO_FLAGS;
|
||||
(*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
|
||||
(*tt_data)->ttvn = READ_ONCE(orig_node->last_ttvn);
|
||||
(*tt_data)->num_vlan = htons(num_vlan);
|
||||
|
||||
tt_vlan = (*tt_data)->vlan_data;
|
||||
|
|
@ -1821,7 +1819,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
|
|||
if (!hdr)
|
||||
return -ENOBUFS;
|
||||
|
||||
last_ttvn = atomic_read(&orig->orig_node->last_ttvn);
|
||||
last_ttvn = READ_ONCE(orig->orig_node->last_ttvn);
|
||||
|
||||
if (nla_put(msg, BATADV_ATTR_TT_ADDRESS, ETH_ALEN, common->addr) ||
|
||||
nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
|
||||
|
|
@ -3012,7 +3010,7 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
|||
if (!res_dst_orig_node)
|
||||
goto out;
|
||||
|
||||
orig_ttvn = (u8)atomic_read(&req_dst_orig_node->last_ttvn);
|
||||
orig_ttvn = READ_ONCE(req_dst_orig_node->last_ttvn);
|
||||
req_ttvn = tt_data->ttvn;
|
||||
|
||||
/* this node doesn't have the requested data */
|
||||
|
|
@ -3068,7 +3066,7 @@ static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
|||
|
||||
/* Don't send the response, if larger than fragmented packet. */
|
||||
tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
|
||||
if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
|
||||
if (tt_len > READ_ONCE(bat_priv->packet_size_max)) {
|
||||
net_ratelimited_function(batadv_info, bat_priv->mesh_iface,
|
||||
"Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
|
||||
res_dst_orig_node->orig);
|
||||
|
|
@ -3299,7 +3297,7 @@ static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
|
|||
orig_node->tt_buff = NULL;
|
||||
spin_unlock_bh(&orig_node->tt_buff_lock);
|
||||
|
||||
atomic_set(&orig_node->last_ttvn, ttvn);
|
||||
WRITE_ONCE(orig_node->last_ttvn, ttvn);
|
||||
|
||||
out:
|
||||
batadv_orig_node_put(orig_node);
|
||||
|
|
@ -3315,7 +3313,7 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
|
|||
|
||||
batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
|
||||
batadv_tt_len(tt_num_changes));
|
||||
atomic_set(&orig_node->last_ttvn, ttvn);
|
||||
WRITE_ONCE(orig_node->last_ttvn, ttvn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3729,7 +3727,7 @@ bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, u8 *src, u8 *dst,
|
|||
if (!vlan)
|
||||
return false;
|
||||
|
||||
if (!atomic_read(&vlan->ap_isolation))
|
||||
if (!READ_ONCE(vlan->ap_isolation))
|
||||
goto vlan_put;
|
||||
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
|
||||
|
|
@ -3768,7 +3766,7 @@ static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
|
|||
struct batadv_tvlv_tt_change *tt_change,
|
||||
u16 tt_num_changes, u8 ttvn)
|
||||
{
|
||||
u8 orig_ttvn = (u8)atomic_read(&orig_node->last_ttvn);
|
||||
u8 orig_ttvn = READ_ONCE(orig_node->last_ttvn);
|
||||
struct batadv_tvlv_tt_vlan_data *tt_vlan;
|
||||
bool full_table = true;
|
||||
bool has_tt_init;
|
||||
|
|
@ -3910,7 +3908,7 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
|
|||
|
||||
if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
|
||||
BATADV_TT_CLIENT_TEMP,
|
||||
atomic_read(&orig_node->last_ttvn)))
|
||||
READ_ONCE(orig_node->last_ttvn)))
|
||||
return false;
|
||||
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
|
|
@ -3931,7 +3929,7 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
|
|||
void batadv_tt_local_resize_to_mtu(struct net_device *mesh_iface)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
|
||||
int packet_size_max = atomic_read(&bat_priv->packet_size_max);
|
||||
int packet_size_max = READ_ONCE(bat_priv->packet_size_max);
|
||||
int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
|
||||
bool reduced = false;
|
||||
|
||||
|
|
@ -4124,7 +4122,7 @@ static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
|
|||
|
||||
batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
|
||||
ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
|
||||
atomic_read(&orig_node->last_ttvn) + 1);
|
||||
READ_ONCE(orig_node->last_ttvn) + 1);
|
||||
|
||||
out:
|
||||
batadv_orig_node_put(orig_node);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "main.h"
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/errno.h>
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
#include <linux/limits.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <linux/rculist.h>
|
||||
|
|
@ -266,32 +268,48 @@ void batadv_tvlv_container_register(struct batadv_priv *bat_priv,
|
|||
/**
|
||||
* batadv_tvlv_realloc_packet_buff() - reallocate packet buffer to accommodate
|
||||
* requested packet size
|
||||
* @packet_buff: packet buffer
|
||||
* @packet_buff_len: packet buffer size
|
||||
* @min_packet_len: requested packet minimum size
|
||||
* @ogm_buff: ogm packet buffer
|
||||
* @additional_packet_len: requested additional packet size on top of minimum
|
||||
* size
|
||||
*
|
||||
* Return: true of the packet buffer could be changed to the requested size,
|
||||
* false otherwise.
|
||||
*/
|
||||
static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff,
|
||||
int *packet_buff_len,
|
||||
int min_packet_len,
|
||||
int additional_packet_len)
|
||||
static bool batadv_tvlv_realloc_packet_buff(struct batadv_ogm_buf *ogm_buff,
|
||||
size_t additional_packet_len)
|
||||
{
|
||||
unsigned char *new_buff;
|
||||
size_t newcapacity;
|
||||
size_t newlen;
|
||||
|
||||
new_buff = kmalloc(min_packet_len + additional_packet_len, GFP_ATOMIC);
|
||||
newlen = ogm_buff->header_length + additional_packet_len;
|
||||
newcapacity = roundup_pow_of_two(newlen);
|
||||
|
||||
/* nothing to reallocate */
|
||||
if (newcapacity == ogm_buff->capacity) {
|
||||
ogm_buff->len = newlen;
|
||||
return true;
|
||||
}
|
||||
|
||||
new_buff = kmalloc(newcapacity, GFP_ATOMIC);
|
||||
|
||||
/* keep old buffer if kmalloc should fail */
|
||||
if (!new_buff)
|
||||
return false;
|
||||
if (!new_buff) {
|
||||
/* continue to use oversize buffer if new data fits */
|
||||
if (newlen <= ogm_buff->capacity) {
|
||||
ogm_buff->len = newlen;
|
||||
return true;
|
||||
}
|
||||
|
||||
memcpy(new_buff, *packet_buff, min_packet_len);
|
||||
kfree(*packet_buff);
|
||||
*packet_buff = new_buff;
|
||||
*packet_buff_len = min_packet_len + additional_packet_len;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(new_buff, ogm_buff->buf, ogm_buff->header_length);
|
||||
kfree(ogm_buff->buf);
|
||||
|
||||
ogm_buff->buf = new_buff;
|
||||
ogm_buff->len = newlen;
|
||||
ogm_buff->capacity = newcapacity;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -300,10 +318,7 @@ static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff,
|
|||
* batadv_tvlv_container_ogm_append() - append tvlv container content to given
|
||||
* OGM packet buffer
|
||||
* @bat_priv: the bat priv with all the mesh interface information
|
||||
* @packet_buff: ogm packet buffer
|
||||
* @packet_buff_len: ogm packet buffer size including ogm header and tvlv
|
||||
* content
|
||||
* @packet_min_len: ogm header size to be preserved for the OGM itself
|
||||
* @ogm_buff: ogm packet buffer
|
||||
*
|
||||
* The ogm packet might be enlarged or shrunk depending on the current size
|
||||
* and the size of the to-be-appended tvlv containers.
|
||||
|
|
@ -312,8 +327,7 @@ static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff,
|
|||
* if operation failed
|
||||
*/
|
||||
int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
||||
unsigned char **packet_buff,
|
||||
int *packet_buff_len, int packet_min_len)
|
||||
struct batadv_ogm_buf *ogm_buff)
|
||||
{
|
||||
struct batadv_tvlv_container *tvlv;
|
||||
struct batadv_tvlv_hdr *tvlv_hdr;
|
||||
|
|
@ -329,8 +343,7 @@ int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
|||
goto end;
|
||||
}
|
||||
|
||||
ret = batadv_tvlv_realloc_packet_buff(packet_buff, packet_buff_len,
|
||||
packet_min_len, tvlv_value_len);
|
||||
ret = batadv_tvlv_realloc_packet_buff(ogm_buff, tvlv_value_len);
|
||||
if (!ret) {
|
||||
tvlv_len_ret = -ENOMEM;
|
||||
goto end;
|
||||
|
|
@ -341,7 +354,7 @@ int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
|||
if (!tvlv_value_len)
|
||||
goto end;
|
||||
|
||||
tvlv_value = (*packet_buff) + packet_min_len;
|
||||
tvlv_value = (u8 *)ogm_buff->buf + ogm_buff->header_length;
|
||||
|
||||
hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) {
|
||||
tvlv_hdr = tvlv_value;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ void batadv_tvlv_container_register(struct batadv_priv *bat_priv,
|
|||
u8 type, u8 version,
|
||||
void *tvlv_value, u16 tvlv_value_len);
|
||||
int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
||||
unsigned char **packet_buff,
|
||||
int *packet_buff_len, int packet_min_len);
|
||||
struct batadv_ogm_buf *ogm_buff);
|
||||
void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
|
||||
struct batadv_ogm_packet *batadv_ogm_packet,
|
||||
struct batadv_orig_node *orig_node);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rhashtable-types.h>
|
||||
#include <linux/sched.h> /* for linux/wait.h */
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
|
@ -70,15 +71,29 @@ enum batadv_dhcp_recipient {
|
|||
*/
|
||||
#define BATADV_TT_SYNC_MASK 0x00F0
|
||||
|
||||
/**
|
||||
* struct batadv_ogm_buf - Buffer to construct an OGM with TVLV
|
||||
*/
|
||||
struct batadv_ogm_buf {
|
||||
/** @buf: buffer holding the OGM packet */
|
||||
void *buf;
|
||||
|
||||
/** @len: length of the OGM packet buffer data */
|
||||
size_t len;
|
||||
|
||||
/** @capacity: size of allocated buf */
|
||||
size_t capacity;
|
||||
|
||||
/** @header_length: fixed size header length (must be <= len) */
|
||||
size_t header_length;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data
|
||||
*/
|
||||
struct batadv_hard_iface_bat_iv {
|
||||
/** @ogm_buff: buffer holding the OGM packet */
|
||||
unsigned char *ogm_buff;
|
||||
|
||||
/** @ogm_buff_len: length of the OGM packet buffer */
|
||||
int ogm_buff_len;
|
||||
struct batadv_ogm_buf ogm_buff;
|
||||
|
||||
/** @ogm_seqno: OGM sequence number - used to identify each OGM */
|
||||
atomic_t ogm_seqno;
|
||||
|
|
@ -86,7 +101,7 @@ struct batadv_hard_iface_bat_iv {
|
|||
/** @reschedule_work: recover OGM schedule after schedule error */
|
||||
struct delayed_work reschedule_work;
|
||||
|
||||
/** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
|
||||
/** @ogm_buff_mutex: lock protecting ogm_buff */
|
||||
struct mutex ogm_buff_mutex;
|
||||
};
|
||||
|
||||
|
|
@ -113,7 +128,7 @@ enum batadv_v_hard_iface_flags {
|
|||
*/
|
||||
struct batadv_hard_iface_bat_v {
|
||||
/** @elp_interval: time interval between two ELP transmissions */
|
||||
atomic_t elp_interval;
|
||||
u32 elp_interval;
|
||||
|
||||
/** @elp_seqno: current ELP sequence number */
|
||||
atomic_t elp_seqno;
|
||||
|
|
@ -137,7 +152,7 @@ struct batadv_hard_iface_bat_v {
|
|||
* @throughput_override: throughput override to disable link
|
||||
* auto-detection
|
||||
*/
|
||||
atomic_t throughput_override;
|
||||
u32 throughput_override;
|
||||
|
||||
/** @flags: interface specific flags */
|
||||
u8 flags;
|
||||
|
|
@ -166,6 +181,29 @@ enum batadv_hard_iface_wifi_flags {
|
|||
BATADV_HARDIF_WIFI_CFG80211_INDIRECT = BIT(3),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batadv_wifi_net_device_state - cache of wifi information of net_devices
|
||||
*/
|
||||
struct batadv_wifi_net_device_state {
|
||||
/** @l: anchor in rhashtable */
|
||||
struct rhash_head l;
|
||||
|
||||
/** @netdev: pointer to the net_device */
|
||||
struct net_device *netdev;
|
||||
|
||||
/** @dev_tracker: device tracker for @netdev */
|
||||
netdevice_tracker dev_tracker;
|
||||
|
||||
/**
|
||||
* @wifi_flags: flags whether this is (directly or indirectly) a wifi
|
||||
* interface
|
||||
*/
|
||||
u32 wifi_flags;
|
||||
|
||||
/** @rcu: struct used for freeing in an RCU-safe manner */
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batadv_hard_iface - network device known to batman-adv
|
||||
*/
|
||||
|
|
@ -181,12 +219,6 @@ struct batadv_hard_iface {
|
|||
*/
|
||||
u8 num_bcasts;
|
||||
|
||||
/**
|
||||
* @wifi_flags: flags whether this is (directly or indirectly) a wifi
|
||||
* interface
|
||||
*/
|
||||
u32 wifi_flags;
|
||||
|
||||
/** @net_dev: pointer to the net_device */
|
||||
struct net_device *net_dev;
|
||||
|
||||
|
|
@ -218,7 +250,7 @@ struct batadv_hard_iface {
|
|||
* @hop_penalty: penalty which will be applied to the tq-field
|
||||
* of an OGM received via this interface
|
||||
*/
|
||||
atomic_t hop_penalty;
|
||||
u8 hop_penalty;
|
||||
|
||||
/** @bat_iv: per hard-interface B.A.T.M.A.N. IV data */
|
||||
struct batadv_hard_iface_bat_iv bat_iv;
|
||||
|
|
@ -446,7 +478,7 @@ struct batadv_orig_node {
|
|||
unsigned long capa_initialized;
|
||||
|
||||
/** @last_ttvn: last seen translation table version number */
|
||||
atomic_t last_ttvn;
|
||||
u8 last_ttvn;
|
||||
|
||||
/** @tt_buff: last tt changeset this node received from the orig node */
|
||||
unsigned char *tt_buff;
|
||||
|
|
@ -631,8 +663,15 @@ struct batadv_neigh_node {
|
|||
/** @list: list node for &batadv_orig_node.neigh_list */
|
||||
struct hlist_node list;
|
||||
|
||||
/** @orig_node: pointer to corresponding orig_node */
|
||||
struct batadv_orig_node *orig_node;
|
||||
#ifdef CONFIG_BATMAN_ADV_BATMAN_V
|
||||
/**
|
||||
* @orig_node_id: pointer to corresponding orig_node. It must only be used
|
||||
* to identify the node but must NEVER be dereferenced. The reference counter
|
||||
* was not increased when this was assigned because it would otherwise create
|
||||
* a reference cycle.
|
||||
*/
|
||||
struct batadv_orig_node *__private orig_node_id;
|
||||
#endif
|
||||
|
||||
/** @addr: the MAC address of the neighboring interface */
|
||||
u8 addr[ETH_ALEN];
|
||||
|
|
@ -1101,21 +1140,21 @@ struct batadv_priv_gw {
|
|||
/**
|
||||
* @mode: gateway operation: off, client or server (see batadv_gw_modes)
|
||||
*/
|
||||
atomic_t mode;
|
||||
enum batadv_gw_modes mode;
|
||||
|
||||
/** @sel_class: gateway selection class (applies if gw_mode client) */
|
||||
atomic_t sel_class;
|
||||
u32 sel_class;
|
||||
|
||||
/**
|
||||
* @bandwidth_down: advertised uplink download bandwidth (if gw_mode
|
||||
* server)
|
||||
*/
|
||||
atomic_t bandwidth_down;
|
||||
u32 bandwidth_down;
|
||||
|
||||
/**
|
||||
* @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server)
|
||||
*/
|
||||
atomic_t bandwidth_up;
|
||||
u32 bandwidth_up;
|
||||
|
||||
/** @reselect: bool indicating a gateway re-selection is in progress */
|
||||
atomic_t reselect;
|
||||
|
|
@ -1441,7 +1480,7 @@ struct batadv_meshif_vlan {
|
|||
unsigned short vid;
|
||||
|
||||
/** @ap_isolation: AP isolation state */
|
||||
atomic_t ap_isolation; /* boolean */
|
||||
u8 ap_isolation; /* boolean */
|
||||
|
||||
/** @tt: TT private attributes (VLAN specific) */
|
||||
struct batadv_vlan_tt tt;
|
||||
|
|
@ -1463,15 +1502,12 @@ struct batadv_meshif_vlan {
|
|||
*/
|
||||
struct batadv_priv_bat_v {
|
||||
/** @ogm_buff: buffer holding the OGM packet */
|
||||
unsigned char *ogm_buff;
|
||||
|
||||
/** @ogm_buff_len: length of the OGM packet buffer */
|
||||
int ogm_buff_len;
|
||||
struct batadv_ogm_buf ogm_buff;
|
||||
|
||||
/** @ogm_seqno: OGM sequence number - used to identify each OGM */
|
||||
atomic_t ogm_seqno;
|
||||
|
||||
/** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
|
||||
/** @ogm_buff_mutex: lock protecting ogm_buff */
|
||||
struct mutex ogm_buff_mutex;
|
||||
|
||||
/** @ogm_wq: workqueue used to schedule OGM transmissions */
|
||||
|
|
@ -1486,7 +1522,7 @@ struct batadv_priv {
|
|||
* @mesh_state: current status of the mesh
|
||||
* (inactive/active/deactivating)
|
||||
*/
|
||||
atomic_t mesh_state;
|
||||
enum batadv_mesh_state mesh_state;
|
||||
|
||||
/** @mesh_iface: net device which holds this struct as private data */
|
||||
struct net_device *mesh_iface;
|
||||
|
|
@ -1506,36 +1542,23 @@ struct batadv_priv {
|
|||
/**
|
||||
* @aggregated_ogms: bool indicating whether OGM aggregation is enabled
|
||||
*/
|
||||
atomic_t aggregated_ogms;
|
||||
u8 aggregated_ogms;
|
||||
|
||||
/** @bonding: bool indicating whether traffic bonding is enabled */
|
||||
atomic_t bonding;
|
||||
u8 bonding;
|
||||
|
||||
/**
|
||||
* @fragmentation: bool indicating whether traffic fragmentation is
|
||||
* enabled
|
||||
*/
|
||||
atomic_t fragmentation;
|
||||
|
||||
/**
|
||||
* @packet_size_max: max packet size that can be transmitted via
|
||||
* multiple fragmented skbs or a single frame if fragmentation is
|
||||
* disabled
|
||||
*/
|
||||
atomic_t packet_size_max;
|
||||
|
||||
/**
|
||||
* @frag_seqno: incremental counter to identify chains of egress
|
||||
* fragments
|
||||
*/
|
||||
atomic_t frag_seqno;
|
||||
u8 fragmentation;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
/**
|
||||
* @bridge_loop_avoidance: bool indicating whether bridge loop
|
||||
* avoidance is enabled
|
||||
*/
|
||||
atomic_t bridge_loop_avoidance;
|
||||
u8 bridge_loop_avoidance;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DAT
|
||||
|
|
@ -1543,7 +1566,7 @@ struct batadv_priv {
|
|||
* @distributed_arp_table: bool indicating whether distributed ARP table
|
||||
* is enabled
|
||||
*/
|
||||
atomic_t distributed_arp_table;
|
||||
u8 distributed_arp_table;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_MCAST
|
||||
|
|
@ -1551,27 +1574,40 @@ struct batadv_priv {
|
|||
* @multicast_mode: Enable or disable multicast optimizations on this
|
||||
* node's sender/originating side
|
||||
*/
|
||||
atomic_t multicast_mode;
|
||||
u8 multicast_mode;
|
||||
|
||||
/**
|
||||
* @multicast_fanout: Maximum number of packet copies to generate for a
|
||||
* multicast-to-unicast conversion
|
||||
*/
|
||||
atomic_t multicast_fanout;
|
||||
u32 multicast_fanout;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @packet_size_max: max packet size that can be transmitted via
|
||||
* multiple fragmented skbs or a single frame if fragmentation is
|
||||
* disabled
|
||||
*/
|
||||
int packet_size_max;
|
||||
|
||||
/**
|
||||
* @frag_seqno: incremental counter to identify chains of egress
|
||||
* fragments
|
||||
*/
|
||||
atomic_t frag_seqno;
|
||||
|
||||
/** @orig_interval: OGM broadcast interval in milliseconds */
|
||||
atomic_t orig_interval;
|
||||
u32 orig_interval;
|
||||
|
||||
/**
|
||||
* @hop_penalty: penalty which will be applied to an OGM's tq-field on
|
||||
* every hop
|
||||
*/
|
||||
atomic_t hop_penalty;
|
||||
u8 hop_penalty;
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
||||
/** @log_level: configured log level (see batadv_dbg_level) */
|
||||
atomic_t log_level;
|
||||
u32 log_level;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
|||
12
net/batman-adv/version.c
Normal file
12
net/batman-adv/version.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/* WARNING userspace tools like batctl were relying on
|
||||
* /sys/module/batman_adv/version to check if the module was loaded. If it
|
||||
* isn't present, they usually error out before finishing setup of the batadv
|
||||
* interface. It should be kept until it is unlikely that there are active
|
||||
* installations of these "broken" versions of these tools with recent kernels.
|
||||
*/
|
||||
MODULE_VERSION(UTS_RELEASE);
|
||||
Loading…
Reference in New Issue
Block a user