Commit 18522108 authored by David S. Miller's avatar David S. Miller

Merge tag 'batadv-next-for-davem-20180919' of git://git.open-mesh.org/linux-merge

Simon Wunderlich says:

====================
This feature/cleanup patchset includes the following patches:

 - bump version strings, by Simon Wunderlich

 - Inform users about debugfs interface deprecation, by Sven Eckelmann

 - Implement tracing, planned to replace debugfs log messages,
   by Sven Eckelmann

 - Move OGM rebroadcasts to per interface struct, by Sven Eckelmann

 - Enable LockLess TX to increase throughput, by Sven Eckelmann
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b9d957c5 a7ea49af
......@@ -106,3 +106,14 @@ config BATMAN_ADV_DEBUG
say N here. This enables compilation of support for
outputting debugging information to the kernel log. The
output is controlled via the module parameter debug.
config BATMAN_ADV_TRACING
bool "B.A.T.M.A.N. tracing support"
depends on BATMAN_ADV
depends on EVENT_TRACING
help
This is an option for use by developers; most people should
say N here. Select this option to gather traces like the debug
messages using the generic tracing infrastructure of the kernel.
BATMAN_ADV_DEBUG must also be selected to get trace events for
batadv_dbg.
......@@ -42,6 +42,9 @@ batman-adv-y += routing.o
batman-adv-y += send.o
batman-adv-y += soft-interface.o
batman-adv-y += sysfs.o
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
CFLAGS_trace.o := -I$(src)
This diff is collapsed.
......@@ -47,8 +47,24 @@
static struct dentry *batadv_debugfs;
/**
* batadv_debugfs_deprecated() - Log use of deprecated batadv debugfs access
* @file: file which was accessed
* @alt: explanation what can be used as alternative
*/
void batadv_debugfs_deprecated(struct file *file, const char *alt)
{
struct dentry *dentry = file_dentry(file);
const char *name = dentry->d_name.name;
pr_warn_ratelimited(DEPRECATED "%s (pid %d) Use of debugfs file \"%s\".\n%s",
current->comm, task_pid_nr(current), name, alt);
}
static int batadv_algorithms_open(struct inode *inode, struct file *file)
{
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_ROUTING_ALGOS instead\n");
return single_open(file, batadv_algo_seq_print_text, NULL);
}
......@@ -56,6 +72,8 @@ static int neighbors_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_NEIGHBORS instead\n");
return single_open(file, batadv_hardif_neigh_seq_print_text, net_dev);
}
......@@ -63,6 +81,8 @@ static int batadv_originators_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_ORIGINATORS instead\n");
return single_open(file, batadv_orig_seq_print_text, net_dev);
}
......@@ -79,6 +99,8 @@ static int batadv_originators_hardif_open(struct inode *inode,
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_HARDIFS instead\n");
return single_open(file, batadv_orig_hardif_seq_print_text, net_dev);
}
......@@ -86,6 +108,8 @@ static int batadv_gateways_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_GATEWAYS instead\n");
return single_open(file, batadv_gw_client_seq_print_text, net_dev);
}
......@@ -93,6 +117,8 @@ static int batadv_transtable_global_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_TRANSTABLE_GLOBAL instead\n");
return single_open(file, batadv_tt_global_seq_print_text, net_dev);
}
......@@ -101,6 +127,8 @@ static int batadv_bla_claim_table_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_BLA_CLAIM instead\n");
return single_open(file, batadv_bla_claim_table_seq_print_text,
net_dev);
}
......@@ -110,6 +138,8 @@ static int batadv_bla_backbone_table_open(struct inode *inode,
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_BLA_BACKBONE instead\n");
return single_open(file, batadv_bla_backbone_table_seq_print_text,
net_dev);
}
......@@ -128,6 +158,8 @@ static int batadv_dat_cache_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_DAT_CACHE instead\n");
return single_open(file, batadv_dat_cache_seq_print_text, net_dev);
}
#endif
......@@ -136,6 +168,8 @@ static int batadv_transtable_local_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_TRANSTABLE_LOCAL instead\n");
return single_open(file, batadv_tt_local_seq_print_text, net_dev);
}
......@@ -149,6 +183,7 @@ static int batadv_nc_nodes_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file, "");
return single_open(file, batadv_nc_nodes_seq_print_text, net_dev);
}
#endif
......@@ -165,6 +200,8 @@ static int batadv_mcast_flags_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
batadv_debugfs_deprecated(file,
"Use genl command BATADV_CMD_GET_MCAST_FLAGS instead\n");
return single_open(file, batadv_mcast_flags_seq_print_text, net_dev);
}
#endif
......
......@@ -21,12 +21,14 @@
#include "main.h"
struct file;
struct net_device;
#define BATADV_DEBUGFS_SUBDIR "batman_adv"
#if IS_ENABLED(CONFIG_BATMAN_ADV_DEBUGFS)
void batadv_debugfs_deprecated(struct file *file, const char *alt);
void batadv_debugfs_init(void);
void batadv_debugfs_destroy(void);
int batadv_debugfs_add_meshif(struct net_device *dev);
......@@ -38,6 +40,10 @@ void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface);
#else
static inline void batadv_debugfs_deprecated(struct file *file, const char *alt)
{
}
static inline void batadv_debugfs_init(void)
{
}
......
......@@ -763,11 +763,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
hard_iface->soft_iface = soft_iface;
bat_priv = netdev_priv(hard_iface->soft_iface);
if (bat_priv->num_ifaces >= UINT_MAX) {
ret = -ENOSPC;
goto err_dev;
}
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
soft_iface, NULL, NULL, NULL);
if (ret)
......@@ -777,16 +772,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
if (ret < 0)
goto err_upper;
hard_iface->if_num = bat_priv->num_ifaces;
bat_priv->num_ifaces++;
hard_iface->if_status = BATADV_IF_INACTIVE;
ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces);
if (ret < 0) {
bat_priv->algo_ops->iface.disable(hard_iface);
bat_priv->num_ifaces--;
hard_iface->if_status = BATADV_IF_NOT_IN_USE;
goto err_upper;
}
kref_get(&hard_iface->refcount);
hard_iface->batman_adv_ptype.type = ethertype;
......@@ -833,6 +819,33 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
return ret;
}
/**
* batadv_hardif_cnt() - get number of interfaces enslaved to soft interface
* @soft_iface: soft interface to check
*
* This function is only using RCU for locking - the result can therefore be
* off when another functions is modifying the list at the same time. The
* caller can use the rtnl_lock to make sure that the count is accurate.
*
* Return: number of connected/enslaved hard interfaces
*/
static size_t batadv_hardif_cnt(const struct net_device *soft_iface)
{
struct batadv_hard_iface *hard_iface;
size_t count = 0;
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
if (hard_iface->soft_iface != soft_iface)
continue;
count++;
}
rcu_read_unlock();
return count;
}
/**
* batadv_hardif_disable_interface() - Remove hard interface from soft interface
* @hard_iface: hard interface to be removed
......@@ -855,9 +868,6 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
dev_remove_pack(&hard_iface->batman_adv_ptype);
batadv_hardif_put(hard_iface);
bat_priv->num_ifaces--;
batadv_orig_hash_del_if(hard_iface, bat_priv->num_ifaces);
primary_if = batadv_primary_if_get_selected(bat_priv);
if (hard_iface == primary_if) {
struct batadv_hard_iface *new_if;
......@@ -881,7 +891,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
/* nobody uses this interface anymore */
if (bat_priv->num_ifaces == 0) {
if (batadv_hardif_cnt(hard_iface->soft_iface) <= 1) {
batadv_gw_check_client_stop(bat_priv);
if (autodel == BATADV_IF_CLEANUP_AUTO)
......@@ -917,7 +927,6 @@ batadv_hardif_add_interface(struct net_device *net_dev)
if (ret)
goto free_if;
hard_iface->if_num = 0;
hard_iface->net_dev = net_dev;
hard_iface->soft_iface = NULL;
hard_iface->if_status = BATADV_IF_NOT_IN_USE;
......
......@@ -47,6 +47,7 @@
#include <linux/wait.h>
#include <uapi/linux/batadv_packet.h>
#include "debugfs.h"
#include "hard-interface.h"
#include "log.h"
#include "originator.h"
......@@ -74,6 +75,8 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
if (!try_module_get(THIS_MODULE))
return -EBUSY;
batadv_debugfs_deprecated(file, "");
nonseekable_open(inode, file);
socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
......
......@@ -40,6 +40,9 @@
#include <linux/wait.h>
#include <stdarg.h>
#include "debugfs.h"
#include "trace.h"
#define BATADV_LOG_BUFF_MASK (batadv_log_buff_len - 1)
static const int batadv_log_buff_len = BATADV_LOG_BUF_LEN;
......@@ -98,13 +101,19 @@ static int batadv_fdebug_log(struct batadv_priv_debug_log *debug_log,
*/
int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
char tmp_log_buf[256];
va_start(args, fmt);
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
batadv_fdebug_log(bat_priv->debug_log, "[%10u] %s",
jiffies_to_msecs(jiffies), tmp_log_buf);
vaf.fmt = fmt;
vaf.va = &args;
batadv_fdebug_log(bat_priv->debug_log, "[%10u] %pV",
jiffies_to_msecs(jiffies), &vaf);
trace_batadv_dbg(bat_priv, &vaf);
va_end(args);
return 0;
......@@ -115,6 +124,9 @@ static int batadv_log_open(struct inode *inode, struct file *file)
if (!try_module_get(THIS_MODULE))
return -EBUSY;
batadv_debugfs_deprecated(file,
"Use tracepoint batadv:batadv_dbg instead\n");
nonseekable_open(inode, file);
file->private_data = inode->i_private;
return 0;
......
......@@ -25,7 +25,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2018.2"
#define BATADV_SOURCE_VERSION "2018.4"
#endif
/* B.A.T.M.A.N. parameters */
......
......@@ -904,9 +904,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
batadv_frag_purge_orig(orig_node, NULL);
if (orig_node->bat_priv->algo_ops->orig.free)
orig_node->bat_priv->algo_ops->orig.free(orig_node);
kfree(orig_node->tt_buff);
kfree(orig_node);
}
......@@ -1555,107 +1552,3 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
return ret;
}
/**
* batadv_orig_hash_add_if() - Add interface to originators in orig_hash
* @hard_iface: hard interface to add (already slave of the soft interface)
* @max_if_num: new number of interfaces
*
* Return: 0 on success or negative error number in case of failure
*/
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
unsigned int max_if_num)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_algo_ops *bao = bat_priv->algo_ops;
struct batadv_hashtable *hash = bat_priv->orig_hash;
struct hlist_head *head;
struct batadv_orig_node *orig_node;
u32 i;
int ret;
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num
*/
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
ret = 0;
if (bao->orig.add_if)
ret = bao->orig.add_if(orig_node, max_if_num);
if (ret == -ENOMEM)
goto err;
}
rcu_read_unlock();
}
return 0;
err:
rcu_read_unlock();
return -ENOMEM;
}
/**
* batadv_orig_hash_del_if() - Remove interface from originators in orig_hash
* @hard_iface: hard interface to remove (still slave of the soft interface)
* @max_if_num: new number of interfaces
*
* Return: 0 on success or negative error number in case of failure
*/
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
unsigned int max_if_num)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_hashtable *hash = bat_priv->orig_hash;
struct hlist_head *head;
struct batadv_hard_iface *hard_iface_tmp;
struct batadv_orig_node *orig_node;
struct batadv_algo_ops *bao = bat_priv->algo_ops;
u32 i;
int ret;
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num
*/
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
ret = 0;
if (bao->orig.del_if)
ret = bao->orig.del_if(orig_node, max_if_num,
hard_iface->if_num);
if (ret == -ENOMEM)
goto err;
}
rcu_read_unlock();
}
/* renumber remaining batman interfaces _inside_ of orig_hash_lock */
rcu_read_lock();
list_for_each_entry_rcu(hard_iface_tmp, &batadv_hardif_list, list) {
if (hard_iface_tmp->if_status == BATADV_IF_NOT_IN_USE)
continue;
if (hard_iface == hard_iface_tmp)
continue;
if (hard_iface->soft_iface != hard_iface_tmp->soft_iface)
continue;
if (hard_iface_tmp->if_num > hard_iface->if_num)
hard_iface_tmp->if_num--;
}
rcu_read_unlock();
hard_iface->if_num = -1;
return 0;
err:
rcu_read_unlock();
return -ENOMEM;
}
......@@ -72,10 +72,6 @@ void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo);
int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
unsigned int max_if_num);
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
unsigned int max_if_num);
struct batadv_orig_node_vlan *
batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
unsigned short vid);
......
......@@ -833,7 +833,6 @@ static int batadv_softif_init_late(struct net_device *dev)
atomic_set(&bat_priv->frag_seqno, random_seqno);
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
batadv_nc_init_bat_priv(bat_priv);
......@@ -1051,6 +1050,7 @@ static void batadv_softif_init_early(struct net_device *dev)
dev->needs_free_netdev = true;
dev->priv_destructor = batadv_softif_free;
dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
dev->features |= NETIF_F_LLTX;
dev->priv_flags |= IFF_NO_QUEUE;
/* can't call min_mtu, because the needed variables
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
*
* Sven Eckelmann
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/module.h>
#define CREATE_TRACE_POINTS
#include "trace.h"
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2010-2018 B.A.T.M.A.N. contributors:
*
* Sven Eckelmann
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_NET_BATMAN_ADV_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
#define _NET_BATMAN_ADV_TRACE_H_
#include "main.h"
#include <linux/tracepoint.h>
#undef TRACE_SYSTEM
#define TRACE_SYSTEM batadv
/* provide dummy function when tracing is disabled */
#if !defined(CONFIG_BATMAN_ADV_TRACING)
#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {}
#endif /* CONFIG_BATMAN_ADV_TRACING */
#define BATADV_MAX_MSG_LEN 256
TRACE_EVENT(batadv_dbg,
TP_PROTO(struct batadv_priv *bat_priv,
struct va_format *vaf),
TP_ARGS(bat_priv, vaf),
TP_STRUCT__entry(
__string(device, bat_priv->soft_iface->name)
__string(driver, KBUILD_MODNAME)
__dynamic_array(char, msg, BATADV_MAX_MSG_LEN)
),
TP_fast_assign(
__assign_str(device, bat_priv->soft_iface->name);
__assign_str(driver, KBUILD_MODNAME);
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
BATADV_MAX_MSG_LEN,
vaf->fmt,
*vaf->va) >= BATADV_MAX_MSG_LEN);
),
TP_printk(
"%s %s %s",
__get_str(driver),
__get_str(device),
__get_str(msg)
)
);
#endif /* _NET_BATMAN_ADV_TRACE_H_ || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace
/* This part must be outside protection */
#include <trace/define_trace.h>
......@@ -167,9 +167,6 @@ struct batadv_hard_iface {
/** @list: list node for batadv_hardif_list */
struct list_head list;
/** @if_num: identificator of the interface */
unsigned int if_num;
/** @if_status: status of the interface for batman-adv */
char if_status;
......@@ -232,6 +229,20 @@ struct batadv_hard_iface {
spinlock_t neigh_list_lock;
};
/**
* struct batadv_orig_ifinfo - B.A.T.M.A.N. IV private orig_ifinfo members
*/
struct batadv_orig_ifinfo_bat_iv {
/**
* @bcast_own: bitfield which counts the number of our OGMs this
* orig_node rebroadcasted "back" to us (relative to last_real_seqno)
*/
DECLARE_BITMAP(bcast_own, BATADV_TQ_LOCAL_WINDOW_SIZE);
/** @bcast_own_sum: sum of bcast_own */
u8 bcast_own_sum;
};
/**
* struct batadv_orig_ifinfo - originator info per outgoing interface
*/
......@@ -257,6 +268,9 @@ struct batadv_orig_ifinfo {
/** @batman_seqno_reset: time when the batman seqno window was reset */
unsigned long batman_seqno_reset;
/** @bat_iv: B.A.T.M.A.N. IV private structure */
struct batadv_orig_ifinfo_bat_iv bat_iv;
/** @refcount: number of contexts the object is used */
struct kref refcount;
......@@ -339,19 +353,10 @@ struct batadv_orig_node_vlan {
*/
struct batadv_orig_bat_iv {
/**
* @bcast_own: set of bitfields (one per hard-interface) where each one
* counts the number of our OGMs this orig_node rebroadcasted "back" to
* us (relative to last_real_seqno). Every bitfield is
* BATADV_TQ_LOCAL_WINDOW_SIZE bits long.
*/
unsigned long *bcast_own;
/** @bcast_own_sum: sum of bcast_own */
u8 *bcast_own_sum;
/**
* @ogm_cnt_lock: lock protecting bcast_own, bcast_own_sum,
* neigh_node->bat_iv.real_bits & neigh_node->bat_iv.real_packet_count
* @ogm_cnt_lock: lock protecting &batadv_orig_ifinfo_bat_iv.bcast_own,
* &batadv_orig_ifinfo_bat_iv.bcast_own_sum,
* &batadv_neigh_ifinfo_bat_iv.bat_iv.real_bits and
* &batadv_neigh_ifinfo_bat_iv.real_packet_count
*/
spinlock_t ogm_cnt_lock;
};
......@@ -1597,9 +1602,6 @@ struct batadv_priv {
/** @batman_queue_left: number of remaining OGM packet slots */
atomic_t batman_queue_left;
/** @num_ifaces: number of interfaces assigned to this mesh interface */
unsigned int num_ifaces;
/** @mesh_obj: kobject for sysfs mesh subdirectory */
struct kobject *mesh_obj;
......@@ -2179,28 +2181,6 @@ struct batadv_algo_neigh_ops {
* struct batadv_algo_orig_ops - mesh algorithm callbacks (originator specific)
*/
struct batadv_algo_orig_ops {
/**
* @free: free the resources allocated by the routing algorithm for an
* orig_node object (optional)
*/
void (*free)(struct batadv_orig_node *orig_node);
/**
* @add_if: ask the routing algorithm to apply the needed changes to the
* orig_node due to a new hard-interface being added into the mesh
* (optional)
*/
int (*add_if)(struct batadv_orig_node *orig_node,
unsigned int max_if_num);
/**
* @del_if: ask the routing algorithm to apply the needed changes to the
* orig_node due to an hard-interface being removed from the mesh
* (optional)
*/
int (*del_if)(struct batadv_orig_node *orig_node,
unsigned int max_if_num, unsigned int del_if_num);
#ifdef CONFIG_BATMAN_ADV_DEBUGFS
/** @print: print the originator table (optional) */
void (*print)(struct batadv_priv *priv, struct seq_file *seq,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment