Here are a few batman-adv bugfixes:

- avoid WARN_ON for orig_ifinfo allocation failure, by Deepanshu Kartikey
 
 - close OGM aggregation before transmission, by Chengfeng Ye
 
 - mcast: validate tracker padding before forwarding, by Kyle Zeng
 
 The remaining bugfixes are authored by Sven Eckelmann:
 
 - tpmeter: fix u32 truncation of reported bytes
 
 - dat: initialize orig_node of unfilled candidate slots
 
 - fix skb leak when hard_iface is being released
 
 - stop originator purge worker before freeing tt
 
 - tt: fix flag and event handling (6 patches)
 
 - tt: limit local table to single TVLV response size
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEE1ilQI7G+y+fdhnrfoSvjmEKSnqEFAmrknyAWHHN3QHNpbW9u
 d3VuZGVybGljaC5kZQAKCRChK+OYQpKeoaNWEACKp6LrH/AcPfvHZdsAc6qCud1a
 p/U2axzCDiabpabhdT/5vB4APk9WtKq0emDoPyzoscYDqkSGUza4Vlr6E4zf+zRP
 M4l+HcF3KMfhFY+yEMwFA/wt7eTzmVZzd7fu28Xha2nc1a8zwiSOLIKmh3QPxXFj
 zQfPZyR8a+fpakdJBWGk8IU1F5dJSWKZkUcV5PPYRN0kyI/hNY/y7xjjV5SNua4K
 IpRKv0ADXNdn4VHdW0KhYBFPWrMyJJkEJC2snjfJYKtwAVOj38AkC3xuX0tGkQQX
 id9SYExWwIISOiZcuCE7bynp95LM/F+CsdS7D7I92AB/FHqrLun2lrmdLhHQLyPn
 +zmOFVoTWpDrSttwHIPkv15cdsdPovH1ctCfVEkH13GD6k3Z4T0XGD+lUkeHDsAc
 O+irSMqdNIqSS6niDmBGmYicuZnIGuo+IQFzy3/GfP91ryn7e3XelRGn+CTJ4upe
 LnLx+UN3Y+EqBJ5LeJeZdo+C64Va/GezI36KygdDUtgBal2ietFhPm9lb90mhlg9
 ETi7oBU7VDGVvHeYm90XYP0vOLtVd/C1qfwi3NvqFanbAzwEWKAQW2ZYzkDHQx4K
 TXC+q9xRnYMwOscrAiZRbnGiJgXjBX1cDvdTDrdMt9vn0NDy8vdU69fqxObmu60O
 6VW1pFog501NQeSkmg==
 =LkDM
 -----END PGP SIGNATURE-----

Merge tag 'batadv-net-pullrequest-20261030' of https://git.open-mesh.org/batadv

Simon Wunderlich says:

====================
Here are a few batman-adv bugfixes:

- avoid WARN_ON for orig_ifinfo allocation failure, by Deepanshu Kartikey

- close OGM aggregation before transmission, by Chengfeng Ye

- mcast: validate tracker padding before forwarding, by Kyle Zeng

The remaining bugfixes are authored by Sven Eckelmann:

- tpmeter: fix u32 truncation of reported bytes

- dat: initialize orig_node of unfilled candidate slots

- fix skb leak when hard_iface is being released

- stop originator purge worker before freeing tt

- tt: fix flag and event handling (6 patches)

- tt: limit local table to single TVLV response size

* tag 'batadv-net-pullrequest-20261030' of https://git.open-mesh.org/batadv:
  batman-adv: tt: limit local table to single TVLV response size
  batman-adv: tt: don't drop local events queued during TVLV update
  batman-adv: tt: only update flags for TT events
  batman-adv: tt: ignore ROAM flag of received ADD changes
  batman-adv: tt: send ROAM_ADV on each roamed back client
  batman-adv: tt: clear ROAM flag when re-adding a pending local client
  batman-adv: tt: only transmit local ROAM flag together with DEL
  batman-adv: stop originator purge worker before freeing TT
  batman-adv: fix skb leak when hard_iface is being released
  batman-adv: dat: initialize orig_node of unfilled candidate slots
  batman-adv: tpmeter: fix u32 truncation of reported bytes
  batman-adv: mcast: validate tracker padding before forwarding
  batman-adv: Close OGM aggregation before transmission
  batman-adv: avoid WARN_ON for orig_ifinfo allocation failure
