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
Included changes:

* major skb->data pointer usage fix
* interval version update
* added get_ethtool_stats() support
* endianess clean up
* routing protocol API improvement wrt TT commit code
* fix locking in hash table code
* minor cleanups and fixes
  • Loading branch information
David S. Miller committed Jun 19, 2012
2 parents 6fac262 + dafe94b commit f032537
Show file tree
Hide file tree
Showing 21 changed files with 420 additions and 225 deletions.
5 changes: 5 additions & 0 deletions Documentation/networking/batman-adv.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ The debug output can be changed at runtime using the file

will enable debug messages for when routes change.

Counters for different types of packets entering and leaving the
batman-adv module are available through ethtool:

# ethtool --statistics bat0


BATCTL
------
Expand Down
11 changes: 7 additions & 4 deletions net/batman-adv/bat_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@ static int debug_log_setup(struct bat_priv *bat_priv)

d = debugfs_create_file("log", S_IFREG | S_IRUSR,
bat_priv->debug_dir, bat_priv, &log_fops);
if (d)
if (!d)
goto err;

return 0;

err:
return 1;
return -ENOMEM;
}

static void debug_log_cleanup(struct bat_priv *bat_priv)
Expand Down Expand Up @@ -348,8 +348,11 @@ int debugfs_add_meshif(struct net_device *dev)
if (!bat_priv->debug_dir)
goto out;

bat_socket_setup(bat_priv);
debug_log_setup(bat_priv);
if (bat_socket_setup(bat_priv) < 0)
goto rem_attr;

if (debug_log_setup(bat_priv) < 0)
goto rem_attr;

for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
file = debugfs_create_file(((*bat_debug)->attr).name,
Expand Down
63 changes: 34 additions & 29 deletions net/batman-adv/bat_iv_ogm.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface,
const uint8_t *neigh_addr,
struct orig_node *orig_node,
struct orig_node *orig_neigh,
uint32_t seqno)
__be32 seqno)
{
struct neigh_node *neigh_node;

neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, seqno);
neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr,
ntohl(seqno));
if (!neigh_node)
goto out;

Expand All @@ -59,7 +60,7 @@ static int bat_iv_ogm_iface_enable(struct hard_iface *hard_iface)
{
struct batman_ogm_packet *batman_ogm_packet;
uint32_t random_seqno;
int res = -1;
int res = -ENOMEM;

/* randomize initial seqno to avoid collision */
get_random_bytes(&random_seqno, sizeof(random_seqno));
Expand Down Expand Up @@ -196,8 +197,12 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,

/* create clone because function is called more than once */
skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
if (skb)
if (skb) {
batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX);
batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES,
skb->len + ETH_HLEN);
send_skb_packet(skb, hard_iface, broadcast_addr);
}
}

/* send a batman ogm packet */
Expand Down Expand Up @@ -542,9 +547,6 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node,
"Forwarding packet: tq: %i, ttl: %i\n",
batman_ogm_packet->tq, batman_ogm_packet->header.ttl);

batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);

/* switch of primaries first hop flag when forwarding */
batman_ogm_packet->flags &= ~PRIMARIES_FIRST_HOP;
if (is_single_hop_neigh)
Expand All @@ -557,26 +559,31 @@ static void bat_iv_ogm_forward(struct orig_node *orig_node,
if_incoming, 0, bat_iv_ogm_fwd_send_time());
}

static void bat_iv_ogm_schedule(struct hard_iface *hard_iface,
int tt_num_changes)
static void bat_iv_ogm_schedule(struct hard_iface *hard_iface)
{
struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batman_ogm_packet *batman_ogm_packet;
struct hard_iface *primary_if;
int vis_server;
int vis_server, tt_num_changes = 0;

vis_server = atomic_read(&bat_priv->vis_mode);
primary_if = primary_if_get_selected(bat_priv);

if (hard_iface == primary_if)
tt_num_changes = batadv_tt_append_diff(bat_priv,
&hard_iface->packet_buff,
&hard_iface->packet_len,
BATMAN_OGM_HLEN);

batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;

/* change sequence number to network order */
batman_ogm_packet->seqno =
htonl((uint32_t)atomic_read(&hard_iface->seqno));
atomic_inc(&hard_iface->seqno);

batman_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn);
batman_ogm_packet->tt_crc = htons((uint16_t)
atomic_read(&bat_priv->tt_crc));
batman_ogm_packet->tt_crc = htons(bat_priv->tt_crc);
if (tt_num_changes >= 0)
batman_ogm_packet->tt_num_changes = tt_num_changes;

