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

Commit ea407f0b 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



Included changes:
- A fix for the network coding component which has been added within the last
  pull request (so it is in linux-3.10). The problem has been spotted thanks to
  Fengguang Wu's automated daily checks on our tree.
- Implementation of the RTNL API for virtual interface creation/deletion and slave
  manipulation
- substitution of seq_printf with seq_puts when possible
- minor cleanups

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9631d79e 0c814653
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
#
#
# Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
# Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
#
#
# Marek Lindner, Simon Wunderlich
# Marek Lindner, Simon Wunderlich
#
#
+1 −1
Original line number Original line Diff line number Diff line
@@ -500,7 +500,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
	rcu_read_unlock();
	rcu_read_unlock();


	if (gw_count == 0)
	if (gw_count == 0)
		seq_printf(seq, "No gateways in range ...\n");
		seq_puts(seq, "No gateways in range ...\n");


out:
out:
	if (primary_if)
	if (primary_if)
+54 −12
Original line number Original line Diff line number Diff line
@@ -307,11 +307,35 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
	batadv_update_min_mtu(hard_iface->soft_iface);
	batadv_update_min_mtu(hard_iface->soft_iface);
}
}


/**
 * batadv_master_del_slave - remove hard_iface from the current master interface
 * @slave: the interface enslaved in another master
 * @master: the master from which slave has to be removed
 *
 * Invoke ndo_del_slave on master passing slave as argument. In this way slave
 * is free'd and master can correctly change its internal state.
 * Return 0 on success, a negative value representing the error otherwise
 */
static int batadv_master_del_slave(struct batadv_hard_iface *slave,
				   struct net_device *master)
{
	int ret;

	if (!master)
		return 0;

	ret = -EBUSY;
	if (master->netdev_ops->ndo_del_slave)
		ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev);

	return ret;
}

int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
				   const char *iface_name)
				   const char *iface_name)
{
{
	struct batadv_priv *bat_priv;
	struct batadv_priv *bat_priv;
	struct net_device *soft_iface;
	struct net_device *soft_iface, *master;
	__be16 ethertype = __constant_htons(ETH_P_BATMAN);
	__be16 ethertype = __constant_htons(ETH_P_BATMAN);
	int ret;
	int ret;


@@ -321,11 +345,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
	if (!atomic_inc_not_zero(&hard_iface->refcount))
	if (!atomic_inc_not_zero(&hard_iface->refcount))
		goto out;
		goto out;


	/* hard-interface is part of a bridge */
	if (hard_iface->net_dev->priv_flags & IFF_BRIDGE_PORT)
		pr_err("You are about to enable batman-adv on '%s' which already is part of a bridge. Unless you know exactly what you are doing this is probably wrong and won't work the way you think it would.\n",
		       hard_iface->net_dev->name);

	soft_iface = dev_get_by_name(&init_net, iface_name);
	soft_iface = dev_get_by_name(&init_net, iface_name);


	if (!soft_iface) {
	if (!soft_iface) {
@@ -347,12 +366,24 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
		goto err_dev;
		goto err_dev;
	}
	}


	/* check if the interface is enslaved in another virtual one and
	 * in that case unlink it first
	 */
	master = netdev_master_upper_dev_get(hard_iface->net_dev);
	ret = batadv_master_del_slave(hard_iface, master);
	if (ret)
		goto err_dev;

	hard_iface->soft_iface = soft_iface;
	hard_iface->soft_iface = soft_iface;
	bat_priv = netdev_priv(hard_iface->soft_iface);
	bat_priv = netdev_priv(hard_iface->soft_iface);


	ret = netdev_master_upper_dev_link(hard_iface->net_dev, soft_iface);
	if (ret)
		goto err_dev;

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


	hard_iface->if_num = bat_priv->num_ifaces;
	hard_iface->if_num = bat_priv->num_ifaces;
	bat_priv->num_ifaces++;
	bat_priv->num_ifaces++;
@@ -362,7 +393,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
		bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
		bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
		bat_priv->num_ifaces--;
		bat_priv->num_ifaces--;
		hard_iface->if_status = BATADV_IF_NOT_IN_USE;
		hard_iface->if_status = BATADV_IF_NOT_IN_USE;
		goto err_dev;
		goto err_upper;
	}
	}


	hard_iface->batman_adv_ptype.type = ethertype;
	hard_iface->batman_adv_ptype.type = ethertype;
@@ -401,14 +432,18 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
out:
out:
	return 0;
	return 0;


err_upper:
	netdev_upper_dev_unlink(hard_iface->net_dev, soft_iface);
err_dev:
err_dev:
	hard_iface->soft_iface = NULL;
	dev_put(soft_iface);
	dev_put(soft_iface);
err:
err:
	batadv_hardif_free_ref(hard_iface);
	batadv_hardif_free_ref(hard_iface);
	return ret;
	return ret;
}
}