====================

Link: https://patch.msgid.link/20261030135105.2555887-1-sw@simonwunderlich.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-10-30 14:54:00 -07:00
commit 84574c7e46
7 changed files with 174 additions and 76 deletions

View File

@ -1410,7 +1410,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
return BATADV_NO_DUP;
orig_ifinfo = batadv_orig_ifinfo_new(orig_node, if_outgoing);
if (WARN_ON(!orig_ifinfo)) {
if (!orig_ifinfo) {
batadv_orig_node_put(orig_node);
return 0;
}
@ -1909,6 +1909,11 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
goto out;
}
/* Mark aggregate as full before forcing emit. */
spin_lock_bh(&bat_priv->forw_bat_list_lock);
forw_packet->num_packets = BATADV_MAX_AGGREGATION_PACKETS;
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
batadv_iv_ogm_emit(forw_packet);
/* we have to have at least one packet in the queue to determine the

View File

@ -653,6 +653,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
* NOT_FOUND
*/
cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND;
cands[select].orig_node = NULL;
/* iterate over the originator list and find the node with the closest
* dat_address which has not been selected yet

View File

@ -295,6 +295,11 @@ void batadv_mesh_free(struct net_device *mesh_iface)
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
/* the originator purge worker accesses (among others) the TT tables
* and must therefore be stopped before any of them are freed
*/
disable_delayed_work_sync(&bat_priv->orig_work);
batadv_purge_outstanding_packets(bat_priv, NULL);
batadv_tp_stop_all(bat_priv);
@ -484,8 +489,10 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
* shut down otherwise the packet may trigger de-reference errors
* further down in the receive path.
*/
if (!kref_get_unless_zero(&hard_iface->refcount))
goto err_out;
if (!kref_get_unless_zero(&hard_iface->refcount)) {
kfree_skb(skb);
return NET_RX_DROP;
}
skb = skb_share_check(skb, GFP_ATOMIC);
@ -541,7 +548,6 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
kfree_skb(skb);
err_put:
batadv_hardif_put(hard_iface);
err_out:
return NET_RX_DROP;
}

View File

