Skip to content

Commit

Permalink
batman-adv: remove ogm_emit and ogm_schedule API calls
Browse files Browse the repository at this point in the history
The ogm_emit and ogm_schedule API calls were rather tight to the
B.A.T.M.A.N. IV logic and therefore rather difficult to use
with other algorithm implementations.

Remove such calls and move the surrounding logic into the
B.A.T.M.A.N. IV specific code.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
  • Loading branch information
Antonio Quartulli authored and Simon Wunderlich committed Jun 30, 2016
1 parent d9f1798 commit f0d9725
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 86 deletions.
69 changes: 65 additions & 4 deletions net/batman-adv/bat_iv_ogm.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/kref.h>
#include <linux/lockdep.h>
Expand Down Expand Up @@ -58,6 +59,8 @@
#include "send.h"
#include "translation-table.h"

static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work);

/**
* enum batadv_dup_status - duplicate status
* @BATADV_NO_DUP: the packet is no duplicate
Expand Down Expand Up @@ -731,7 +734,7 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,

/* start timer for this packet */
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,
&forw_packet_aggr->delayed_work,
send_time - jiffies);
Expand Down Expand Up @@ -938,6 +941,19 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
u16 tvlv_len = 0;
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);

if (hard_iface == primary_if) {
Expand Down Expand Up @@ -1779,6 +1795,45 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
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,
struct batadv_hard_iface *if_incoming)
{
Expand All @@ -1795,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
* 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;

batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
Expand Down Expand Up @@ -2053,14 +2109,19 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
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 = {
.name = "BATMAN_IV",
.bat_iface_activate = batadv_iv_iface_activate,
.bat_iface_enable = batadv_iv_ogm_iface_enable,
.bat_iface_disable = batadv_iv_ogm_iface_disable,
.bat_iface_update_mac = batadv_iv_ogm_iface_update_mac,
.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_is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
.bat_neigh_print = batadv_iv_neigh_print,
Expand Down
10 changes: 0 additions & 10 deletions net/batman-adv/bat_v.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,6 @@ batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
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
* @orig_node: the orig_node for which the neighbors are printed
Expand Down Expand Up @@ -340,8 +332,6 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = {
.bat_iface_update_mac = batadv_v_iface_update_mac,
.bat_primary_iface_set = batadv_v_primary_iface_set,
.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_neigh_cmp = batadv_v_neigh_cmp,
.bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob,
Expand Down
3 changes: 0 additions & 3 deletions net/batman-adv/hard-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,

batadv_hardif_recalc_extra_skbroom(soft_iface);

/* begin scheduling originator messages on that interface */
batadv_schedule_bat_ogm(hard_iface);

out:
return 0;

Expand Down
2 changes: 0 additions & 2 deletions net/batman-adv/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_update_mac ||
!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_is_similar_or_better) {
pr_info("Routing algo '%s' does not implement required ops\n",
Expand Down
61 changes: 1 addition & 60 deletions net/batman-adv/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,27 +428,7 @@ int batadv_send_skb_via_gw(struct batadv_priv *bat_priv, struct sk_buff *skb,
orig_node, vid);
}

void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
{
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)
void batadv_forw_packet_free(struct batadv_forw_packet *forw_packet)
{
kfree_skb(forw_packet->skb);
if (forw_packet->if_incoming)
Expand Down Expand Up @@ -604,45 +584,6 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
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
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
const struct batadv_hard_iface *hard_iface)
Expand Down
4 changes: 1 addition & 3 deletions net/batman-adv/send.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
#include "packet.h"

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,
struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if);
Expand All @@ -38,11 +38,9 @@ int batadv_send_broadcast_skb(struct sk_buff *skb,
struct batadv_hard_iface *hard_iface);
int batadv_send_unicast_skb(struct sk_buff *skb,
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,
const struct sk_buff *skb,
unsigned long delay);
void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work);
void
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
const struct batadv_hard_iface *hard_iface);
Expand Down
4 changes: 0 additions & 4 deletions net/batman-adv/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1269,8 +1269,6 @@ struct batadv_forw_packet {
* @bat_iface_update_mac: (re-)init mac addresses of the protocol information
* belonging to this hard-interface
* @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_neigh_cmp: compare the metrics of two neighbors for their respective
* outgoing interfaces
Expand All @@ -1294,8 +1292,6 @@ struct batadv_algo_ops {
void (*bat_iface_disable)(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_ogm_schedule)(struct batadv_hard_iface *hard_iface);
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
/* neigh_node handling API */
void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh);
int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
Expand Down

0 comments on commit f0d9725

Please sign in to comment.