void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
				     enum batadv_hard_if_cleanup autodel)
{
{
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_hard_iface *primary_if = NULL;
@@ -446,9 +481,10 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
	dev_put(hard_iface->soft_iface);
	dev_put(hard_iface->soft_iface);


	/* nobody uses this interface anymore */
	/* nobody uses this interface anymore */
	if (!bat_priv->num_ifaces)
	if (!bat_priv->num_ifaces && autodel == BATADV_IF_CLEANUP_AUTO)
		batadv_softif_destroy(hard_iface->soft_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;
	hard_iface->soft_iface = NULL;
	batadv_hardif_free_ref(hard_iface);
	batadv_hardif_free_ref(hard_iface);


@@ -533,7 +569,8 @@ static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)


	/* first deactivate interface */
	/* first deactivate interface */
	if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
	if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
		batadv_hardif_disable_interface(hard_iface);
		batadv_hardif_disable_interface(hard_iface,
						BATADV_IF_CLEANUP_AUTO);


	if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
	if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
		return;
		return;
@@ -563,6 +600,11 @@ static int batadv_hard_if_event(struct notifier_block *this,
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_priv *bat_priv;
	struct batadv_priv *bat_priv;


	if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
		batadv_sysfs_add_meshif(net_dev);
		return NOTIFY_DONE;
	}

	hard_iface = batadv_hardif_get_by_netdev(net_dev);
	hard_iface = batadv_hardif_get_by_netdev(net_dev);
	if (!hard_iface && event == NETDEV_REGISTER)
	if (!hard_iface && event == NETDEV_REGISTER)
		hard_iface = batadv_hardif_add_interface(net_dev);
		hard_iface = batadv_hardif_add_interface(net_dev);
+12 −1
Original line number Original line Diff line number Diff line
@@ -29,13 +29,24 @@ enum batadv_hard_if_state {
	BATADV_IF_I_WANT_YOU,
	BATADV_IF_I_WANT_YOU,
};
};


/**
 * enum batadv_hard_if_cleanup - Cleanup modi for soft_iface after slave removal
 * @BATADV_IF_CLEANUP_KEEP: Don't automatically delete soft-interface
 * @BATADV_IF_CLEANUP_AUTO: Delete soft-interface after last slave was removed
 */
enum batadv_hard_if_cleanup {
	BATADV_IF_CLEANUP_KEEP,
	BATADV_IF_CLEANUP_AUTO,
};

extern struct notifier_block batadv_hard_if_notifier;
extern struct notifier_block batadv_hard_if_notifier;


struct batadv_hard_iface*
struct batadv_hard_iface*
batadv_hardif_get_by_netdev(const struct net_device *net_dev);
batadv_hardif_get_by_netdev(const struct net_device *net_dev);
int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
				   const char *iface_name);
				   const char *iface_name);
void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface);
void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
				     enum batadv_hard_if_cleanup autodel);
void batadv_hardif_remove_interfaces(void);
void batadv_hardif_remove_interfaces(void);
int batadv_hardif_min_mtu(struct net_device *soft_iface);
int batadv_hardif_min_mtu(struct net_device *soft_iface);
void batadv_update_min_mtu(struct net_device *soft_iface);
void batadv_update_min_mtu(struct net_device *soft_iface);
+3 −1
Original line number Original line Diff line number Diff line
@@ -71,6 +71,7 @@ static int __init batadv_init(void)
	batadv_debugfs_init();
	batadv_debugfs_init();


	register_netdevice_notifier(&batadv_hard_if_notifier);
	register_netdevice_notifier(&batadv_hard_if_notifier);
	rtnl_link_register(&batadv_link_ops);


	pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
	pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
		BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
		BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
@@ -81,6 +82,7 @@ static int __init batadv_init(void)
static void __exit batadv_exit(void)
static void __exit batadv_exit(void)
{
{
	batadv_debugfs_destroy();
	batadv_debugfs_destroy();
	rtnl_link_unregister(&batadv_link_ops);
	unregister_netdevice_notifier(&batadv_hard_if_notifier);
	unregister_netdevice_notifier(&batadv_hard_if_notifier);
	batadv_hardif_remove_interfaces();
	batadv_hardif_remove_interfaces();


@@ -417,7 +419,7 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset)
{
{
	struct batadv_algo_ops *bat_algo_ops;
	struct batadv_algo_ops *bat_algo_ops;


	seq_printf(seq, "Available routing algorithms:\n");
	seq_puts(seq, "Available routing algorithms:\n");


	hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) {
	hlist_for_each_entry(bat_algo_ops, &batadv_algo_list, list) {
		seq_printf(seq, "%s\n", bat_algo_ops->name);
		seq_printf(seq, "%s\n", bat_algo_ops->name);
Loading