@ -950,8 +950,11 @@ static int batadv_mcast_forw_packet(struct batadv_priv *bat_priv,
dest = (u8 *)mcast_tracker + sizeof(*mcast_tracker);
/* check if full tracker tvlv is within skb length */
/* check if full tracker tvlv, including padding, is within skb length */
tvlv_len = sizeof(*mcast_tracker) + ETH_ALEN * num_dests;
if (!(num_dests % 2))
tvlv_len += 2;
if (tvlv_len > skb_network_header_len(skb))
return -EINVAL;

View File

@ -221,7 +221,7 @@ static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,
unsigned long start_time, u64 total_sent,
u32 cookie)
{
u32 total_bytes;
u64 total_bytes;
u32 test_time;
u8 result;

View File

@ -26,8 +26,10 @@
#include <linux/jhash.h>
#include <linux/jiffies.h>
#include <linux/kref.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/minmax.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
@ -253,7 +255,8 @@ static int batadv_tt_len(int changes_num)
*
* Return: local translation table size in bytes.
*/
static int batadv_tt_local_transmit_size(u16 num_vlan, u16 num_entries)
static int batadv_tt_local_transmit_size(unsigned int num_vlan,
unsigned int num_entries)
{
int hdr_size;
@ -266,6 +269,25 @@ static int batadv_tt_local_transmit_size(u16 num_vlan, u16 num_entries)
return hdr_size + batadv_tt_len(num_entries);
}
/**
* batadv_tt_local_transmit_size_max() - get the maximum size of a full local table
* response
* @bat_priv: the bat priv with all the mesh interface information
*
* The full table response is sent as a single unicast TVLV packet. Its
* tvlv_len, which covers the TVLV header and the TT TVLV, is only 16 bit wide.
* This limits the response size even when packet_size_max is larger.
*
* Return: maximum size of a full local table response in bytes
*/
static int batadv_tt_local_transmit_size_max(struct batadv_priv *bat_priv)
{
int tvlv_size_max = sizeof(struct batadv_unicast_tvlv_packet) + U16_MAX;
int packet_size_max = READ_ONCE(bat_priv->packet_size_max);
return min(packet_size_max, tvlv_size_max);
}
/**
* batadv_tt_local_reserve() - reserve room in the transmittable local table
* @bat_priv: the bat priv with all the mesh interface information
@ -290,22 +312,23 @@ static int batadv_tt_local_transmit_size(u16 num_vlan, u16 num_entries)
static bool batadv_tt_local_reserve(struct batadv_priv *bat_priv, u16 num_vlan,
u16 num_entries, int *table_size)
{
int packet_size_max = READ_ONCE(bat_priv->packet_size_max);
int size_max = batadv_tt_local_transmit_size_max(bat_priv);
unsigned int entries;
unsigned int vlans;
scoped_guard(spinlock_bh, &bat_priv->tt.reserve_lock) {
bat_priv->tt.reserved_vlans += num_vlan;
bat_priv->tt.reserved_entries += num_entries;
vlans = bat_priv->tt.reserved_vlans + num_vlan;
entries = bat_priv->tt.reserved_entries + num_entries;
*table_size = batadv_tt_local_transmit_size(bat_priv->tt.reserved_vlans,
bat_priv->tt.reserved_entries);
if (*table_size <= packet_size_max)
return true;
*table_size = batadv_tt_local_transmit_size(vlans, entries);
if (*table_size > size_max)
return false;
bat_priv->tt.reserved_vlans -= num_vlan;
bat_priv->tt.reserved_entries -= num_entries;
bat_priv->tt.reserved_vlans = vlans;
bat_priv->tt.reserved_entries = entries;
}
return false;
return true;
}
/**
@ -339,9 +362,10 @@ static bool batadv_tt_local_reserve_entry(struct batadv_priv *bat_priv,
return true;
net_ratelimited_function(batadv_info, bat_priv->mesh_iface,
"Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
"Local translation table size (%i) exceeds maximum table response size (%i); Ignoring new local tt entry: %pM\n",
table_size,
READ_ONCE(bat_priv->packet_size_max), addr);
batadv_tt_local_transmit_size_max(bat_priv),
addr);
return false;
}
@ -374,8 +398,9 @@ bool batadv_tt_local_reserve_vlan(struct batadv_priv *bat_priv,
return true;
net_ratelimited_function(batadv_info, bat_priv->mesh_iface,
"Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new VLAN: %d\n",
table_size, READ_ONCE(bat_priv->packet_size_max),
"Local translation table size (%i) exceeds maximum table response size (%i); Ignoring new VLAN: %d\n",
table_size,
batadv_tt_local_transmit_size_max(bat_priv),
batadv_print_vid(vid));
return false;
@ -622,6 +647,9 @@ static u16 batadv_tt_flags_get(struct batadv_tt_common_entry *common)
* @bat_priv: the bat priv with all the mesh interface information
* @common: the TT entry involved in the event
* @flags: flags of the TT entry combined with the event flags
*
* Only a single change per client is queued. It describes the latest state of
* the client and a new event therefore replaces an already queued one.
*/
static void __batadv_tt_local_event(struct batadv_priv *bat_priv,
const struct batadv_tt_common_entry *common,
@ -631,7 +659,6 @@ static void __batadv_tt_local_event(struct batadv_priv *bat_priv,
struct batadv_tt_change_node *entry;
struct batadv_tt_change_node *safe;
bool del_op_requested;
bool del_op_entry;
size_t changes;
tt_change_node = kmem_cache_alloc(batadv_tt_change_cache, GFP_ATOMIC);
@ -643,9 +670,17 @@ static void __batadv_tt_local_event(struct batadv_priv *bat_priv,
ether_addr_copy(tt_change_node->change.addr, common->addr);
tt_change_node->change.vid = htons(common->vid);
tt_change_node->change.flags = flags;
del_op_requested = flags & BATADV_TT_CLIENT_DEL;
/* the ROAM flag is only meaningful for the receiver in combination
* with a DEL. An ADD with ROAM would be interpreted as a roaming
* advertisement
*/
if (!del_op_requested)
flags &= ~BATADV_TT_CLIENT_ROAM;
tt_change_node->change.flags = flags;
/* check for ADD+DEL, DEL+ADD, ADD+ADD or DEL+DEL events */
spin_lock_bh(&bat_priv->tt.changes_list_lock);
changes = READ_ONCE(bat_priv->tt.local_changes);
@ -657,25 +692,12 @@ static void __batadv_tt_local_event(struct batadv_priv *bat_priv,
if (entry->change.vid != tt_change_node->change.vid)
continue;
del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
if (del_op_requested != del_op_entry) {
/* DEL+ADD in the same orig interval have no effect and
* can be removed to avoid silly behaviour on the
* receiver side. The other way around (ADD+DEL) can
* happen in case of roaming of a client still in the
* NEW state. Roaming of NEW clients is now possible due
* to automatically recognition of "temporary" clients
*/
list_del(&entry->list);
kmem_cache_free(batadv_tt_change_cache, entry);
changes--;
} else {
/* this is a second add or del in the same originator
* interval. It could mean that flags have been changed
* (e.g. double add): update them
*/
entry->change.flags = flags;
}
/* the other nodes may know the client with different
* flags. A DEL+ADD must therefore still announce the
* current flags and an ADD+DEL must still remove the
* client. ADD+ADD and DEL+DEL only update the flags
*/
entry->change.flags = flags;
kmem_cache_free(batadv_tt_change_cache, tt_change_node);
goto update_changes;
@ -727,9 +749,9 @@ static u16 batadv_tt_entries(u16 tt_len)
*/
static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
{
unsigned int tt_local_entries = 0;
struct batadv_meshif_vlan *vlan;
u16 tt_local_entries = 0;
u16 num_vlan = 0;
unsigned int num_vlan = 0;
rcu_read_lock();
hlist_for_each_entry_rcu(vlan, &bat_priv->meshif_vlan_list, list) {
@ -811,14 +833,21 @@ static void batadv_tt_local_add_roam(struct batadv_priv *bat_priv,
if (!tt_global)
return;
/* Check whether it is a roaming, but don't do anything if the roaming
* process has already been handled
/* Handle newly roamed client - but not roamed back client.
*
* A client which roamed back must always be reclaimed from the
* originator(s) which sent the ROAMING_ADV. The global entry created by
* this ROAMING_ADV might still carry BATADV_TT_CLIENT_ROAM because the
* new originator did not yet announce the client.
*/
scoped_guard(spinlock_bh, &tt_global->common.flags_lock) {
if (tt_global->common.flags & BATADV_TT_CLIENT_ROAM)
return;
if (!roamed_back) {
scoped_guard(spinlock_bh, &tt_global->common.flags_lock) {
/* Check whether it is a roaming, but don't do anything
* if the roaming process has already been handled.
*/
if (tt_global->common.flags & BATADV_TT_CLIENT_ROAM)
return;
if (!roamed_back) {
/* The global entry has to be marked as ROAMING and has to be
* kept for consistency purpose.
*
@ -886,6 +915,7 @@ static bool batadv_tt_local_add_existing(struct batadv_priv *bat_priv,
bool *roamed_back)
{
struct batadv_tt_common_entry *common = &tt_local->common;
bool readded = false;
tt_local->last_seen = jiffies;
@ -900,8 +930,7 @@ static bool batadv_tt_local_add_existing(struct batadv_priv *bat_priv,
* flag can be reset like it was never enqueued
*/
common->flags &= ~BATADV_TT_CLIENT_PENDING;
return true;
readded = true;
}
if (common->flags & BATADV_TT_CLIENT_ROAM) {
@ -918,7 +947,7 @@ static bool batadv_tt_local_add_existing(struct batadv_priv *bat_priv,
}
}
return false;
return readded;
}
/**
@ -1319,22 +1348,24 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
* batadv_tt_tvlv_container_update() - update the translation table tvlv
* container after local tt changes have been committed
* @bat_priv: the bat priv with all the mesh interface information
* @changes_list: list of committed changes which will be consumed
* @tt_diff_entries_num: number of entries in @changes_list
*/
static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv,
struct list_head *changes_list,
int tt_diff_entries_num)
{
struct batadv_tvlv_tt_change *tt_change;
struct batadv_tt_change_node *entry;
struct batadv_tvlv_tt_data *tt_data;
struct batadv_tt_change_node *safe;
int tt_diff_entries_count = 0;
int tt_diff_entries_num = 0;
bool drop_changes = false;
size_t tt_extra_len = 0;
int tt_change_len = 0;
int tt_diff_len;
u16 tvlv_len;
tt_diff_entries_num = READ_ONCE(bat_priv->tt.local_changes);
tt_diff_len = batadv_tt_len(tt_diff_entries_num);
/* if we have too many changes for one packet don't send any
@ -1352,19 +1383,39 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
&tt_change, &tt_diff_len);
if (!tvlv_len)
if (!tvlv_len) {
/* the changes are lost and the other nodes have to request the
* full table. Don't answer TT requests for the new TTVN with
* the stale changeset of the previous TTVN. Without changes, the
* TTVN was not incremented and the last changeset is still valid
*/
if (drop_changes || tt_diff_entries_num > 0) {
list_for_each_entry_safe(entry, safe, changes_list,
list) {
list_del(&entry->list);
kmem_cache_free(batadv_tt_change_cache, entry);
}
spin_lock_bh(&bat_priv->tt.last_changeset_lock);
kfree(bat_priv->tt.last_changeset);
bat_priv->tt.last_changeset = NULL;
bat_priv->tt.last_changeset_len = 0;
spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
}
/* announce the already committed TTVN in the next OGM interval
* instead of waiting for BATADV_TT_OGM_APPEND_MAX idle rounds
*/
atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
return;
}
tt_data->flags = BATADV_TT_OGM_DIFF;
if (!drop_changes && tt_diff_len == 0)
goto container_register;
spin_lock_bh(&bat_priv->tt.changes_list_lock);
WRITE_ONCE(bat_priv->tt.local_changes, 0);
list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
list) {
list_for_each_entry_safe(entry, safe, changes_list, list) {
if (tt_diff_entries_count < tt_diff_entries_num) {
memcpy(tt_change + tt_diff_entries_count,
&entry->change,
@ -1374,7 +1425,6 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
list_del(&entry->list);
kmem_cache_free(batadv_tt_change_cache, entry);
}
spin_unlock_bh(&bat_priv->tt.changes_list_lock);
tt_extra_len = batadv_tt_len(tt_diff_entries_num -
tt_diff_entries_count);
@ -3342,8 +3392,12 @@ static bool batadv_tt_local_valid(void *entry_ptr,
if (tt_flags & BATADV_TT_CLIENT_NEW)
return false;
/* the entry is (still) announced. A ROAM flag of an entry which is
* pending to be removed must not be transmitted. Otherwise, the
* receiver would handle it like a roaming advertisement
*/
if (flags)
*flags = tt_flags;
*flags = tt_flags & ~BATADV_TT_CLIENT_ROAM;
return true;
}
@ -3922,21 +3976,30 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
u16 tt_num_changes, u8 ttvn)
{
int roams;
u8 flags;
int i;
for (i = 0; i < tt_num_changes; i++) {
if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
flags = (tt_change + i)->flags;
if (flags & BATADV_TT_CLIENT_DEL) {
roams = flags & BATADV_TT_CLIENT_ROAM;
batadv_tt_global_del(bat_priv, orig_node,
(tt_change + i)->addr,
ntohs((tt_change + i)->vid),
"tt removed by changes",
roams);
} else {
/* an announced client cannot have roamed away from
* orig_node. Only a ROAMING_ADV is allowed to add a
* global entry with the ROAM flag
*/
flags &= ~BATADV_TT_CLIENT_ROAM;
if (!batadv_tt_global_add(bat_priv, orig_node,
(tt_change + i)->addr,
ntohs((tt_change + i)->vid),
(tt_change + i)->flags, ttvn))
flags, ttvn))
/* In case of problem while storing a
* global_entry, we stop the updating
* procedure without committing the
@ -4412,11 +4475,25 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
*/
static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
{
LIST_HEAD(changes_list);
int changes_num;
lockdep_assert_held(&bat_priv->tt.commit_lock);
if (READ_ONCE(bat_priv->tt.local_changes) == 0) {
/* atomically get the list of changes. The TTVN decision and the
* announced changeset must cover the same events. Events queued
* afterwards stay in the tt.changes_list for the next TT round
*/
spin_lock_bh(&bat_priv->tt.changes_list_lock);
list_splice_init(&bat_priv->tt.changes_list, &changes_list);
changes_num = READ_ONCE(bat_priv->tt.local_changes);
WRITE_ONCE(bat_priv->tt.local_changes, 0);
spin_unlock_bh(&bat_priv->tt.changes_list_lock);
if (changes_num == 0) {
if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
batadv_tt_tvlv_container_update(bat_priv);
batadv_tt_tvlv_container_update(bat_priv, &changes_list,
changes_num);
return;
}
@ -4433,7 +4510,7 @@ static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
/* reset the sending counter */
atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
batadv_tt_tvlv_container_update(bat_priv);
batadv_tt_tvlv_container_update(bat_priv, &changes_list, changes_num);
}
/**
@ -4675,16 +4752,16 @@ void batadv_tt_local_resize_to_mtu(struct net_device *mesh_iface)
struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
int timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
bool reduced = false;
int packet_size_max;
int table_size;
int size_max;
packet_size_max = READ_ONCE(bat_priv->packet_size_max);
size_max = batadv_tt_local_transmit_size_max(bat_priv);
spin_lock_bh(&bat_priv->tt.commit_lock);
while (timeout) {
table_size = batadv_tt_local_table_transmit_size(bat_priv);
if (packet_size_max >= table_size)
if (size_max >= table_size)
break;
batadv_tt_local_purge(bat_priv, timeout);
@ -4693,8 +4770,8 @@ void batadv_tt_local_resize_to_mtu(struct net_device *mesh_iface)
timeout /= 2;
reduced = true;
net_ratelimited_function(batadv_info, mesh_iface,
"Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
packet_size_max);
"Forced to purge local tt entries to fit new maximum table response size (%i)\n",
size_max);
}
/* commit these changes immediately, to avoid synchronization problem

View File

@ -2047,7 +2047,13 @@ struct batadv_forw_packet {
/** @direct_link_flags: direct link flags for aggregated OGM packets */
DECLARE_BITMAP(direct_link_flags, BATADV_MAX_AGGREGATION_PACKETS);
/** @num_packets: counter for aggregated OGMv1 packets */
/**
* @num_packets: counter for aggregated OGMv1 packets. Set to
* BATADV_MAX_AGGREGATION_PACKETS (independent of the real number of
* aggregated packets) by the send worker to prevent further
* aggregation while the packet is emitted. It must therefore not be
* used to iterate over the aggregated packets
*/
u8 num_packets;
/** @delayed_work: work queue callback item for packet sending */