Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b72ca67 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge



Antonio Quartulli says:

====================
Included changes:
- code beautification
- remove obsolete 'deleted' attribute for bat-gw node
- increase internal version number
- prevent potential access to netdev object after deregistration
- set needed_head/tail_room for batman virtual interface
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9723e6ab ed292663
Loading
Loading
Loading
Loading
+2 −28
Original line number Diff line number Diff line
@@ -296,39 +296,13 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
			struct batadv_orig_node *orig_node,
			struct batadv_orig_node *orig_neigh)
{
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
	struct batadv_neigh_node *neigh_node, *tmp_neigh_node;
	struct batadv_neigh_node *neigh_node;

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

	if (!atomic_inc_not_zero(&hard_iface->refcount)) {
		kfree(neigh_node);
		neigh_node = NULL;
		goto out;
	}

	neigh_node->orig_node = orig_neigh;
	neigh_node->if_incoming = hard_iface;

	spin_lock_bh(&orig_node->neigh_list_lock);
	tmp_neigh_node = batadv_neigh_node_get(orig_node, hard_iface,
					       neigh_addr);
	if (!tmp_neigh_node) {
		hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
	} else {
		kfree(neigh_node);
		batadv_hardif_free_ref(hard_iface);
		neigh_node = tmp_neigh_node;
	}
	spin_unlock_bh(&orig_node->neigh_list_lock);

	if (!tmp_neigh_node)
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Creating new neighbor %pM for orig_node %pM on interface %s\n",
			   neigh_addr, orig_node->orig,
			   hard_iface->net_dev->name);

out:
	return neigh_node;
+12 −38
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/netdevice.h>
@@ -161,9 +160,6 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)

	rcu_read_lock();
	hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
		if (gw_node->deleted)
			continue;

		orig_node = gw_node->orig_node;
		router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
		if (!router)
@@ -473,9 +469,6 @@ batadv_gw_node_get(struct batadv_priv *bat_priv,
		if (gw_node_tmp->orig_node != orig_node)
			continue;

		if (gw_node_tmp->deleted)
			continue;

		if (!atomic_inc_not_zero(&gw_node_tmp->refcount))
			continue;

@@ -525,9 +518,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
	gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
	gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);

	gw_node->deleted = 0;
	if (ntohl(gateway->bandwidth_down) == 0) {
		gw_node->deleted = jiffies;
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Gateway %pM removed from gateway list\n",
			   orig_node->orig);
@@ -535,14 +526,21 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
		/* Note: We don't need a NULL check here, since curr_gw never
		 * gets dereferenced.
		 */
		spin_lock_bh(&bat_priv->gw.list_lock);
		hlist_del_init_rcu(&gw_node->list);
		spin_unlock_bh(&bat_priv->gw.list_lock);

		batadv_gw_node_free_ref(gw_node);

		curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
		if (gw_node == curr_gw)
			batadv_gw_reselect(bat_priv);
	}

out:
		if (curr_gw)
			batadv_gw_node_free_ref(curr_gw);
	}

out:
	if (gw_node)
		batadv_gw_node_free_ref(gw_node);
}
@@ -558,39 +556,18 @@ void batadv_gw_node_delete(struct batadv_priv *bat_priv,
	batadv_gw_node_update(bat_priv, orig_node, &gateway);
}

void batadv_gw_node_purge(struct batadv_priv *bat_priv)
void batadv_gw_node_free(struct batadv_priv *bat_priv)
{
	struct batadv_gw_node *gw_node, *curr_gw;
	struct batadv_gw_node *gw_node;
	struct hlist_node *node_tmp;
	unsigned long timeout = msecs_to_jiffies(2 * BATADV_PURGE_TIMEOUT);
	int do_reselect = 0;

	curr_gw = batadv_gw_get_selected_gw_node(bat_priv);

	spin_lock_bh(&bat_priv->gw.list_lock);

	hlist_for_each_entry_safe(gw_node, node_tmp,
				  &bat_priv->gw.list, list) {
		if (((!gw_node->deleted) ||
		     (time_before(jiffies, gw_node->deleted + timeout))) &&
		    atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE)
			continue;

		if (curr_gw == gw_node)
			do_reselect = 1;

		hlist_del_rcu(&gw_node->list);
		hlist_del_init_rcu(&gw_node->list);
		batadv_gw_node_free_ref(gw_node);
	}

	spin_unlock_bh(&bat_priv->gw.list_lock);

	/* gw_reselect() needs to acquire the gw_list_lock */
	if (do_reselect)
		batadv_gw_reselect(bat_priv);

	if (curr_gw)
		batadv_gw_node_free_ref(curr_gw);
}