Expand All @@ -592,8 +599,6 @@ static void bat_iv_ogm_schedule(struct hard_iface *hard_iface,
else
batman_ogm_packet->gw_flags = NO_FLAGS;

atomic_inc(&hard_iface->seqno);

slide_own_bcast_window(hard_iface);
bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
hard_iface->packet_len, hard_iface, 1,
Expand Down Expand Up @@ -721,7 +726,7 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
tt_update_orig(bat_priv, orig_node, tt_buff,
batman_ogm_packet->tt_num_changes,
batman_ogm_packet->ttvn,
batman_ogm_packet->tt_crc);
ntohs(batman_ogm_packet->tt_crc));

if (orig_node->gw_flags != batman_ogm_packet->gw_flags)
gw_node_update(bat_priv, orig_node,
Expand Down Expand Up @@ -868,13 +873,14 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
int32_t seq_diff;
int need_update = 0;
int set_mark, ret = -1;
uint32_t seqno = ntohl(batman_ogm_packet->seqno);

orig_node = get_orig_node(bat_priv, batman_ogm_packet->orig);
if (!orig_node)
return 0;

spin_lock_bh(&orig_node->ogm_cnt_lock);
seq_diff = batman_ogm_packet->seqno - orig_node->last_real_seqno;
seq_diff = seqno - orig_node->last_real_seqno;

/* signalize caller that the packet is to be dropped. */
if (!hlist_empty(&orig_node->neigh_list) &&
Expand All @@ -888,7 +894,7 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,

is_duplicate |= bat_test_bit(tmp_neigh_node->real_bits,
orig_node->last_real_seqno,
batman_ogm_packet->seqno);
seqno);

if (compare_eth(tmp_neigh_node->addr, ethhdr->h_source) &&
(tmp_neigh_node->if_incoming == if_incoming))
Expand All @@ -910,8 +916,8 @@ static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
if (need_update) {
bat_dbg(DBG_BATMAN, bat_priv,
"updating last_seqno: old %u, new %u\n",
orig_node->last_real_seqno, batman_ogm_packet->seqno);
orig_node->last_real_seqno = batman_ogm_packet->seqno;
orig_node->last_real_seqno, seqno);
orig_node->last_real_seqno = seqno;
}

ret = is_duplicate;
Expand Down Expand Up @@ -967,8 +973,8 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
"Received BATMAN packet via NB: %pM, IF: %s [%pM] (from OG: %pM, via prev OG: %pM, seqno %u, ttvn %u, crc %u, changes %u, td %d, TTL %d, V %d, IDF %d)\n",
ethhdr->h_source, if_incoming->net_dev->name,
if_incoming->net_dev->dev_addr, batman_ogm_packet->orig,
batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc,
batman_ogm_packet->prev_sender, ntohl(batman_ogm_packet->seqno),
batman_ogm_packet->ttvn, ntohs(batman_ogm_packet->tt_crc),
batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
batman_ogm_packet->header.ttl,
batman_ogm_packet->header.version, has_directlink_flag);
Expand Down Expand Up @@ -1039,7 +1045,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
word = &(orig_neigh_node->bcast_own[offset]);
bat_set_bit(word,
if_incoming_seqno -
batman_ogm_packet->seqno - 2);
ntohl(batman_ogm_packet->seqno) - 2);
orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
bitmap_weight(word, TQ_LOCAL_WINDOW_SIZE);
spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
Expand Down Expand Up @@ -1132,7 +1138,7 @@ static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
* seqno and similar ttl as the non-duplicate */
if (is_bidirectional &&
(!is_duplicate ||
((orig_node->last_real_seqno == batman_ogm_packet->seqno) &&
((orig_node->last_real_seqno == ntohl(batman_ogm_packet->seqno)) &&
(orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl))))
bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
batman_ogm_packet, if_incoming,
Expand Down Expand Up @@ -1204,18 +1210,17 @@ static int bat_iv_ogm_receive(struct sk_buff *skb,
if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit)
return NET_RX_DROP;

batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX);
batadv_add_counter(bat_priv, BAT_CNT_MGMT_RX_BYTES,
skb->len + ETH_HLEN);

packet_len = skb_headlen(skb);
ethhdr = (struct ethhdr *)skb_mac_header(skb);
packet_buff = skb->data;
batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;

