Skip to content

Commit

Permalink
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Browse files Browse the repository at this point in the history
Antonio Quartulli says:

====================
Included changes:
- remove useless skb size check in batadv_interface_rx
- basic netns support introduced by Andrew Lunn:
    - prevent virtual interface from changing netns by setting
      NETIF_F_NETNS_LOCAL
    - create virtual interface within the netns of the first
      hard-interface
- introduce detection of complex bridge loops and report event
  to the user (via udev) when the Bridge Loop Avoidance mechanism
  can't prevent them
- minor reference counting bugfixes for the hard_iface object that
  couldn't make it via the net tree
- use kref_get() instead of kref_get_unless_zero() to make reference
  counting bug more visible
- use batadv_compare_eth() all over the code when possible instead of
  plain memcmp()
- minor code cleanup and style adjustments
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 11, 2016
2 parents 953abb3 + 676970e commit cf88585
Show file tree
Hide file tree
Showing 26 changed files with 465 additions and 295 deletions.
48 changes: 26 additions & 22 deletions net/batman-adv/bat_iv_ogm.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,18 +681,12 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
unsigned char *skb_buff;
unsigned int skb_size;

if (!kref_get_unless_zero(&if_incoming->refcount))
return;

if (!kref_get_unless_zero(&if_outgoing->refcount))
goto out_free_incoming;

/* own packet should always be scheduled */
if (!own_packet) {
if (!batadv_atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"batman packet queue full\n");
goto out_free_outgoing;
return;
}
}

Expand All @@ -718,6 +712,8 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
forw_packet_aggr->packet_len = packet_len;
memcpy(skb_buff, packet_buff, packet_len);

kref_get(&if_incoming->refcount);
kref_get(&if_outgoing->refcount);
forw_packet_aggr->own = own_packet;
forw_packet_aggr->if_incoming = if_incoming;
forw_packet_aggr->if_outgoing = if_outgoing;
Expand Down Expand Up @@ -747,10 +743,6 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
out_nomem:
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
out_free_outgoing:
batadv_hardif_put(if_outgoing);
out_free_incoming:
batadv_hardif_put(if_incoming);
}

/* aggregate a new packet into the existing ogm packet */
Expand Down Expand Up @@ -987,9 +979,15 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
if (tmp_hard_iface->soft_iface != hard_iface->soft_iface)
continue;

if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
continue;

batadv_iv_ogm_queue_add(bat_priv, *ogm_buff,
*ogm_buff_len, hard_iface,
tmp_hard_iface, 1, send_time);

batadv_hardif_put(tmp_hard_iface);
}
rcu_read_unlock();

Expand Down Expand Up @@ -1170,23 +1168,24 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
* @if_incoming: interface where the packet was received
* @if_outgoing: interface for which the retransmission should be considered
*
* Return: 1 if the link can be considered bidirectional, 0 otherwise
* Return: true if the link can be considered bidirectional, false otherwise
*/
static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
struct batadv_orig_node *orig_neigh_node,
struct batadv_ogm_packet *batadv_ogm_packet,
struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
struct batadv_orig_node *orig_neigh_node,
struct batadv_ogm_packet *batadv_ogm_packet,
struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
{
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
struct batadv_neigh_ifinfo *neigh_ifinfo;
u8 total_count;
u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0;
int tq_asym_penalty, inv_asym_penalty, if_num;
unsigned int combined_tq;
int tq_iface_penalty;
bool ret = false;

/* find corresponding one hop neighbor */
rcu_read_lock();
Expand Down Expand Up @@ -1298,7 +1297,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
* consider it bidirectional
*/
if (batadv_ogm_packet->tq >= BATADV_TQ_TOTAL_BIDRECT_LIMIT)
ret = 1;
ret = true;

out:
if (neigh_node)
Expand Down Expand Up @@ -1327,9 +1326,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
struct batadv_orig_ifinfo *orig_ifinfo = NULL;
struct batadv_neigh_node *neigh_node;
struct batadv_neigh_ifinfo *neigh_ifinfo;
int is_dup;
bool is_dup;
s32 seq_diff;
int need_update = 0;
bool need_update = false;
int set_mark;
enum batadv_dup_status ret = BATADV_NO_DUP;
u32 seqno = ntohl(batadv_ogm_packet->seqno);
Expand Down Expand Up @@ -1439,7 +1438,7 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
struct sk_buff *skb_priv;
struct ethhdr *ethhdr;
u8 *prev_sender;
int is_bidirect;
bool is_bidirect;

/* create a private copy of the skb, as some functions change tq value
* and/or flags.
Expand Down Expand Up @@ -1767,8 +1766,13 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (hard_iface->soft_iface != bat_priv->soft_iface)
continue;

if (!kref_get_unless_zero(&hard_iface->refcount))
continue;

batadv_iv_ogm_process_per_outif(skb, ogm_offset, orig_node,
if_incoming, hard_iface);

batadv_hardif_put(hard_iface);
}
rcu_read_unlock();

Expand Down
14 changes: 13 additions & 1 deletion net/batman-adv/bat_v_ogm.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/if_ether.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/random.h>
Expand Down Expand Up @@ -176,6 +177,9 @@ static void batadv_v_ogm_send(struct work_struct *work)
if (hard_iface->soft_iface != bat_priv->soft_iface)
continue;

if (!kref_get_unless_zero(&hard_iface->refcount))
continue;

batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n",
ogm_packet->orig, ntohl(ogm_packet->seqno),
Expand All @@ -185,10 +189,13 @@ static void batadv_v_ogm_send(struct work_struct *work)

/* this skb gets consumed by batadv_v_ogm_send_to_if() */
skb_tmp = skb_clone(skb, GFP_ATOMIC);
if (!skb_tmp)
if (!skb_tmp) {
batadv_hardif_put(hard_iface);
break;
}

batadv_v_ogm_send_to_if(skb_tmp, hard_iface);
batadv_hardif_put(hard_iface);
}
rcu_read_unlock();

