The new neighbor discovery packets will later need their own interval per interface. For instance on a wifi interface which has regularly changing link qualities the ndp interval should be faster than on a static cable link where we would need some probes from time to time only.
This patch adds a workqueue per interface used by batman-adv. When an interface is active, a ndp_send() with the according batman_if structure will be called every second now.
Signed-off-by: Linus Lüssing linus.luessing@ascom.ch --- Makefile.kbuild | 1 + hard-interface.c | 9 +++++++ ndp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ndp.h | 31 +++++++++++++++++++++++ types.h | 3 ++ 5 files changed, 115 insertions(+), 0 deletions(-) create mode 100644 ndp.c create mode 100644 ndp.h
diff --git a/batman-adv/Makefile.kbuild b/batman-adv/Makefile.kbuild index e99c198..094eb31 100644 --- a/batman-adv/Makefile.kbuild +++ b/batman-adv/Makefile.kbuild @@ -42,6 +42,7 @@ batman-adv-y += hard-interface.o batman-adv-y += hash.o batman-adv-y += icmp_socket.o batman-adv-y += main.o +batman-adv-y += ndp.o batman-adv-y += originator.o batman-adv-y += ring_buffer.o batman-adv-y += routing.o diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c index a992113..aba895f 100644 --- a/batman-adv/hard-interface.c +++ b/batman-adv/hard-interface.c @@ -26,6 +26,7 @@ #include "translation-table.h" #include "routing.h" #include "bat_sysfs.h" +#include "ndp.h" #include "originator.h" #include "hash.h"
@@ -260,6 +261,7 @@ static void hardif_activate_interface(struct batman_if *batman_if) batman_if->net_dev->name);
update_min_mtu(batman_if->soft_iface); + ndp_start_timer(batman_if); return; }
@@ -274,6 +276,7 @@ static void hardif_deactivate_interface(struct batman_if *batman_if) bat_info(batman_if->soft_iface, "Interface deactivated: %s\n", batman_if->net_dev->name);
+ ndp_stop_timer(batman_if); update_min_mtu(batman_if->soft_iface); }
@@ -328,6 +331,8 @@ int hardif_enable_interface(struct batman_if *batman_if, char *iface_name)
atomic_set(&batman_if->seqno, 1); atomic_set(&batman_if->frag_seqno, 1); + ndp_init(batman_if); + bat_info(batman_if->soft_iface, "Adding interface: %s\n", batman_if->net_dev->name);
@@ -381,6 +386,7 @@ void hardif_disable_interface(struct batman_if *batman_if)
bat_info(batman_if->soft_iface, "Removing interface: %s\n", batman_if->net_dev->name); + ndp_free(batman_if); dev_remove_pack(&batman_if->batman_adv_ptype); kref_put(&batman_if->refcount, hardif_free_ref);
@@ -435,6 +441,9 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) if (ret) goto free_if;
+ atomic_set(&batman_if->ndp_interval, 500); + atomic_set(&batman_if->ndp_seqno, 0); + batman_if->if_num = -1; batman_if->net_dev = net_dev; batman_if->soft_iface = NULL; diff --git a/batman-adv/ndp.c b/batman-adv/ndp.c new file mode 100644 index 0000000..60631b0 --- /dev/null +++ b/batman-adv/ndp.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Linus Lüssing + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "send.h" +#include "ndp.h" + +/* when do we schedule our own neighbor discovery packet to be sent */ +static unsigned long own_ndp_send_time(struct batman_if *batman_if) +{ + return jiffies + msecs_to_jiffies( + atomic_read(&batman_if->ndp_interval) - + JITTER + (random32() % 2*JITTER)); +} + +void ndp_start_timer(struct batman_if *batman_if) +{ + /* adding some jitter */ + unsigned long ndp_interval = own_ndp_send_time(batman_if); + queue_delayed_work(bat_event_workqueue, &batman_if->ndp_wq, + ndp_interval - jiffies); +} + +void ndp_stop_timer(struct batman_if *batman_if) +{ + cancel_delayed_work_sync(&batman_if->ndp_wq); +} + +static void ndp_send(struct work_struct *work) +{ + struct batman_if *batman_if = container_of(work, struct batman_if, + ndp_wq.work); + struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); + + bat_dbg(DBG_BATMAN, bat_priv, + "batman-adv:Sending ndp packet on interface %s, seqno %d\n", + batman_if->net_dev, atomic_read(&batman_if->ndp_seqno)); + + atomic_inc(&batman_if->ndp_seqno); + ndp_start_timer(batman_if); +} + +int ndp_init(struct batman_if *batman_if) +{ + INIT_DELAYED_WORK(&batman_if->ndp_wq, ndp_send); + + return 0; +} + +void ndp_free(struct batman_if *batman_if) +{ + ndp_stop_timer(batman_if); +} diff --git a/batman-adv/ndp.h b/batman-adv/ndp.h new file mode 100644 index 0000000..1405e6b --- /dev/null +++ b/batman-adv/ndp.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Linus Lüssing + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_NDP_H_ +#define _NET_BATMAN_ADV_NDP_H_ + +void ndp_start_timer(struct batman_if *batman_if); +void ndp_stop_timer(struct batman_if *batman_if); + +int ndp_init(struct batman_if *batman_if); +void ndp_free(struct batman_if *batman_if); + +#endif /* _NET_BATMAN_ADV_NDP_H_ */ diff --git a/batman-adv/types.h b/batman-adv/types.h index 09d18d8..3ef48a6 100644 --- a/batman-adv/types.h +++ b/batman-adv/types.h @@ -47,6 +47,9 @@ struct batman_if { struct packet_type batman_adv_ptype; struct net_device *soft_iface; struct rcu_head rcu; + atomic_t ndp_interval; + atomic_t ndp_seqno; + struct delayed_work ndp_wq; };
/**