/* unpack the aggregated packets and process them one by one */
do {
/* network to host order for our 32bit seqno and the
orig_interval */
batman_ogm_packet->seqno = ntohl(batman_ogm_packet->seqno);
batman_ogm_packet->tt_crc = ntohs(batman_ogm_packet->tt_crc);

tt_buff = packet_buff + buff_pos + BATMAN_OGM_HLEN;

bat_iv_ogm_process(ethhdr, batman_ogm_packet,
Expand All @@ -1234,7 +1239,7 @@ static int bat_iv_ogm_receive(struct sk_buff *skb,
}

static struct bat_algo_ops batman_iv __read_mostly = {
.name = "BATMAN IV",
.name = "BATMAN_IV",
.bat_iface_enable = bat_iv_ogm_iface_enable,
.bat_iface_disable = bat_iv_ogm_iface_disable,
.bat_iface_update_mac = bat_iv_ogm_iface_update_mac,
Expand Down
4 changes: 2 additions & 2 deletions net/batman-adv/bat_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ BAT_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
store_gw_bwidth);
#ifdef CONFIG_BATMAN_ADV_DEBUG
BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
BAT_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, DBG_ALL, NULL);
#endif

static struct bat_attribute *mesh_attrs[] = {
Expand Down Expand Up @@ -680,7 +680,7 @@ void sysfs_del_hardif(struct kobject **hardif_obj)
int throw_uevent(struct bat_priv *bat_priv, enum uev_type type,
enum uev_action action, const char *data)
{
int ret = -1;
int ret = -ENOMEM;
struct hard_iface *primary_if = NULL;
struct kobject *bat_kobj;
char *uevent_env[4] = { NULL, NULL, NULL, NULL };
Expand Down
27 changes: 20 additions & 7 deletions net/batman-adv/bridge_loop_avoidance.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
struct net_device *soft_iface;
uint8_t *hw_src;
struct bla_claim_dst local_claim_dest;
uint32_t zeroip = 0;
__be32 zeroip = 0;

primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
Expand Down Expand Up @@ -506,11 +506,11 @@ static void bla_send_announce(struct bat_priv *bat_priv,
struct backbone_gw *backbone_gw)
{
uint8_t mac[ETH_ALEN];
uint16_t crc;
__be16 crc;

memcpy(mac, announce_mac, 4);
crc = htons(backbone_gw->crc);
memcpy(&mac[4], (uint8_t *)&crc, 2);
memcpy(&mac[4], &crc, 2);

bla_send_claim(bat_priv, mac, backbone_gw->vid, CLAIM_TYPE_ANNOUNCE);

Expand Down Expand Up @@ -627,7 +627,7 @@ static int handle_announce(struct bat_priv *bat_priv,

/* handle as ANNOUNCE frame */
backbone_gw->lasttime = jiffies;
crc = ntohs(*((uint16_t *)(&an_addr[4])));
crc = ntohs(*((__be16 *)(&an_addr[4])));

bat_dbg(DBG_BLA, bat_priv,
"handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n",
Expand Down Expand Up @@ -1127,6 +1127,14 @@ static void bla_periodic_work(struct work_struct *work)
bla_start_timer(bat_priv);
}

/* The hash for claim and backbone hash receive the same key because they
* are getting initialized by hash_new with the same key. Reinitializing
* them with to different keys to allow nested locking without generating
* lockdep warnings
*/
static struct lock_class_key claim_hash_lock_class_key;
static struct lock_class_key backbone_hash_lock_class_key;

/* initialize all bla structures */
int bla_init(struct bat_priv *bat_priv)
{
Expand Down Expand Up @@ -1156,18 +1164,23 @@ int bla_init(struct bat_priv *bat_priv)
bat_priv->bcast_duplist_curr = 0;

if (bat_priv->claim_hash)
return 1;
return 0;

bat_priv->claim_hash = hash_new(128);
bat_priv->backbone_hash = hash_new(32);

if (!bat_priv->claim_hash || !bat_priv->backbone_hash)
return -1;
return -ENOMEM;

batadv_hash_set_lock_class(bat_priv->claim_hash,
&claim_hash_lock_class_key);
batadv_hash_set_lock_class(bat_priv->backbone_hash,
&backbone_hash_lock_class_key);

bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n");

bla_start_timer(bat_priv);
return 1;
return 0;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions net/batman-adv/gateway_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count)
**/
gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up);

if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp)
return count;

gw_deselect(bat_priv);
bat_info(net_dev,
"Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n",
Expand Down
4 changes: 1 addition & 3 deletions net/batman-adv/hard-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
bat_priv = netdev_priv(hard_iface->soft_iface);

ret = bat_priv->bat_algo_ops->bat_iface_enable(hard_iface);
if (ret < 0) {
ret = -ENOMEM;
if (ret < 0)
goto err_dev;
}

hard_iface->if_num = bat_priv->num_ifaces;
bat_priv->num_ifaces++;
Expand Down
9 changes: 9 additions & 0 deletions net/batman-adv/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ struct hashtable_t *hash_new(uint32_t size)
kfree(hash);
return NULL;
}

void batadv_hash_set_lock_class(struct hashtable_t *hash,
struct lock_class_key *key)
{
uint32_t i;

for (i = 0; i < hash->size; i++)
lockdep_set_class(&hash->list_locks[i], key);
}
Loading

0 comments on commit f032537

Please sign in to comment.