Permalink
Browse files

batman-adv: introduce 'no_rebroadcast' option

This patch introduces a new sysfs option named "no_rebroadcast" on
a per hard interface basis. It allows manually enabling a split-horizon
like behaviour for the layer 2 multicast payload frames, in that
incoming multicast payload frames on such a hard interface are only
being rebroadcasted on all interfaces except the incoming one instead
of being rebroadcasted on all interfaces.

Such an option should only be enabled if you are certain that these
rebroadcasts are unnecessary. This is usually the case for instance
for point-to-point wifi longshots or wired links.

This option can especially safe a significant amount of upload overhead
if the neighbourhood on a link is rather large, for instance in some
transitive, symmetric VPN configurations.

Using this option wrongly will break your mesh network, use this option
wisely and at your own risk!

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
  • Loading branch information...
T-X authored and NeoRaider committed Sep 24, 2013
1 parent 1356028 commit b0160f988c7ff386042b2feef4f056cb66602090
Showing with 76 additions and 0 deletions.
  1. +2 −0 hard-interface.c
  2. +4 −0 send.c
  3. +10 −0 sysfs-class-net-batman-adv
  4. +59 −0 sysfs.c
  5. +1 −0 types.h
@@ -600,6 +600,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
/* extra reference for return */
atomic_set(&hard_iface->refcount, 2);
atomic_set(&hard_iface->no_rebroadcast, 0);
batadv_check_known_mac_addr(hard_iface->net_dev);
list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
4 send.c
@@ -272,6 +272,10 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
if (forw_packet->num_packets >= hard_iface->num_bcasts)
continue;
if (atomic_read(&hard_iface->no_rebroadcast) &&
forw_packet->skb->dev == hard_iface->net_dev)
continue;
/* send a copy of the saved skb */
skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
if (skb1)
@@ -13,3 +13,13 @@ Description:
displays the batman mesh interface this <iface>
currently is associated with.
What: /sys/class/net/<iface>/batman-adv/no_rebroadcast
Date: Sep 2013
Contact: Linus Lüssing <linus.luessing@web.de>
Description:
With this option set incoming multicast payload frames on
<iface> are not being rebroadcasted on <iface> again. This
option should be set on links which are known to be transitive
and symmetric only, for instance point-to-point wifi longshots
or wired links. Using this option wrongly is going to
break your mesh network, use at your own risk!
59 sysfs.c
@@ -53,6 +53,17 @@ static char *batadv_uev_type_str[] = {
"gw"
};
/* Use this, if you have customized show and store functions
* for hard interface attrs
*/
#define BATADV_ATTR_HIF(_name, _mode, _show, _store) \
struct batadv_attribute batadv_attr_hif_##_name = { \
.attr = {.name = __stringify(_name), \
.mode = _mode }, \
.show = _show, \
.store = _store, \
};
/* Use this, if you have customized show and store functions */
#define BATADV_ATTR(_name, _mode, _show, _store) \
struct batadv_attribute batadv_attr_##_name = { \
@@ -123,6 +134,52 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \
batadv_store_##_name)
#define BATADV_ATTR_HIF_STORE_BOOL(_name, _post_func) \
ssize_t batadv_store_hif_##_name(struct kobject *kobj, \
struct attribute *attr, char *buff, \
size_t count) \
{ \
struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
struct batadv_hard_iface *hard_iface; \
size_t res; \
\
hard_iface = batadv_hardif_get_by_netdev(net_dev); \
if (!hard_iface) \
return 0; \
\
res = __batadv_store_bool_attr(buff, count, _post_func, \
attr, &hard_iface->_name, \
hard_iface->soft_iface); \
batadv_hardif_free_ref(hard_iface); \
return res; \
}
#define BATADV_ATTR_HIF_SHOW_BOOL(_name) \
ssize_t batadv_show_hif_##_name(struct kobject *kobj, \
struct attribute *attr, char *buff) \
{ \
struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
struct batadv_hard_iface *hard_iface; \
size_t res; \
\
hard_iface = batadv_hardif_get_by_netdev(net_dev); \
if (!hard_iface) \
return 0; \
\
res = sprintf(buff, "%s\n", \
atomic_read(&hard_iface->_name) == 0 ? \
"disabled" : "enabled"); \
batadv_hardif_free_ref(hard_iface); \
return res; \
}
/* Use this, if you are going to turn a [name] in the vlan struct on or off */
#define BATADV_ATTR_HIF_BOOL(_name, _mode, _post_func) \
static BATADV_ATTR_HIF_STORE_BOOL(_name, _post_func) \
static BATADV_ATTR_HIF_SHOW_BOOL(_name) \
static BATADV_ATTR_HIF(_name, _mode, batadv_show_hif_##_name, \
batadv_store_hif_##_name)
static int batadv_store_bool_attr(char *buff, size_t count,
struct net_device *net_dev,
const char *attr_name, atomic_t *attr)
@@ -642,10 +699,12 @@ static ssize_t batadv_show_iface_status(struct kobject *kobj,
static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
batadv_store_mesh_iface);
static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
BATADV_ATTR_HIF_BOOL(no_rebroadcast, S_IRUGO | S_IWUSR, NULL);
static struct batadv_attribute *batadv_batman_attrs[] = {
&batadv_attr_mesh_iface,
&batadv_attr_iface_status,
&batadv_attr_hif_no_rebroadcast,
NULL,
};
@@ -85,6 +85,7 @@ struct batadv_hard_iface {
struct rcu_head rcu;
struct batadv_hard_iface_bat_iv bat_iv;
struct work_struct cleanup_work;
atomic_t no_rebroadcast;
};
/**

0 comments on commit b0160f9

Please sign in to comment.