Commit 3ea00443 authored by David S. Miller's avatar David S. Miller

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

Simon Wunderlich says:

====================
This feature patchset includes the following changes:

 - two patches with minimal clean up work by Antonio Quartulli and
   Simon Wunderlich

 - eight patches of B.A.T.M.A.N. V, API and documentation clean
   up work, by Antonio Quartulli and Marek Lindner

 - Andrew Lunn fixed the skb priority adoption when forwarding
   fragmented packets (two patches)

 - Multicast optimization support is now enabled for bridges which
   comes with some protocol updates, by Linus Luessing
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ca9354a1 4e3e823b
What: /sys/class/net/<iface>/batman-adv/throughput_override
Date: Feb 2014
Contact: Antonio Quartulli <antonio@meshcoding.com>
description:
Defines the throughput value to be used by B.A.T.M.A.N. V
when estimating the link throughput using this interface.
If the value is set to 0 then batman-adv will try to
estimate the throughput by itself.
What: /sys/class/net/<iface>/batman-adv/elp_interval What: /sys/class/net/<iface>/batman-adv/elp_interval
Date: Feb 2014 Date: Feb 2014
Contact: Linus Lüssing <linus.luessing@web.de> Contact: Linus Lüssing <linus.luessing@web.de>
Description: Description:
Defines the interval in milliseconds in which batman Defines the interval in milliseconds in which batman
sends its probing packets for link quality measurements. emits probing packets for neighbor sensing (ELP).
What: /sys/class/net/<iface>/batman-adv/iface_status What: /sys/class/net/<iface>/batman-adv/iface_status
Date: May 2010 Date: May 2010
...@@ -28,3 +19,12 @@ Description: ...@@ -28,3 +19,12 @@ Description:
The /sys/class/net/<iface>/batman-adv/mesh_iface file The /sys/class/net/<iface>/batman-adv/mesh_iface file
displays the batman mesh interface this <iface> displays the batman mesh interface this <iface>
currently is associated with. currently is associated with.
What: /sys/class/net/<iface>/batman-adv/throughput_override
Date: Feb 2014
Contact: Antonio Quartulli <a@unstable.cc>
description:
Defines the throughput value to be used by B.A.T.M.A.N. V
when estimating the link throughput using this interface.
If the value is set to 0 then batman-adv will try to
estimate the throughput by itself.
...@@ -66,7 +66,7 @@ config BATMAN_ADV_NC ...@@ -66,7 +66,7 @@ config BATMAN_ADV_NC
config BATMAN_ADV_MCAST config BATMAN_ADV_MCAST
bool "Multicast optimisation" bool "Multicast optimisation"
depends on BATMAN_ADV depends on BATMAN_ADV && INET && !(BRIDGE=m && BATMAN_ADV=y)
default n default n
help help
This option enables the multicast optimisation which aims to This option enables the multicast optimisation which aims to
......
...@@ -18,13 +18,14 @@ ...@@ -18,13 +18,14 @@
#ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ #ifndef _NET_BATMAN_ADV_BAT_ALGO_H_
#define _NET_BATMAN_ADV_BAT_ALGO_H_ #define _NET_BATMAN_ADV_BAT_ALGO_H_
struct batadv_priv; #include "main.h"
int batadv_iv_init(void); int batadv_iv_init(void);
#ifdef CONFIG_BATMAN_ADV_BATMAN_V #ifdef CONFIG_BATMAN_ADV_BATMAN_V
int batadv_v_init(void); int batadv_v_init(void);
void batadv_v_hardif_init(struct batadv_hard_iface *hardif);
int batadv_v_mesh_init(struct batadv_priv *bat_priv); int batadv_v_mesh_init(struct batadv_priv *bat_priv);
void batadv_v_mesh_free(struct batadv_priv *bat_priv); void batadv_v_mesh_free(struct batadv_priv *bat_priv);
...@@ -35,6 +36,10 @@ static inline int batadv_v_init(void) ...@@ -35,6 +36,10 @@ static inline int batadv_v_init(void)
return 0; return 0;
} }
static inline void batadv_v_hardif_init(struct batadv_hard_iface *hardif)
{
}
static inline int batadv_v_mesh_init(struct batadv_priv *bat_priv) static inline int batadv_v_mesh_init(struct batadv_priv *bat_priv)
{ {
return 0; return 0;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/lockdep.h> #include <linux/lockdep.h>
...@@ -58,6 +59,8 @@ ...@@ -58,6 +59,8 @@
#include "send.h" #include "send.h"
#include "translation-table.h" #include "translation-table.h"
static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work);
/** /**
* enum batadv_dup_status - duplicate status * enum batadv_dup_status - duplicate status
* @BATADV_NO_DUP: the packet is no duplicate * @BATADV_NO_DUP: the packet is no duplicate
...@@ -336,7 +339,8 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, ...@@ -336,7 +339,8 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
{ {
struct batadv_neigh_node *neigh_node; struct batadv_neigh_node *neigh_node;
neigh_node = batadv_neigh_node_new(orig_node, hard_iface, neigh_addr); neigh_node = batadv_neigh_node_get_or_create(orig_node,
hard_iface, neigh_addr);
if (!neigh_node) if (!neigh_node)
goto out; goto out;
...@@ -730,7 +734,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, ...@@ -730,7 +734,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
/* start timer for this packet */ /* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
batadv_send_outstanding_bat_ogm_packet); batadv_iv_send_outstanding_bat_ogm_packet);
queue_delayed_work(batadv_event_workqueue, queue_delayed_work(batadv_event_workqueue,
&forw_packet_aggr->delayed_work, &forw_packet_aggr->delayed_work,
send_time - jiffies); send_time - jiffies);
...@@ -937,6 +941,19 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ...@@ -937,6 +941,19 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
u16 tvlv_len = 0; u16 tvlv_len = 0;
unsigned long send_time; unsigned long send_time;
if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
(hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
return;
/* the interface gets activated here to avoid race conditions between
* the moment of activating the interface in
* hardif_activate_interface() where the originator mac is set and
* outdated packets (especially uninitialized mac addresses) in the
* packet queue
*/
if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
hard_iface->if_status = BATADV_IF_ACTIVE;
primary_if = batadv_primary_if_get_selected(bat_priv); primary_if = batadv_primary_if_get_selected(bat_priv);
if (hard_iface == primary_if) { if (hard_iface == primary_if) {
...@@ -1778,6 +1795,45 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, ...@@ -1778,6 +1795,45 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
batadv_orig_node_put(orig_node); batadv_orig_node_put(orig_node);
} }
static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
{
struct delayed_work *delayed_work;
struct batadv_forw_packet *forw_packet;
struct batadv_priv *bat_priv;
delayed_work = to_delayed_work(work);
forw_packet = container_of(delayed_work, struct batadv_forw_packet,
delayed_work);
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
goto out;
batadv_iv_ogm_emit(forw_packet);
/* we have to have at least one packet in the queue to determine the
* queues wake up time unless we are shutting down.
*
* only re-schedule if this is the "original" copy, e.g. the OGM of the
* primary interface should only be rescheduled once per period, but
* this function will be called for the forw_packet instances of the
* other secondary interfaces as well.
*/
if (forw_packet->own &&
forw_packet->if_incoming == forw_packet->if_outgoing)
batadv_iv_ogm_schedule(forw_packet->if_incoming);
out:
/* don't count own packet */
if (!forw_packet->own)
atomic_inc(&bat_priv->batman_queue_left);
batadv_forw_packet_free(forw_packet);
}
static int batadv_iv_ogm_receive(struct sk_buff *skb, static int batadv_iv_ogm_receive(struct sk_buff *skb,
struct batadv_hard_iface *if_incoming) struct batadv_hard_iface *if_incoming)
{ {
...@@ -1794,7 +1850,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, ...@@ -1794,7 +1850,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
/* did we receive a B.A.T.M.A.N. IV OGM packet on an interface /* did we receive a B.A.T.M.A.N. IV OGM packet on an interface
* that does not have B.A.T.M.A.N. IV enabled ? * that does not have B.A.T.M.A.N. IV enabled ?
*/ */
if (bat_priv->bat_algo_ops->bat_ogm_emit != batadv_iv_ogm_emit) if (bat_priv->bat_algo_ops->bat_iface_enable !=
batadv_iv_ogm_iface_enable)
return NET_RX_DROP; return NET_RX_DROP;
batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX); batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
...@@ -2052,14 +2109,19 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1, ...@@ -2052,14 +2109,19 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
return ret; return ret;
} }
static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
{
/* begin scheduling originator messages on that interface */
batadv_iv_ogm_schedule(hard_iface);
}
static struct batadv_algo_ops batadv_batman_iv __read_mostly = { static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
.name = "BATMAN_IV", .name = "BATMAN_IV",
.bat_iface_activate = batadv_iv_iface_activate,
.bat_iface_enable = batadv_iv_ogm_iface_enable, .bat_iface_enable = batadv_iv_ogm_iface_enable,
.bat_iface_disable = batadv_iv_ogm_iface_disable, .bat_iface_disable = batadv_iv_ogm_iface_disable,
.bat_iface_update_mac = batadv_iv_ogm_iface_update_mac, .bat_iface_update_mac = batadv_iv_ogm_iface_update_mac,
.bat_primary_iface_set = batadv_iv_ogm_primary_iface_set, .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set,
.bat_ogm_schedule = batadv_iv_ogm_schedule,
.bat_ogm_emit = batadv_iv_ogm_emit,
.bat_neigh_cmp = batadv_iv_ogm_neigh_cmp, .bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
.bat_neigh_is_similar_or_better = batadv_iv_ogm_neigh_is_sob, .bat_neigh_is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
.bat_neigh_print = batadv_iv_neigh_print, .bat_neigh_print = batadv_iv_neigh_print,
......
...@@ -70,11 +70,6 @@ static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) ...@@ -70,11 +70,6 @@ static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
if (ret < 0) if (ret < 0)
batadv_v_elp_iface_disable(hard_iface); batadv_v_elp_iface_disable(hard_iface);
/* enable link throughput auto-detection by setting the throughput
* override to zero
*/
atomic_set(&hard_iface->bat_v.throughput_override, 0);
return ret; return ret;
} }
...@@ -119,14 +114,6 @@ batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) ...@@ -119,14 +114,6 @@ batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
batadv_v_elp_throughput_metric_update); batadv_v_elp_throughput_metric_update);
} }
static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface)
{
}
static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet)
{
}
/** /**
* batadv_v_orig_print_neigh - print neighbors for the originator table * batadv_v_orig_print_neigh - print neighbors for the originator table
* @orig_node: the orig_node for which the neighbors are printed * @orig_node: the orig_node for which the neighbors are printed
...@@ -340,14 +327,26 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { ...@@ -340,14 +327,26 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
.bat_iface_update_mac = batadv_v_iface_update_mac, .bat_iface_update_mac = batadv_v_iface_update_mac,
.bat_primary_iface_set = batadv_v_primary_iface_set, .bat_primary_iface_set = batadv_v_primary_iface_set,
.bat_hardif_neigh_init = batadv_v_hardif_neigh_init, .bat_hardif_neigh_init = batadv_v_hardif_neigh_init,
.bat_ogm_emit = batadv_v_ogm_emit,
.bat_ogm_schedule = batadv_v_ogm_schedule,
.bat_orig_print = batadv_v_orig_print, .bat_orig_print = batadv_v_orig_print,
.bat_neigh_cmp = batadv_v_neigh_cmp, .bat_neigh_cmp = batadv_v_neigh_cmp,
.bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob, .bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob,
.bat_neigh_print = batadv_v_neigh_print, .bat_neigh_print = batadv_v_neigh_print,
}; };
/**
* batadv_v_hardif_init - initialize the algorithm specific fields in the
* hard-interface object
* @hard_iface: the hard-interface to initialize
*/
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);
}
/** /**
* batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a * batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a
* mesh * mesh
......
...@@ -344,7 +344,6 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) ...@@ -344,7 +344,6 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
/* randomize initial seqno to avoid collision */ /* randomize initial seqno to avoid collision */
get_random_bytes(&random_seqno, sizeof(random_seqno)); get_random_bytes(&random_seqno, sizeof(random_seqno));
atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno); atomic_set(&hard_iface->bat_v.elp_seqno, random_seqno);
atomic_set(&hard_iface->bat_v.elp_interval, 500);
/* assume full-duplex by default */ /* assume full-duplex by default */
hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX; hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX;
...@@ -443,7 +442,8 @@ static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv, ...@@ -443,7 +442,8 @@ static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv,
if (!orig_neigh) if (!orig_neigh)
return; return;
neigh = batadv_neigh_node_new(orig_neigh, if_incoming, neigh_addr); neigh = batadv_neigh_node_get_or_create(orig_neigh,
if_incoming, neigh_addr);
if (!neigh) if (!neigh)
goto orig_free; goto orig_free;
......
...@@ -683,7 +683,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, ...@@ -683,7 +683,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (!orig_node) if (!orig_node)
return; return;
neigh_node = batadv_neigh_node_new(orig_node, if_incoming, neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
ethhdr->h_source); ethhdr->h_source);
if (!neigh_node) if (!neigh_node)
goto out; goto out;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "distributed-arp-table.h" #include "distributed-arp-table.h"
#include "gateway_client.h" #include "gateway_client.h"
#include "icmp_socket.h" #include "icmp_socket.h"
#include "multicast.h"
#include "network-coding.h" #include "network-coding.h"
#include "originator.h" #include "originator.h"
#include "translation-table.h" #include "translation-table.h"
...@@ -363,6 +364,22 @@ static int batadv_nc_nodes_open(struct inode *inode, struct file *file) ...@@ -363,6 +364,22 @@ static int batadv_nc_nodes_open(struct inode *inode, struct file *file)
} }
#endif #endif
#ifdef CONFIG_BATMAN_ADV_MCAST
/**
* batadv_mcast_flags_open - prepare file handler for reads from mcast_flags
* @inode: inode which was opened
* @file: file handle to be initialized
*
* Return: 0 on success or negative error number in case of failure
*/
static int batadv_mcast_flags_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, batadv_mcast_flags_seq_print_text, net_dev);
}
#endif
#define BATADV_DEBUGINFO(_name, _mode, _open) \ #define BATADV_DEBUGINFO(_name, _mode, _open) \
struct batadv_debuginfo batadv_debuginfo_##_name = { \ struct batadv_debuginfo batadv_debuginfo_##_name = { \
.attr = { \ .attr = { \
...@@ -407,6 +424,9 @@ static BATADV_DEBUGINFO(transtable_local, S_IRUGO, ...@@ -407,6 +424,9 @@ static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
#ifdef CONFIG_BATMAN_ADV_NC #ifdef CONFIG_BATMAN_ADV_NC
static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open); static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
#endif #endif
#ifdef CONFIG_BATMAN_ADV_MCAST
static BATADV_DEBUGINFO(mcast_flags, S_IRUGO, batadv_mcast_flags_open);
#endif
static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
&batadv_debuginfo_neighbors, &batadv_debuginfo_neighbors,
...@@ -423,6 +443,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { ...@@ -423,6 +443,9 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
&batadv_debuginfo_transtable_local, &batadv_debuginfo_transtable_local,
#ifdef CONFIG_BATMAN_ADV_NC #ifdef CONFIG_BATMAN_ADV_NC
&batadv_debuginfo_nc_nodes, &batadv_debuginfo_nc_nodes,
#endif
#ifdef CONFIG_BATMAN_ADV_MCAST
&batadv_debuginfo_mcast_flags,
#endif #endif
NULL, NULL,
}; };
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/pkt_sched.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -414,7 +413,7 @@ static struct sk_buff *batadv_frag_create(struct sk_buff *skb, ...@@ -414,7 +413,7 @@ static struct sk_buff *batadv_frag_create(struct sk_buff *skb,
if (!skb_fragment) if (!skb_fragment)
goto err; goto err;
skb->priority = TC_PRIO_CONTROL; skb_fragment->priority = skb->priority;
/* Eat the last mtu-bytes of the skb */ /* Eat the last mtu-bytes of the skb */
skb_reserve(skb_fragment, header_size + ETH_HLEN); skb_reserve(skb_fragment, header_size + ETH_HLEN);
...@@ -473,6 +472,15 @@ bool batadv_frag_send_packet(struct sk_buff *skb, ...@@ -473,6 +472,15 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
frag_header.reserved = 0; frag_header.reserved = 0;
frag_header.no = 0; frag_header.no = 0;
frag_header.total_size = htons(skb->len); frag_header.total_size = htons(skb->len);
/* skb->priority values from 256->263 are magic values to
* directly indicate a specific 802.1d priority. This is used
* to allow 802.1d priority to be passed directly in from VLAN
* tags, etc.
*/
if (skb->priority >= 256 && skb->priority <= 263)
frag_header.priority = skb->priority - 256;
ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
ether_addr_copy(frag_header.dest, orig_node->orig); ether_addr_copy(frag_header.dest, orig_node->orig);
......
...@@ -192,7 +192,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) ...@@ -192,7 +192,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
tq_avg = router_ifinfo->bat_iv.tq_avg; tq_avg = router_ifinfo->bat_iv.tq_avg;
switch (atomic_read(&bat_priv->gw_sel_class)) { switch (atomic_read(&bat_priv->gw.sel_class)) {
case 1: /* fast connection */ case 1: /* fast connection */
tmp_gw_factor = tq_avg * tq_avg; tmp_gw_factor = tq_avg * tq_avg;
tmp_gw_factor *= gw_node->bandwidth_down; tmp_gw_factor *= gw_node->bandwidth_down;
...@@ -255,7 +255,7 @@ void batadv_gw_check_client_stop(struct batadv_priv *bat_priv) ...@@ -255,7 +255,7 @@ void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
{ {
struct batadv_gw_node *curr_gw; struct batadv_gw_node *curr_gw;
if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
return; return;
curr_gw = batadv_gw_get_selected_gw_node(bat_priv); curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
...@@ -283,7 +283,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv) ...@@ -283,7 +283,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
struct batadv_neigh_ifinfo *router_ifinfo = NULL; struct batadv_neigh_ifinfo *router_ifinfo = NULL;
char gw_addr[18] = { '\0' }; char gw_addr[18] = { '\0' };
if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
goto out; goto out;
curr_gw = batadv_gw_get_selected_gw_node(bat_priv); curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
...@@ -402,8 +402,8 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv, ...@@ -402,8 +402,8 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
/* if the routing class is greater than 3 the value tells us how much /* if the routing class is greater than 3 the value tells us how much
* greater the TQ value of the new gateway must be * greater the TQ value of the new gateway must be
*/ */
if ((atomic_read(&bat_priv->gw_sel_class) > 3) && if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
(orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
goto out; goto out;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
...@@ -638,8 +638,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) ...@@ -638,8 +638,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
goto out; goto out;
seq_printf(seq, seq_printf(seq,
" %-12s (%s/%i) %17s [%10s]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", " Gateway (#/255) Nexthop [outgoingIF]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
"Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
BATADV_SOURCE_VERSION, primary_if->net_dev->name, BATADV_SOURCE_VERSION, primary_if->net_dev->name,
primary_if->net_dev->dev_addr, net_dev->name); primary_if->net_dev->dev_addr, net_dev->name);
...@@ -821,7 +820,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, ...@@ -821,7 +820,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
if (!gw_node) if (!gw_node)
goto out; goto out;
switch (atomic_read(&bat_priv->gw_mode)) { switch (atomic_read(&bat_priv->gw.mode)) {
case BATADV_GW_MODE_SERVER: case BATADV_GW_MODE_SERVER:
/* If we are a GW then we are our best GW. We can artificially /* If we are a GW then we are our best GW. We can artificially
* set the tq towards ourself as the maximum value * set the tq towards ourself as the maximum value
......
...@@ -144,7 +144,7 @@ void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv) ...@@ -144,7 +144,7 @@ void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
u32 down, up; u32 down, up;
char gw_mode; char gw_mode;
gw_mode = atomic_read(&bat_priv->gw_mode); gw_mode = atomic_read(&bat_priv->gw.mode);
switch (gw_mode) { switch (gw_mode) {
case BATADV_GW_MODE_OFF: case BATADV_GW_MODE_OFF:
...@@ -241,8 +241,8 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, ...@@ -241,8 +241,8 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
/* restart gateway selection if fast or late switching was enabled */ /* restart gateway selection if fast or late switching was enabled */
if ((gateway.bandwidth_down != 0) && if ((gateway.bandwidth_down != 0) &&
(atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) && (atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT) &&
(atomic_read(&bat_priv->gw_sel_class) > 2)) (atomic_read(&bat_priv->gw.sel_class) > 2))
batadv_gw_check_election(bat_priv, orig); batadv_gw_check_election(bat_priv, orig);
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include "bat_algo.h"
#include "bridge_loop_avoidance.h" #include "bridge_loop_avoidance.h"
#include "debugfs.h" #include "debugfs.h"
#include "distributed-arp-table.h" #include "distributed-arp-table.h"
...@@ -553,9 +554,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, ...@@ -553,9 +554,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
batadv_hardif_recalc_extra_skbroom(soft_iface); batadv_hardif_recalc_extra_skbroom(soft_iface);
/* begin scheduling originator messages on that interface */
batadv_schedule_bat_ogm(hard_iface);
out: out:
return 0; return 0;
...@@ -686,6 +684,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) ...@@ -686,6 +684,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
if (batadv_is_wifi_netdev(net_dev)) if (batadv_is_wifi_netdev(net_dev))
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
batadv_v_hardif_init(hard_iface);
/* extra reference for return */ /* extra reference for return */
kref_init(&hard_iface->refcount); kref_init(&hard_iface->refcount);
kref_get(&hard_iface->refcount); kref_get(&hard_iface->refcount);
......
...@@ -569,8 +569,6 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops) ...@@ -569,8 +569,6 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops)
!bat_algo_ops->bat_iface_disable || !bat_algo_ops->bat_iface_disable ||
!bat_algo_ops->bat_iface_update_mac || !bat_algo_ops->bat_iface_update_mac ||
!bat_algo_ops->bat_primary_iface_set || !bat_algo_ops->bat_primary_iface_set ||
!bat_algo_ops->bat_ogm_schedule ||
!bat_algo_ops->bat_ogm_emit ||
!bat_algo_ops->bat_neigh_cmp || !bat_algo_ops->bat_neigh_cmp ||
!bat_algo_ops->bat_neigh_is_similar_or_better) { !bat_algo_ops->bat_neigh_is_similar_or_better) {
pr_info("Routing algo '%s' does not implement required ops\n", pr_info("Routing algo '%s' does not implement required ops\n",
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2016.2" #define BATADV_SOURCE_VERSION "2016.3"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
...@@ -231,6 +231,7 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr); ...@@ -231,6 +231,7 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
* @BATADV_DBG_BLA: bridge loop avoidance messages * @BATADV_DBG_BLA: bridge loop avoidance messages
* @BATADV_DBG_DAT: ARP snooping and DAT related messages * @BATADV_DBG_DAT: ARP snooping and DAT related messages
* @BATADV_DBG_NC: network coding related messages * @BATADV_DBG_NC: network coding related messages
* @BATADV_DBG_MCAST: multicast related messages
* @BATADV_DBG_ALL: the union of all the above log levels * @BATADV_DBG_ALL: the union of all the above log levels
*/ */
enum batadv_dbg_level { enum batadv_dbg_level {
...@@ -240,7 +241,8 @@ enum batadv_dbg_level { ...@@ -240,7 +241,8 @@ enum batadv_dbg_level {
BATADV_DBG_BLA = BIT(3), BATADV_DBG_BLA = BIT(3),
BATADV_DBG_DAT = BIT(4), BATADV_DBG_DAT = BIT(4),
BATADV_DBG_NC = BIT(5), BATADV_DBG_NC = BIT(5),
BATADV_DBG_ALL = 63, BATADV_DBG_MCAST = BIT(6),
BATADV_DBG_ALL = 127,
}; };
#ifdef CONFIG_BATMAN_ADV_DEBUG #ifdef CONFIG_BATMAN_ADV_DEBUG
......
This diff is collapsed.
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "main.h" #include "main.h"
struct seq_file;
struct sk_buff; struct sk_buff;
/** /**
...@@ -46,6 +47,8 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -46,6 +47,8 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
void batadv_mcast_init(struct batadv_priv *bat_priv); void batadv_mcast_init(struct batadv_priv *bat_priv);
int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset);
void batadv_mcast_free(struct batadv_priv *bat_priv); void batadv_mcast_free(struct batadv_priv *bat_priv);
void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node); void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
......
...@@ -251,10 +251,8 @@ static void batadv_neigh_node_release(struct kref *ref) ...@@ -251,10 +251,8 @@ static void batadv_neigh_node_release(struct kref *ref)
struct hlist_node *node_tmp; struct hlist_node *node_tmp;
struct batadv_neigh_node *neigh_node; struct batadv_neigh_node *neigh_node;
struct batadv_neigh_ifinfo *neigh_ifinfo; struct batadv_neigh_ifinfo *neigh_ifinfo;
struct batadv_algo_ops *bao;
neigh_node = container_of(ref, struct batadv_neigh_node, refcount); neigh_node = container_of(ref, struct batadv_neigh_node, refcount);
bao = neigh_node->orig_node->bat_priv->bat_algo_ops;
hlist_for_each_entry_safe(neigh_ifinfo, node_tmp, hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
&neigh_node->ifinfo_list, list) { &neigh_node->ifinfo_list, list) {
...@@ -263,9 +261,6 @@ static void batadv_neigh_node_release(struct kref *ref) ...@@ -263,9 +261,6 @@ static void batadv_neigh_node_release(struct kref *ref)
batadv_hardif_neigh_put(neigh_node->hardif_neigh); batadv_hardif_neigh_put(neigh_node->hardif_neigh);
if (bao->bat_neigh_free)
bao->bat_neigh_free(neigh_node);
batadv_hardif_put(neigh_node->if_incoming); batadv_hardif_put(neigh_node->if_incoming);
kfree_rcu(neigh_node, rcu); kfree_rcu(neigh_node, rcu);
...@@ -602,17 +597,17 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface, ...@@ -602,17 +597,17 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
} }
/** /**
* batadv_neigh_node_new - create and init a new neigh_node object * batadv_neigh_node_create - create a neigh node object
* @orig_node: originator object representing the neighbour * @orig_node: originator object representing the neighbour
* @hard_iface: the interface where the neighbour is connected to * @hard_iface: the interface where the neighbour is connected to
* @neigh_addr: the mac address of the neighbour interface * @neigh_addr: the mac address of the neighbour interface
* *
* Allocates a new neigh_node object and initialises all the generic fields. * Allocates a new neigh_node object and initialises all the generic fields.
* *
* Return: neighbor when found. Othwerwise NULL * Return: the neighbour node if found or created or NULL otherwise.
*/ */
struct batadv_neigh_node * static struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_orig_node *orig_node, batadv_neigh_node_create(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *hard_iface, struct batadv_hard_iface *hard_iface,
const u8 *neigh_addr) const u8 *neigh_addr)
{ {
...@@ -666,6 +661,29 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node, ...@@ -666,6 +661,29 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
return neigh_node; return neigh_node;
} }
/**
* batadv_neigh_node_get_or_create - retrieve or create a neigh node object
* @orig_node: originator object representing the neighbour
* @hard_iface: the interface where the neighbour is connected to
* @neigh_addr: the mac address of the neighbour interface
*
* Return: the neighbour node if found or created or NULL otherwise.
*/
struct batadv_neigh_node *
batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *hard_iface,
const u8 *neigh_addr)
{
struct batadv_neigh_node *neigh_node = NULL;
/* first check without locking to avoid the overhead */
neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
if (neigh_node)
return neigh_node;
return batadv_neigh_node_create(orig_node, hard_iface, neigh_addr);
}
/** /**
* batadv_hardif_neigh_seq_print_text - print the single hop neighbour list * batadv_hardif_neigh_seq_print_text - print the single hop neighbour list
* @seq: neighbour table seq_file struct * @seq: neighbour table seq_file struct
......
...@@ -46,7 +46,7 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface, ...@@ -46,7 +46,7 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
void void
batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh); batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh);
struct batadv_neigh_node * struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_orig_node *orig_node, batadv_neigh_node_get_or_create(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *hard_iface, struct batadv_hard_iface *hard_iface,
const u8 *neigh_addr); const u8 *neigh_addr);
void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node); void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node);
......
...@@ -420,6 +420,7 @@ struct batadv_unicast_4addr_packet { ...@@ -420,6 +420,7 @@ struct batadv_unicast_4addr_packet {
* @dest: final destination used when routing fragments * @dest: final destination used when routing fragments
* @orig: originator of the fragment used when merging the packet * @orig: originator of the fragment used when merging the packet
* @no: fragment number within this sequence * @no: fragment number within this sequence
* @priority: priority of frame, from ToS IP precedence or 802.1p
* @reserved: reserved byte for alignment * @reserved: reserved byte for alignment
* @seqno: sequence identification * @seqno: sequence identification
* @total_size: size of the merged packet * @total_size: size of the merged packet
...@@ -430,9 +431,11 @@ struct batadv_frag_packet { ...@@ -430,9 +431,11 @@ struct batadv_frag_packet {
u8 ttl; u8 ttl;
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
u8 no:4; u8 no:4;
u8 reserved:4; u8 priority:3;
u8 reserved:1;
#elif defined(__LITTLE_ENDIAN_BITFIELD) #elif defined(__LITTLE_ENDIAN_BITFIELD)
u8 reserved:4; u8 reserved:1;
u8 priority:3;
u8 no:4; u8 no:4;
#else #else
#error "unknown bitfield endianness" #error "unknown bitfield endianness"
......
...@@ -1007,6 +1007,8 @@ int batadv_recv_frag_packet(struct sk_buff *skb, ...@@ -1007,6 +1007,8 @@ int batadv_recv_frag_packet(struct sk_buff *skb,
if (!orig_node_src) if (!orig_node_src)
goto out; goto out;
skb->priority = frag_packet->priority + 256;
/* Route the fragment if it is not for us and too big to be merged. */ /* Route the fragment if it is not for us and too big to be merged. */
if (!batadv_is_my_mac(bat_priv, frag_packet->dest) && if (!batadv_is_my_mac(bat_priv, frag_packet->dest) &&
batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) { batadv_frag_skb_fwd(skb, recv_if, orig_node_src)) {
......
...@@ -428,27 +428,7 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -428,27 +428,7 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
orig_node, vid); orig_node, vid);
} }
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface) void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
(hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
return;
/* the interface gets activated here to avoid race conditions between
* the moment of activating the interface in
* hardif_activate_interface() where the originator mac is set and
* outdated packets (especially uninitialized mac addresses) in the
* packet queue
*/
if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
hard_iface->if_status = BATADV_IF_ACTIVE;
bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface);
}
static void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet)
{ {
kfree_skb(forw_packet->skb); kfree_skb(forw_packet->skb);
if (forw_packet->if_incoming) if (forw_packet->if_incoming)
...@@ -604,45 +584,6 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) ...@@ -604,45 +584,6 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
atomic_inc(&bat_priv->bcast_queue_left); atomic_inc(&bat_priv->bcast_queue_left);
} }
void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
{
struct delayed_work *delayed_work;
struct batadv_forw_packet *forw_packet;
struct batadv_priv *bat_priv;
delayed_work = to_delayed_work(work);
forw_packet = container_of(delayed_work, struct batadv_forw_packet,
delayed_work);
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
goto out;
bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet);
/* we have to have at least one packet in the queue to determine the
* queues wake up time unless we are shutting down.
*
* only re-schedule if this is the "original" copy, e.g. the OGM of the
* primary interface should only be rescheduled once per period, but
* this function will be called for the forw_packet instances of the
* other secondary interfaces as well.
*/
if (forw_packet->own &&
forw_packet->if_incoming == forw_packet->if_outgoing)
batadv_schedule_bat_ogm(forw_packet->if_incoming);
out:
/* don't count own packet */
if (!forw_packet->own)
atomic_inc(&bat_priv->batman_queue_left);
batadv_forw_packet_free(forw_packet);
}
void void
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
const struct batadv_hard_iface *hard_iface) const struct batadv_hard_iface *hard_iface)
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
#include "packet.h" #include "packet.h"
struct sk_buff; struct sk_buff;
struct work_struct;
void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet);
int batadv_send_skb_to_orig(struct sk_buff *skb, int batadv_send_skb_to_orig(struct sk_buff *skb,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if); struct batadv_hard_iface *recv_if);
...@@ -38,11 +38,9 @@ int batadv_send_broadcast_skb(struct sk_buff *skb, ...@@ -38,11 +38,9 @@ int batadv_send_broadcast_skb(struct sk_buff *skb,
struct batadv_hard_iface *hard_iface); struct batadv_hard_iface *hard_iface);
int batadv_send_unicast_skb(struct sk_buff *skb, int batadv_send_unicast_skb(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node); struct batadv_neigh_node *neigh_node);
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
const struct sk_buff *skb, const struct sk_buff *skb,
unsigned long delay); unsigned long delay);
void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work);
void void
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv, batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
const struct batadv_hard_iface *hard_iface); const struct batadv_hard_iface *hard_iface);
......
...@@ -255,7 +255,7 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -255,7 +255,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
goto dropped; goto dropped;
gw_mode = atomic_read(&bat_priv->gw_mode); gw_mode = atomic_read(&bat_priv->gw.mode);
if (is_multicast_ether_addr(ethhdr->h_dest)) { if (is_multicast_ether_addr(ethhdr->h_dest)) {
/* if gw mode is off, broadcast every packet */ /* if gw mode is off, broadcast every packet */
if (gw_mode == BATADV_GW_MODE_OFF) { if (gw_mode == BATADV_GW_MODE_OFF) {
...@@ -808,6 +808,10 @@ static int batadv_softif_init_late(struct net_device *dev) ...@@ -808,6 +808,10 @@ static int batadv_softif_init_late(struct net_device *dev)
atomic_set(&bat_priv->distributed_arp_table, 1); atomic_set(&bat_priv->distributed_arp_table, 1);
#endif #endif
#ifdef CONFIG_BATMAN_ADV_MCAST #ifdef CONFIG_BATMAN_ADV_MCAST
bat_priv->mcast.querier_ipv4.exists = false;
bat_priv->mcast.querier_ipv4.shadowing = false;
bat_priv->mcast.querier_ipv6.exists = false;
bat_priv->mcast.querier_ipv6.shadowing = false;
bat_priv->mcast.flags = BATADV_NO_FLAGS; bat_priv->mcast.flags = BATADV_NO_FLAGS;
atomic_set(&bat_priv->multicast_mode, 1); atomic_set(&bat_priv->multicast_mode, 1);
atomic_set(&bat_priv->mcast.num_disabled, 0); atomic_set(&bat_priv->mcast.num_disabled, 0);
...@@ -815,8 +819,8 @@ static int batadv_softif_init_late(struct net_device *dev) ...@@ -815,8 +819,8 @@ static int batadv_softif_init_late(struct net_device *dev)
atomic_set(&bat_priv->mcast.num_want_all_ipv4, 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_want_all_ipv6, 0);
#endif #endif
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
atomic_set(&bat_priv->gw_sel_class, 20); atomic_set(&bat_priv->gw.sel_class, 20);
atomic_set(&bat_priv->gw.bandwidth_down, 100); atomic_set(&bat_priv->gw.bandwidth_down, 100);
atomic_set(&bat_priv->gw.bandwidth_up, 20); atomic_set(&bat_priv->gw.bandwidth_up, 20);
atomic_set(&bat_priv->orig_interval, 1000); atomic_set(&bat_priv->orig_interval, 1000);
......
...@@ -389,12 +389,12 @@ static int batadv_store_uint_attr(const char *buff, size_t count, ...@@ -389,12 +389,12 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
return count; return count;
} }
static inline ssize_t static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
__batadv_store_uint_attr(const char *buff, size_t count,
int min, int max, int min, int max,
void (*post_func)(struct net_device *), void (*post_func)(struct net_device *),
const struct attribute *attr, const struct attribute *attr,
atomic_t *attr_store, struct net_device *net_dev) atomic_t *attr_store,
struct net_device *net_dev)
{ {
int ret; int ret;
...@@ -427,7 +427,7 @@ static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr, ...@@ -427,7 +427,7 @@ static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr,
struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
int bytes_written; int bytes_written;
switch (atomic_read(&bat_priv->gw_mode)) { switch (atomic_read(&bat_priv->gw.mode)) {
case BATADV_GW_MODE_CLIENT: case BATADV_GW_MODE_CLIENT:
bytes_written = sprintf(buff, "%s\n", bytes_written = sprintf(buff, "%s\n",
BATADV_GW_MODE_CLIENT_NAME); BATADV_GW_MODE_CLIENT_NAME);
...@@ -476,10 +476,10 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, ...@@ -476,10 +476,10 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
return -EINVAL; return -EINVAL;
} }
if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) if (atomic_read(&bat_priv->gw.mode) == gw_mode_tmp)
return count; return count;
switch (atomic_read(&bat_priv->gw_mode)) { switch (atomic_read(&bat_priv->gw.mode)) {
case BATADV_GW_MODE_CLIENT: case BATADV_GW_MODE_CLIENT:
curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME; curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME;
break; break;
...@@ -508,7 +508,7 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj, ...@@ -508,7 +508,7 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
* state * state
*/ */
batadv_gw_check_client_stop(bat_priv); batadv_gw_check_client_stop(bat_priv);
atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); atomic_set(&bat_priv->gw.mode, (unsigned int)gw_mode_tmp);
batadv_gw_tvlv_container_update(bat_priv); batadv_gw_tvlv_container_update(bat_priv);
return count; return count;
} }
...@@ -624,7 +624,7 @@ BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, S_IRUGO | S_IWUSR, ...@@ -624,7 +624,7 @@ BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, S_IRUGO | S_IWUSR,
2 * BATADV_JITTER, INT_MAX, NULL); 2 * BATADV_JITTER, INT_MAX, NULL);
BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, S_IRUGO | S_IWUSR, 0, BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, S_IRUGO | S_IWUSR, 0,
BATADV_TQ_MAX_VALUE, NULL); BATADV_TQ_MAX_VALUE, NULL);
BATADV_ATTR_SIF_UINT(gw_sel_class, gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_ATTR_SIF_UINT(gw_sel_class, gw.sel_class, S_IRUGO | S_IWUSR, 1,
BATADV_TQ_MAX_VALUE, batadv_post_gw_reselect); BATADV_TQ_MAX_VALUE, batadv_post_gw_reselect);
static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
batadv_store_gw_bwidth); batadv_store_gw_bwidth);
......
...@@ -996,7 +996,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) ...@@ -996,7 +996,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
struct batadv_tt_local_entry *tt_local; struct batadv_tt_local_entry *tt_local;
struct batadv_hard_iface *primary_if; struct batadv_hard_iface *primary_if;
struct hlist_head *head; struct hlist_head *head;
unsigned short vid;
u32 i; u32 i;
int last_seen_secs; int last_seen_secs;
int last_seen_msecs; int last_seen_msecs;
...@@ -1023,7 +1022,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) ...@@ -1023,7 +1022,6 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
tt_local = container_of(tt_common_entry, tt_local = container_of(tt_common_entry,
struct batadv_tt_local_entry, struct batadv_tt_local_entry,
common); common);
vid = tt_common_entry->vid;
last_seen_jiffies = jiffies - tt_local->last_seen; last_seen_jiffies = jiffies - tt_local->last_seen;
last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
last_seen_secs = last_seen_msecs / 1000; last_seen_secs = last_seen_msecs / 1000;
......
...@@ -707,6 +707,8 @@ struct batadv_priv_debug_log { ...@@ -707,6 +707,8 @@ struct batadv_priv_debug_log {
* @list: list of available gateway nodes * @list: list of available gateway nodes
* @list_lock: lock protecting gw_list & curr_gw * @list_lock: lock protecting gw_list & curr_gw
* @curr_gw: pointer to currently selected gateway node * @curr_gw: pointer to currently selected gateway node
* @mode: gateway operation: off, client or server (see batadv_gw_modes)
* @sel_class: gateway selection class (applies if gw_mode client)
* @bandwidth_down: advertised uplink download bandwidth (if gw_mode server) * @bandwidth_down: advertised uplink download bandwidth (if gw_mode server)
* @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server) * @bandwidth_up: advertised uplink upload bandwidth (if gw_mode server)
* @reselect: bool indicating a gateway re-selection is in progress * @reselect: bool indicating a gateway re-selection is in progress
...@@ -715,6 +717,8 @@ struct batadv_priv_gw { ...@@ -715,6 +717,8 @@ struct batadv_priv_gw {
struct hlist_head list; struct hlist_head list;
spinlock_t list_lock; /* protects gw_list & curr_gw */ spinlock_t list_lock; /* protects gw_list & curr_gw */
struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
atomic_t mode;
atomic_t sel_class;
atomic_t bandwidth_down; atomic_t bandwidth_down;
atomic_t bandwidth_up; atomic_t bandwidth_up;
atomic_t reselect; atomic_t reselect;
...@@ -750,6 +754,17 @@ struct batadv_priv_dat { ...@@ -750,6 +754,17 @@ struct batadv_priv_dat {
#endif #endif
#ifdef CONFIG_BATMAN_ADV_MCAST #ifdef CONFIG_BATMAN_ADV_MCAST
/**
* struct batadv_mcast_querier_state - IGMP/MLD querier state when bridged
* @exists: whether a querier exists in the mesh
* @shadowing: if a querier exists, whether it is potentially shadowing
* multicast listeners (i.e. querier is behind our own bridge segment)
*/
struct batadv_mcast_querier_state {
bool exists;
bool shadowing;
};
/** /**
* struct batadv_priv_mcast - per mesh interface mcast data * struct batadv_priv_mcast - per mesh interface mcast data
* @mla_list: list of multicast addresses we are currently announcing via TT * @mla_list: list of multicast addresses we are currently announcing via TT
...@@ -757,8 +772,11 @@ struct batadv_priv_dat { ...@@ -757,8 +772,11 @@ struct batadv_priv_dat {
* multicast traffic * multicast traffic
* @want_all_ipv4_list: a list of orig_nodes wanting all IPv4 multicast traffic * @want_all_ipv4_list: a list of orig_nodes wanting all IPv4 multicast traffic
* @want_all_ipv6_list: a list of orig_nodes wanting all IPv6 multicast traffic * @want_all_ipv6_list: a list of orig_nodes wanting all IPv6 multicast traffic
* @querier_ipv4: the current state of an IGMP querier in the mesh
* @querier_ipv6: the current state of an MLD querier in the mesh
* @flags: the flags we have last sent in our mcast tvlv * @flags: the flags we have last sent in our mcast tvlv
* @enabled: whether the multicast tvlv is currently enabled * @enabled: whether the multicast tvlv is currently enabled
* @bridged: whether the soft interface has a bridge on top
* @num_disabled: number of nodes that have no mcast tvlv * @num_disabled: number of nodes that have no mcast tvlv
* @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic * @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP traffic
* @num_want_all_ipv4: counter for items in want_all_ipv4_list * @num_want_all_ipv4: counter for items in want_all_ipv4_list
...@@ -771,8 +789,11 @@ struct batadv_priv_mcast { ...@@ -771,8 +789,11 @@ struct batadv_priv_mcast {
struct hlist_head want_all_unsnoopables_list; struct hlist_head want_all_unsnoopables_list;
struct hlist_head want_all_ipv4_list; struct hlist_head want_all_ipv4_list;
struct hlist_head want_all_ipv6_list; struct hlist_head want_all_ipv6_list;
struct batadv_mcast_querier_state querier_ipv4;
struct batadv_mcast_querier_state querier_ipv6;
u8 flags; u8 flags;
bool enabled; bool enabled;
bool bridged;
atomic_t num_disabled; atomic_t num_disabled;
atomic_t num_want_all_unsnoopables; atomic_t num_want_all_unsnoopables;
atomic_t num_want_all_ipv4; atomic_t num_want_all_ipv4;
...@@ -865,8 +886,6 @@ struct batadv_priv_bat_v { ...@@ -865,8 +886,6 @@ struct batadv_priv_bat_v {
* enabled * enabled
* @multicast_mode: Enable or disable multicast optimizations on this node's * @multicast_mode: Enable or disable multicast optimizations on this node's
* sender/originating side * sender/originating side
* @gw_mode: gateway operation: off, client or server (see batadv_gw_modes)
* @gw_sel_class: gateway selection class (applies if gw_mode client)
* @orig_interval: OGM broadcast interval in milliseconds * @orig_interval: OGM broadcast interval in milliseconds
* @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop * @hop_penalty: penalty which will be applied to an OGM's tq-field on every hop
* @log_level: configured log level (see batadv_dbg_level) * @log_level: configured log level (see batadv_dbg_level)
...@@ -922,8 +941,6 @@ struct batadv_priv { ...@@ -922,8 +941,6 @@ struct batadv_priv {
#ifdef CONFIG_BATMAN_ADV_MCAST #ifdef CONFIG_BATMAN_ADV_MCAST
atomic_t multicast_mode; atomic_t multicast_mode;
#endif #endif
atomic_t gw_mode;
atomic_t gw_sel_class;
atomic_t orig_interval; atomic_t orig_interval;
atomic_t hop_penalty; atomic_t hop_penalty;
#ifdef CONFIG_BATMAN_ADV_DEBUG #ifdef CONFIG_BATMAN_ADV_DEBUG
...@@ -1271,8 +1288,6 @@ struct batadv_forw_packet { ...@@ -1271,8 +1288,6 @@ struct batadv_forw_packet {
* @bat_iface_update_mac: (re-)init mac addresses of the protocol information * @bat_iface_update_mac: (re-)init mac addresses of the protocol information
* belonging to this hard-interface * belonging to this hard-interface
* @bat_primary_iface_set: called when primary interface is selected / changed * @bat_primary_iface_set: called when primary interface is selected / changed
* @bat_ogm_schedule: prepare a new outgoing OGM for the send queue
* @bat_ogm_emit: send scheduled OGM
* @bat_hardif_neigh_init: called on creation of single hop entry * @bat_hardif_neigh_init: called on creation of single hop entry
* @bat_neigh_cmp: compare the metrics of two neighbors for their respective * @bat_neigh_cmp: compare the metrics of two neighbors for their respective
* outgoing interfaces * outgoing interfaces
...@@ -1280,8 +1295,6 @@ struct batadv_forw_packet { ...@@ -1280,8 +1295,6 @@ struct batadv_forw_packet {
* better than neigh2 for their respective outgoing interface from the metric * better than neigh2 for their respective outgoing interface from the metric
* prospective * prospective
* @bat_neigh_print: print the single hop neighbor list (optional) * @bat_neigh_print: print the single hop neighbor list (optional)
* @bat_neigh_free: free the resources allocated by the routing algorithm for a
* neigh_node object
* @bat_orig_print: print the originator table (optional) * @bat_orig_print: print the originator table (optional)
* @bat_orig_free: free the resources allocated by the routing algorithm for an * @bat_orig_free: free the resources allocated by the routing algorithm for an
* orig_node object * orig_node object
...@@ -1298,8 +1311,6 @@ struct batadv_algo_ops { ...@@ -1298,8 +1311,6 @@ struct batadv_algo_ops {
void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface); void (*bat_iface_disable)(struct batadv_hard_iface *hard_iface);
void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface); void (*bat_iface_update_mac)(struct batadv_hard_iface *hard_iface);
void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface); void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface);
void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface);
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
/* neigh_node handling API */ /* neigh_node handling API */
void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh); void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh);
int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1, int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
...@@ -1312,7 +1323,6 @@ struct batadv_algo_ops { ...@@ -1312,7 +1323,6 @@ struct batadv_algo_ops {
struct batadv_neigh_node *neigh2, struct batadv_neigh_node *neigh2,
struct batadv_hard_iface *if_outgoing2); struct batadv_hard_iface *if_outgoing2);
void (*bat_neigh_print)(struct batadv_priv *priv, struct seq_file *seq); void (*bat_neigh_print)(struct batadv_priv *priv, struct seq_file *seq);
void (*bat_neigh_free)(struct batadv_neigh_node *neigh);
/* orig_node handling API */ /* orig_node handling API */
void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq, void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq,
struct batadv_hard_iface *hard_iface); struct batadv_hard_iface *hard_iface);
......
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