The following commit has been merged in the master branch: commit d401c1d1e824f8238c4da5f432151fad0945aeab Merge: a6dfdb4e1cd8ea0cf3e8588b97a0c33f8ad3fa4b 93bbaab455f30fd43911e0881a02107a17150a62 Author: David S. Miller davem@davemloft.net Date: Wed Nov 9 22:15:28 2016 -0500
Merge tag 'batadv-next-for-davem-20161108-v2' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says:
==================== pull request for net-next: batman-adv 2016-11-08 v2
This feature and cleanup patchset includes the following changes:
- netlink and code cleanups by Sven Eckelmann (3 patches)
- Cleanup and minor fixes by Linus Luessing (3 patches)
- Speed up multicast update intervals, by Linus Luessing
- Avoid (re)broadcast in meshes for some easy cases, by Linus Luessing
- Clean up tx return state handling, by Sven Eckelmann (6 patches)
- Fix some special mac address handling cases, by Sven Eckelmann (3 patches) ====================
Signed-off-by: David S. Miller davem@davemloft.net
diff --combined net/batman-adv/hard-interface.c index e034afb,a7a462e..dc1816e --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@@ -228,6 -228,58 +228,58 @@@ bool batadv_is_wifi_netdev(struct net_d return false; }
+ /** + * batadv_hardif_no_broadcast - check whether (re)broadcast is necessary + * @if_outgoing: the outgoing interface checked and considered for (re)broadcast + * @orig_addr: the originator of this packet + * @orig_neigh: originator address of the forwarder we just got the packet from + * (NULL if we originated) + * + * Checks whether a packet needs to be (re)broadcasted on the given interface. + * + * Return: + * BATADV_HARDIF_BCAST_NORECIPIENT: No neighbor on interface + * BATADV_HARDIF_BCAST_DUPFWD: Just one neighbor, but it is the forwarder + * BATADV_HARDIF_BCAST_DUPORIG: Just one neighbor, but it is the originator + * BATADV_HARDIF_BCAST_OK: Several neighbors, must broadcast + */ + int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing, + u8 *orig_addr, u8 *orig_neigh) + { + struct batadv_hardif_neigh_node *hardif_neigh; + struct hlist_node *first; + int ret = BATADV_HARDIF_BCAST_OK; + + rcu_read_lock(); + + /* 0 neighbors -> no (re)broadcast */ + first = rcu_dereference(hlist_first_rcu(&if_outgoing->neigh_list)); + if (!first) { + ret = BATADV_HARDIF_BCAST_NORECIPIENT; + goto out; + } + + /* >1 neighbors -> (re)brodcast */ + if (rcu_dereference(hlist_next_rcu(first))) + goto out; + + hardif_neigh = hlist_entry(first, struct batadv_hardif_neigh_node, + list); + + /* 1 neighbor, is the originator -> no rebroadcast */ + if (orig_addr && batadv_compare_eth(hardif_neigh->orig, orig_addr)) { + ret = BATADV_HARDIF_BCAST_DUPORIG; + /* 1 neighbor, is the one we received from -> no rebroadcast */ + } else if (orig_neigh && + batadv_compare_eth(hardif_neigh->orig, orig_neigh)) { + ret = BATADV_HARDIF_BCAST_DUPFWD; + } + + out: + rcu_read_unlock(); + return ret; + } + static struct batadv_hard_iface * batadv_hardif_get_active(const struct net_device *soft_iface) { @@@ -652,6 -704,7 +704,6 @@@ void batadv_hardif_disable_interface(st batadv_softif_destroy_sysfs(hard_iface->soft_iface); }
- hard_iface->soft_iface = NULL; batadv_hardif_put(hard_iface);
out: diff --combined net/batman-adv/originator.c index c6e7e1e,ad26559..8f3b296 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@@ -512,12 -512,14 +512,14 @@@ batadv_neigh_node_get(const struct bata * batadv_hardif_neigh_create - create a hardif neighbour node * @hard_iface: the interface this neighbour is connected to * @neigh_addr: the interface address of the neighbour to retrieve + * @orig_node: originator object representing the neighbour * * Return: the hardif neighbour node if found or created or NULL otherwise. */ static struct batadv_hardif_neigh_node * batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface, - const u8 *neigh_addr) + const u8 *neigh_addr, + struct batadv_orig_node *orig_node) { struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_hardif_neigh_node *hardif_neigh; @@@ -536,6 -538,7 +538,7 @@@ kref_get(&hard_iface->refcount); INIT_HLIST_NODE(&hardif_neigh->list); ether_addr_copy(hardif_neigh->addr, neigh_addr); + ether_addr_copy(hardif_neigh->orig, orig_node->orig); hardif_neigh->if_incoming = hard_iface; hardif_neigh->last_seen = jiffies;
@@@ -544,7 -547,7 +547,7 @@@ if (bat_priv->algo_ops->neigh.hardif_init) bat_priv->algo_ops->neigh.hardif_init(hardif_neigh);
- hlist_add_head(&hardif_neigh->list, &hard_iface->neigh_list); + hlist_add_head_rcu(&hardif_neigh->list, &hard_iface->neigh_list);
out: spin_unlock_bh(&hard_iface->neigh_list_lock); @@@ -556,12 -559,14 +559,14 @@@ * node * @hard_iface: the interface this neighbour is connected to * @neigh_addr: the interface address of the neighbour to retrieve + * @orig_node: originator object representing the neighbour * * Return: the hardif neighbour node if found or created or NULL otherwise. */ static struct batadv_hardif_neigh_node * batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface, - const u8 *neigh_addr) + const u8 *neigh_addr, + struct batadv_orig_node *orig_node) { struct batadv_hardif_neigh_node *hardif_neigh;
@@@ -570,7 -575,7 +575,7 @@@ if (hardif_neigh) return hardif_neigh;
- return batadv_hardif_neigh_create(hard_iface, neigh_addr); + return batadv_hardif_neigh_create(hard_iface, neigh_addr, orig_node); }
/** @@@ -630,7 -635,7 +635,7 @@@ batadv_neigh_node_create(struct batadv_ goto out;
hardif_neigh = batadv_hardif_neigh_get_or_create(hard_iface, - neigh_addr); + neigh_addr, orig_node); if (!hardif_neigh) goto out;