/* fails if orig_node has no router */
@@ -654,9 +631,6 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)

	rcu_read_lock();
	hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
		if (gw_node->deleted)
			continue;

		/* fails if orig_node has no router */
		if (batadv_write_buffer_text(bat_priv, seq, gw_node) < 0)
			continue;
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
			   struct batadv_tvlv_gateway_data *gateway);
void batadv_gw_node_delete(struct batadv_priv *bat_priv,
			   struct batadv_orig_node *orig_node);
void batadv_gw_node_purge(struct batadv_priv *bat_priv);
void batadv_gw_node_free(struct batadv_priv *bat_priv);
int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset);
bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, struct sk_buff *skb);
enum batadv_dhcp_recipient
+43 −1
Original line number Diff line number Diff line
@@ -252,6 +252,44 @@ static void batadv_check_known_mac_addr(const struct net_device *net_dev)
	rcu_read_unlock();
}

/**
 * batadv_hardif_recalc_extra_skbroom() - Recalculate skbuff extra head/tailroom
 * @soft_iface: netdev struct of the mesh interface
 */
static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface)
{
	const struct batadv_hard_iface *hard_iface;
	unsigned short lower_header_len = ETH_HLEN;
	unsigned short lower_headroom = 0;
	unsigned short lower_tailroom = 0;
	unsigned short needed_headroom;

	rcu_read_lock();
	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
		if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
			continue;

		if (hard_iface->soft_iface != soft_iface)
			continue;

		lower_header_len = max_t(unsigned short, lower_header_len,
					 hard_iface->net_dev->hard_header_len);

		lower_headroom = max_t(unsigned short, lower_headroom,
				       hard_iface->net_dev->needed_headroom);

		lower_tailroom = max_t(unsigned short, lower_tailroom,
				       hard_iface->net_dev->needed_tailroom);
	}
	rcu_read_unlock();

	needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN);
	needed_headroom += batadv_max_header_len();

	soft_iface->needed_headroom = needed_headroom;
	soft_iface->needed_tailroom = lower_tailroom;
}

int batadv_hardif_min_mtu(struct net_device *soft_iface)
{
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
@@ -474,6 +512,8 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
			   "Not using interface %s (retrying later): interface not active\n",
			   hard_iface->net_dev->name);

	batadv_hardif_recalc_extra_skbroom(soft_iface);

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

@@ -528,6 +568,9 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
	batadv_purge_outstanding_packets(bat_priv, hard_iface);
	dev_put(hard_iface->soft_iface);

	netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
	batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);

	/* nobody uses this interface anymore */
	if (!bat_priv->num_ifaces) {
		batadv_gw_check_client_stop(bat_priv);
@@ -536,7 +579,6 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
			batadv_softif_destroy_sysfs(hard_iface->soft_iface);
	}

	netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->soft_iface);
	hard_iface->soft_iface = NULL;
	batadv_hardif_free_ref(hard_iface);

+1 −1
Original line number Diff line number Diff line
@@ -199,7 +199,7 @@ void batadv_mesh_free(struct net_device *soft_iface)

	batadv_purge_outstanding_packets(bat_priv, NULL);

	batadv_gw_node_purge(bat_priv);
	batadv_gw_node_free(bat_priv);
	batadv_nc_mesh_free(bat_priv);
	batadv_dat_free(bat_priv);
	batadv_bla_free(bat_priv);
Loading