Expand Down Expand Up @@ -704,9 +711,14 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (hard_iface->soft_iface != bat_priv->soft_iface)
continue;

if (!kref_get_unless_zero(&hard_iface->refcount))
continue;

batadv_v_ogm_process_per_outif(bat_priv, ethhdr, ogm_packet,
orig_node, neigh_node,
if_incoming, hard_iface);

batadv_hardif_put(hard_iface);
}
rcu_read_unlock();
out:
Expand Down
16 changes: 8 additions & 8 deletions net/batman-adv/bitarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ static void batadv_bitmap_shift_left(unsigned long *seq_bits, s32 n)
* the last sequence number
* @set_mark: whether this packet should be marked in seq_bits
*
* Return: 1 if the window was moved (either new or very old),
* 0 if the window was not moved/shifted.
* Return: true if the window was moved (either new or very old),
* false if the window was not moved/shifted.
*/
int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff,
int set_mark)
bool batadv_bit_get_packet(void *priv, unsigned long *seq_bits,
s32 seq_num_diff, int set_mark)
{
struct batadv_priv *bat_priv = priv;

Expand All @@ -52,7 +52,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff,
if (seq_num_diff <= 0 && seq_num_diff > -BATADV_TQ_LOCAL_WINDOW_SIZE) {
if (set_mark)
batadv_set_bit(seq_bits, -seq_num_diff);
return 0;
return false;
}

/* sequence number is slightly newer, so we shift the window and
Expand All @@ -63,7 +63,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff,

if (set_mark)
batadv_set_bit(seq_bits, 0);
return 1;
return true;
}

/* sequence number is much newer, probably missed a lot of packets */
Expand All @@ -75,7 +75,7 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff,
bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
if (set_mark)
batadv_set_bit(seq_bits, 0);
return 1;
return true;
}

/* received a much older packet. The other host either restarted
Expand All @@ -94,5 +94,5 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff,
if (set_mark)
batadv_set_bit(seq_bits, 0);

return 1;
return true;
}
15 changes: 8 additions & 7 deletions net/batman-adv/bitarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/stddef.h>
#include <linux/types.h>

/**
Expand All @@ -31,17 +32,17 @@
* @last_seqno: latest sequence number in seq_bits
* @curr_seqno: sequence number to test for
*
* Return: 1 if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno. Otherwise returns 0.
* Return: true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno. Otherwise returns false.
*/
static inline int batadv_test_bit(const unsigned long *seq_bits,
u32 last_seqno, u32 curr_seqno)
static inline bool batadv_test_bit(const unsigned long *seq_bits,
u32 last_seqno, u32 curr_seqno)
{
s32 diff;

diff = last_seqno - curr_seqno;
if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE)
return 0;
return false;
return test_bit(diff, seq_bits) != 0;
}

Expand All @@ -55,7 +56,7 @@ static inline void batadv_set_bit(unsigned long *seq_bits, s32 n)
set_bit(n, seq_bits); /* turn the position on */
}

int batadv_bit_get_packet(void *priv, unsigned long *seq_bits, s32 seq_num_diff,
int set_mark);
bool batadv_bit_get_packet(void *priv, unsigned long *seq_bits,
s32 seq_num_diff, int set_mark);

#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
Loading

0 comments on commit cf88585

Please sign in to comment.