[B.A.T.M.A.N.] [PATCH] batman-adv: Deinline batadv_orig_hash_find, save 9024 bytes
by Denys Vlasenko
This function compiles to 473 bytes of machine code.
21 callsites.
text data bss dec hex filename
95903266 20860288 35991552 152755106 91adba2 vmlinux_before
95894242 20860288 35991552 152746082 91ab862 vmlinux
Signed-off-by: Denys Vlasenko <dvlasenk(a)redhat.com>
CC: Marek Lindner <mareklindner(a)neomailbox.ch>
CC: Simon Wunderlich <sw(a)simonwunderlich.de>
CC: Antonio Quartulli <a(a)unstable.cc>
CC: Sven Eckelmann <sven(a)narfation.org>
CC: b.a.t.m.a.n(a)lists.open-mesh.org
CC: linux-kernel(a)vger.kernel.org
---
net/batman-adv/originator.c | 29 +++++++++++++++++++++++++++++
net/batman-adv/originator.h | 31 ++-----------------------------
2 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index e4cbb07..bcf78f1 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -47,6 +47,36 @@
/* hash class keys */
static struct lock_class_key batadv_orig_hash_lock_class_key;
+struct batadv_orig_node *
+batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
+{
+ struct batadv_hashtable *hash = bat_priv->orig_hash;
+ struct hlist_head *head;
+ struct batadv_orig_node *orig_node, *orig_node_tmp = NULL;
+ int index;
+
+ if (!hash)
+ return NULL;
+
+ index = batadv_choose_orig(data, hash->size);
+ head = &hash->table[index];
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
+ if (!batadv_compare_eth(orig_node, data))
+ continue;
+
+ if (!kref_get_unless_zero(&orig_node->refcount))
+ continue;
+
+ orig_node_tmp = orig_node;
+ break;
+ }
+ rcu_read_unlock();
+
+ return orig_node_tmp;
+}
+
static void batadv_purge_orig(struct work_struct *work);
/**
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index 4e8b67f..db7a87d 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -96,34 +96,7 @@ static inline u32 batadv_choose_orig(const void *data, u32 size)
return hash % size;
}
-static inline struct batadv_orig_node *
-batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data)
-{
- struct batadv_hashtable *hash = bat_priv->orig_hash;
- struct hlist_head *head;
- struct batadv_orig_node *orig_node, *orig_node_tmp = NULL;
- int index;
-
- if (!hash)
- return NULL;
-
- index = batadv_choose_orig(data, hash->size);
- head = &hash->table[index];
-
- rcu_read_lock();
- hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
- if (!batadv_compare_eth(orig_node, data))
- continue;
-
- if (!kref_get_unless_zero(&orig_node->refcount))
- continue;
-
- orig_node_tmp = orig_node;
- break;
- }
- rcu_read_unlock();
-
- return orig_node_tmp;
-}
+struct batadv_orig_node *
+batadv_orig_hash_find(struct batadv_priv *bat_priv, const void *data);
#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
--
1.8.1.4
5 years, 3 months
[B.A.T.M.A.N.] [PATCH 0/3] batman-adv: Deletion of a few unnecessary checks
by SF Markus Elfring
From: Markus Elfring <elfring(a)users.sourceforge.net>
Date: Tue, 3 Nov 2015 21:34:29 +0100
Further update suggestions were taken into account after a patch
was applied from static source code analysis.
Markus Elfring (3):
Delete an unnecessary check before the function call "batadv_softif_vlan_free_ref"
Split a condition check
Less function calls in batadv_is_ap_isolated() after error detection
net/batman-adv/translation-table.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
--
2.6.2
6 years, 3 months
[B.A.T.M.A.N.] Patch to add mesh_no_rebroadcast
by Ruben Wisniewski
Signed-off-by: Linus Lüssing <linus.luessing(a)web.de>
---
hard-interface.c | 2 ++
send.c | 4 ++++
sysfs-class-net-batman-adv | 10 ++++++++
sysfs.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++
types.h | 1 +
5 files changed, 76 insertions(+)
diff --git a/hard-interface.c b/hard-interface.c
index fbda6b5..3997f9c 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -591,6 +591,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);
diff --git a/send.c b/send.c
index d27161e..4383a66 100644
--- a/send.c
+++ b/send.c
@@ -513,6 +513,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)
diff --git a/sysfs-class-net-batman-adv b/sysfs-class-net-batman-adv
index 7f34a95..cf7fe00 100644
--- a/sysfs-class-net-batman-adv
+++ b/sysfs-class-net-batman-adv
@@ -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(a)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!
diff --git a/sysfs.c b/sysfs.c
index fc47baa..adaeca4 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -110,6 +110,17 @@ struct batadv_attribute batadv_attr_vlan_##_name = { \
.store = _store, \
}
+/* 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 = { \
@@ -221,6 +232,52 @@ ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
batadv_store_vlan_##_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)
@@ -844,10 +901,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,
};
diff --git a/types.h b/types.h
index 8854c05..39619fb 100644
--- a/types.h
+++ b/types.h
@@ -101,6 +101,7 @@ struct batadv_hard_iface {
struct batadv_hard_iface_bat_iv bat_iv;
struct work_struct cleanup_work;
struct dentry *debug_dir;
+ atomic_t no_rebroadcast;
};
/**
--
2.1.3
6 years, 6 months
[B.A.T.M.A.N.] [PATCH 1/2] batman-adv: Fix broadcast+ogm queue purging race condition
by Linus Lüssing
So far on purging broadcast and ogm queues we temporarily give up the
spin lock of these queues to be able to cancel any scheduled forwarding
work. However this is unsafe and can lead to a general protection error
in batadv_purge_outstanding_packets().
With this patch we split the queue purging into two steps: First
removing forward packets from those queues and signaling the
cancelation. Secondly, we are actively canceling any scheduled
forwarding, wait for any running forwarding to finish and only free a
forw_packet afterwards.
Signed-off-by: Linus Lüssing <linus.luessing(a)web.de>
---
Fixes issue #168
send.c | 117 ++++++++++++++++++++++++++++++++++++++-------------------------
types.h | 1 +
2 files changed, 71 insertions(+), 47 deletions(-)
diff --git a/send.c b/send.c
index 0a0bb45..f93476b 100644
--- a/send.c
+++ b/send.c
@@ -245,6 +245,10 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
bat_priv = netdev_priv(soft_iface);
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+ if (hlist_unhashed(&forw_packet->list)) {
+ spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
+ return;
+ }
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
@@ -293,6 +297,10 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
delayed_work);
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ if (hlist_unhashed(&forw_packet->list)) {
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+ return;
+ }
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
@@ -316,13 +324,68 @@ out:
batadv_forw_packet_free(forw_packet);
}
+/**
+ * batadv_cancel_packets - Cancels a list of forward packets
+ * @forw_list: The to be canceled forward packets
+ * @canceled_list: The backup list.
+ *
+ * This canceles any scheduled forwarding packet tasks in the provided
+ * forw_list. The packets are being moved from the forw_list to the
+ * canceled_list afterwards to unhash the forward packet list pointer,
+ * allowing any already running task to notice the cancelation.
+ */
+static void batadv_cancel_packets(struct hlist_head *forw_list,
+ struct hlist_head *canceled_list,
+ const struct batadv_hard_iface *hard_iface)
+{
+ struct batadv_forw_packet *forw_packet;
+ struct hlist_node *tmp_node, *safe_tmp_node;
+
+ hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
+ forw_list, list) {
+ /* if purge_outstanding_packets() was called with an argument
+ * we delete only packets belonging to the given interface
+ */
+ if ((hard_iface) &&
+ (forw_packet->if_incoming != hard_iface))
+ continue;
+
+ hlist_del_init(&forw_packet->list);
+ hlist_add_head(&forw_packet->canceled_list, canceled_list);
+ }
+}
+
+/**
+ * batadv_canceled_packets_free - Frees canceled forward packets
+ * @head: A list of to be freed forw_packets
+ *
+ * This function canceles the scheduling of any packet in the provided list,
+ * waits for any possibly running packet forwarding thread to finish and
+ * finally, safely frees this forward packet.
+ *
+ * This function might sleep.
+ */
+static void batadv_canceled_packets_free(struct hlist_head *head)
+{
+ struct batadv_forw_packet *forw_packet;
+ struct hlist_node *tmp_node, *safe_tmp_node;
+
+ hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, head,
+ canceled_list) {
+ cancel_delayed_work_sync(&forw_packet->delayed_work);
+
+ hlist_del(&forw_packet->canceled_list);
+ batadv_forw_packet_free(forw_packet);
+ }
+}
+
void
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
const struct batadv_hard_iface *hard_iface)
{
- struct batadv_forw_packet *forw_packet;
- struct hlist_node *tmp_node, *safe_tmp_node;
- bool pending;
+ struct hlist_head head;
+
+ INIT_HLIST_HEAD(&head);
if (hard_iface)
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -334,53 +397,13 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
/* free bcast list */
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
- hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
- &bat_priv->forw_bcast_list, list) {
- /* if purge_outstanding_packets() was called with an argument
- * we delete only packets belonging to the given interface
- */
- if ((hard_iface) &&
- (forw_packet->if_incoming != hard_iface))
- continue;
-
- spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
-
- /* batadv_send_outstanding_bcast_packet() will lock the list to
- * delete the item from the list
- */
- pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock_bh(&bat_priv->forw_bcast_list_lock);
-
- if (pending) {
- hlist_del(&forw_packet->list);
- batadv_forw_packet_free(forw_packet);
- }
- }
+ batadv_cancel_packets(&bat_priv->forw_bcast_list, &head, hard_iface);
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
/* free batman packet list */
spin_lock_bh(&bat_priv->forw_bat_list_lock);
- hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
- &bat_priv->forw_bat_list, list) {
- /* if purge_outstanding_packets() was called with an argument
- * we delete only packets belonging to the given interface
- */
- if ((hard_iface) &&
- (forw_packet->if_incoming != hard_iface))
- continue;
-
- spin_unlock_bh(&bat_priv->forw_bat_list_lock);
-
- /* send_outstanding_bat_packet() will lock the list to
- * delete the item from the list
- */
- pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
- spin_lock_bh(&bat_priv->forw_bat_list_lock);
-
- if (pending) {
- hlist_del(&forw_packet->list);
- batadv_forw_packet_free(forw_packet);
- }
- }
+ batadv_cancel_packets(&bat_priv->forw_bat_list, &head, hard_iface);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
+ batadv_canceled_packets_free(&head);
}
diff --git a/types.h b/types.h
index aba8364..f62a35f 100644
--- a/types.h
+++ b/types.h
@@ -853,6 +853,7 @@ struct batadv_skb_cb {
*/
struct batadv_forw_packet {
struct hlist_node list;
+ struct hlist_node canceled_list;
unsigned long send_time;
uint8_t own;
struct sk_buff *skb;
--
1.7.10.4
6 years, 6 months
[B.A.T.M.A.N.] [PATCH v2 0/2] netns support for alfred
by Andrew Lunn
Dropped patch #1, since it has been merged
Fixed the socket leak
Removed redundant calls to mount debugfs
Andrew Lunn (2):
alfred: Add support for network namespaces
alfred: Mount debugfs before reducing capabilities
batadv_query.c | 19 +------------------
debugfs.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
main.c | 4 ++++
vis/vis.h | 2 +-
4 files changed, 54 insertions(+), 20 deletions(-)
--
2.7.0.rc3
6 years, 8 months
[B.A.T.M.A.N.] [PATCH v3] batman-adv: use static string for table headers
by Sven Eckelmann
From: Antonio Quartulli <a(a)unstable.cc>
Use a static string when showing table headers rather then
a nonsense parametric one with fixed arguments.
It is easier to grep and it does not need to be recomputed
at runtime each time.
Reported-by: Joe Perches <joe(a)perches.com>
Signed-off-by: Antonio Quartulli <a(a)unstable.cc>
[sven(a)narfation.org: fix conflicts with current version]
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
v3:
- workaround checkpatch error (over 80 chars) caused by __stringify
v2:
- rebased patch
- added new static strings in bat_v.c and bat_iv_ogm.c
Patch was resurrected from https://patchwork.open-mesh.org/patch/3599/
I've requested an rebased version at
https://lists.open-mesh.org/pipermail/b.a.t.m.a.n/2016-March/014637.html
but done it myself because it was rather trivial.
---
net/batman-adv/bat_iv_ogm.c | 8 +++-----
net/batman-adv/bat_v.c | 9 ++++-----
net/batman-adv/bridge_loop_avoidance.c | 7 +++----
net/batman-adv/distributed-arp-table.c | 4 ++--
net/batman-adv/translation-table.c | 9 ++++-----
5 files changed, 16 insertions(+), 21 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 2c65668..d9a826a 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -1866,9 +1866,8 @@ static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
int batman_count = 0;
u32 i;
- seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
- "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE,
- "Nexthop", "outgoingIF", "Potential nexthops");
+ seq_puts(seq,
+ " Originator last-seen (#/255) Nexthop [outgoingIF]: Potential nexthops ...\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1948,8 +1947,7 @@ static void batadv_iv_neigh_print(struct batadv_priv *bat_priv,
struct batadv_hard_iface *hard_iface;
int batman_count = 0;
- seq_printf(seq, " %10s %-13s %s\n",
- "IF", "Neighbor", "last-seen");
+ seq_puts(seq, " IF Neighbor last-seen\n");
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 3315b9a..246f9e9 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -151,8 +151,8 @@ static void batadv_v_neigh_print(struct batadv_priv *bat_priv,
struct batadv_hard_iface *hard_iface;
int batman_count = 0;
- seq_printf(seq, " %-15s %s (%11s) [%10s]\n", "Neighbor",
- "last-seen", "throughput", "IF");
+ seq_puts(seq,
+ " Neighbor last-seen ( throughput) [ IF]\n");
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
@@ -191,9 +191,8 @@ static void batadv_v_orig_print(struct batadv_priv *bat_priv,
int batman_count = 0;
u32 i;
- seq_printf(seq, " %-15s %s (%11s) %17s [%10s]: %20s ...\n",
- "Originator", "last-seen", "throughput", "Nexthop",
- "outgoingIF", "Potential nexthops");
+ seq_puts(seq,
+ " Originator last-seen ( throughput) Nexthop [outgoingIF]: Potential nexthops ...\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 642167f..0c951a7 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1816,8 +1816,8 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
"Claims announced for the mesh %s (orig %pM, group id %#.4x)\n",
net_dev->name, primary_addr,
ntohs(bat_priv->bla.claim_dest.group));
- seq_printf(seq, " %-17s %-5s %-17s [o] (%-6s)\n",
- "Client", "VID", "Originator", "CRC");
+ seq_puts(seq,
+ " Client VID Originator [o] (CRC )\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1874,8 +1874,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
"Backbones announced for the mesh %s (orig %pM, group id %#.4x)\n",
net_dev->name, primary_addr,
ntohs(bat_priv->bla.claim_dest.group));
- seq_printf(seq, " %-17s %-5s %-9s (%-6s)\n",
- "Originator", "VID", "last seen", "CRC");
+ seq_puts(seq, " Originator VID last seen (CRC )\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 919a8d2..771708c 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -814,8 +814,8 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset)
goto out;
seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name);
- seq_printf(seq, " %-7s %-9s %4s %11s\n", "IPv4",
- "MAC", "VID", "last-seen");
+ seq_puts(seq,
+ " IPv4 MAC VID last-seen\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 2ed55f4..d7f37e5 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1008,8 +1008,8 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq,
"Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
net_dev->name, (u8)atomic_read(&bat_priv->tt.vn));
- seq_printf(seq, " %-13s %s %-8s %-9s (%-10s)\n", "Client", "VID",
- "Flags", "Last seen", "CRC");
+ seq_puts(seq,
+ " Client VID Flags Last seen (CRC )\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -1706,9 +1706,8 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq,
"Globally announced TT entries received via the mesh %s\n",
net_dev->name);
- seq_printf(seq, " %-13s %s %s %-15s %s (%-10s) %s\n",
- "Client", "VID", "(TTVN)", "Originator", "(Curr TTVN)",
- "CRC", "Flags");
+ seq_puts(seq,
+ " Client VID (TTVN) Originator (Curr TTVN) (CRC ) Flags\n");
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
--
2.7.0
6 years, 9 months
[B.A.T.M.A.N.] [PATCHv13 0/4] Multicast optimizations for bridges
by Linus Lüssing
This patchset enables the usage of the batman-adv multicast optimizations
for scenarios involving bridges on top of e.g. bat0, too.
The first one alters the forwarding behaviour for IGMP and MLD reports
which is a prerequisite before enabling multicast optimizations in
bridged setups. It also increases the MCAST TVLV version number to 2.
More on the issue of insufficient report handling with the v1
MCAST TVLV can be found here:
http://www.open-mesh.org/projects/batman-adv/wiki/Multicast-optimizations...
The second patch finally enables the multicast optimizations for
bridged setups.
Along come two more patches adding according debugging facilities
to make it possible for the user to check why the multicast
optimizations might not work ideally to give hints about
what they might change about their topology.
This patchset can be found in the current linus/multicast-bridge
branch.
Cheers, Linus
-----
Changes in v13:
* Substituted a non-breaking space with a boring one
* Dropped compat code for kernels < 3.2
* Removed mcast tvlv container and handler support for v1 completely
* Rebase to current master branch
(automatic 3-way merge without issues)
Changes in v12:
* Rebase to current master branch
(automatic 3-way merge, then batadv_hardif_free_ref() -> batadv_hardif_put())
* Adding Linux upstream fix to compat-sources/net/core/skbuff.c
-> "net: fix bridge multicast packet checksum validation"
(9b368814b33, present since v4.5, queued for stable)
Changes in v11:
* Rewording of commit messages (PATCH 1/4+2/4)
* Rebasing to master (solving conflict with kernel doc "return" changes)
* Updating kerneldoc to proper "Return:" syntax
* Using eth_zero_addr() over memset (fixes a new checkpatch warning)
* Changing uint8_t to u8 and uint32_t to u32 (fixes new checkpatch warnings)
* Turning some batadv_dbg() into batadv_info(), making querier presence more
visible (i.e. in dmesg too) (PATCH 3/4)
Changes in v10:
- PATCH 1/4:
* Former "[PATCH 4/4] batman-adv: Forward IGMP/MLD reports to selected querier (only)"
substituted by the interim branch "batman-adv: Always flood IGMP/MLD reports"
with the following changes:
* Increased compatibility to mcast-v1-tvlv nodes by
registering a v1 tvlv container and handler, too
(note: PATCH 2/4 needs to still unregister the handler
if the node is bridged bc. it can't "trust" v1 nodes)
* Removed skb_set_network_header() call
(extra patch pending for review for maint)
* Compared to patchset v9 this substitution makes things
compilable again for kernels < 2.6.35
- PATCH 2/4:
* Moved enum introduction of BATADV_DBG_MCAST to PATCH 3/4,
not needed in PATCH 2/4 yet
* Adjusted compat code to new compat layout
* Adjustments to batadv_mcast_mla_tvlv_update() to fit now
preceding PATCH 1/4
* bat_priv->mcast.bridged flag already introduced here
(instead of in PATCH 3/4) because we need it for the new
mcast-v1-tvlv handling
---
Interim Changlog of
"batman-adv: Always flood IGMP/MLD reports"
v1:
* Removed query snooping and state
* Squashed all three patches into one
* Renamed "batadv_mcast_tvlv_ogm_handler_v1()" to *_v2()
* Added explicit icmpv6.h include
* Rebased on top of master
-----
Interim Interim Changelog of
"batman-adv: Unicasting multicast reports to querier-node only"
v6:
* compat: copied copyright headers from original upstream c files
* compat: unified ordering in compat c files:
-> copyright header, then includes, then kernel specific functions
v5:
* Removed RFC tag: Needed exports got merged to net-next and are going to
be available with Linux 4.2
* Redid compat solution - now fully backwards compatible down to 2.6.33
v4:
* excluded bridge part from this patchset, they should
hopefully be added to net-next soon
* Added a compat solution (PATCH 3/3)
* Removed Kconfig-depends as by David's suggestion the needed parsing
functions for MLD are going to be forced built-ins even if IPv6 is
going to be built as a module
* Removed unused variable 'int ret' in batadv_mcast_is_report_ipv6()
* Adjusted to new folder structure
v3:
* Adding Kconfig-depends and #if's
(so basically adding similar dependancy constraints as the bridge code
has, except that there are no depends if batman-adv gets compiled without
multicast optimizations)
-> the case of IPv6=M and batman-adv=y is still impossible if multicast
optimizations are enabled; but I don't see the practical demand for that
either - people who use IPv6 as a module will probably also want to
use batman-adv as a module
v2:
* various bugfixes (now runtime tested, too - should(tm) work)
* added netdev+bridge mailinglists
-----
---
Changes in v9:
- PATCH 1/4:
* fix: added compat code for pr_warn_once()
* compat fix for bridge export stubs: fixes compile error
with kernels < 3.16 without bridge (snooping) support
- PATCH 2/4:
* perform updates of variables within bat_priv->mcast.querier_ipv{4,6}
individually (there's a new, third member in 4/4 which shouldn't be
overriden)
* PATCH 4/4: NEW
Changes in v8 (thanks to Simon's suggestions):
- PATCH 2/3:
* print shadowing status log of an appearing and shadowing querier, too
(the bridge-querier-existence call has an additional 10s delay
to ensure reports had their time to arrive -
the bridge-querier-port call doesn't have that)
- PATCH 3/3:
* changing debugfs output from "+" and "-" to "U/4/6" and "."
* fixing "no querier present" logic (introduced in [PATCHv7 3/3])
Changes in v7 (thanks to Simon's suggestions):
- PATCH 2/3:
* renaming old/new_querier to old/new_state
* slightly extended kerneldoc of batadv_mcast_querier_log()
* removing words "good" and "bad" from debug output
* simplified batadv_mcast_flags_log()
* assignment instead of memset in batadv_mcast_mla_tvlv_update()
and batadv_softif_init_late()
* simple struct member assignments instead of one complex struct
assigment
* removing unnecessary memcmp's
* substituting return statement for an if-block in
batadv_mcast_querier_log() and batadv_mcast_bridge_log()
* print "Unsnoopables(U)-flag" instead of just "U-flag"
- PATCH 3/3:
* use bat_priv values instead of querying bridge ABI in
batadv_mcast_flags_print_header()
Changes in v6:
* New PATCH 2/3 inserted, moving logging to separate patch
* More verbose logging added to PATCH 2/3:
Bridge and querier state changes are logged too
* upper case to lower case for kernel doc of batadv_mcast_flags_open
(PATCH 2/3)
* Adding note to kernel doc of batadv_mcast_get_bridge about
increased refcount (PATCH 1/3)
* Printing some lines about current bridge and querier state to
debugfs too (PATCH 3/3)
Changes in v5 (PATCH 2/2 only):
* s/dat_cache/mcast_flags/ in kerneldoc (copy&paste error)
Changes in v4 (PATCH 2/2 only):
* initial {ad,e}dition of this patch
Changes in v3 (PATCH 1/2 only):
* Removed "RFC" tag in title again: The stubs and new export are upstream
in net-next and therefore going to be included in 3.17
* Added some debug output:
* Two warning messages:
-> Old kernel version or no bridge IGMP/MLD snooping compiled
* New batman-adv log-level "mcast":
-> Logging mcast flag changes
(a third debugging facility, a new table for debugfs for a global
mcast flag overview will be added in a separate patch later
as discussed with Simon)
Changes in v2 (PATCH 1/2 only):
* fetching local (= on this same kernel) multicast listeners from
the bridge instead of the bat0 interface if a bridge is present
- just like ip addresses and routes should be used from br0, the
same goes for multicast listeners
* beautification of batadv_mcast_mla_br_addr_cpy(), now using already
present functions from the kernel instead of own, hackish approach
* changed names of some goto-labels (not using "skip" anymore)
* using new, third bridge multicast export (because this export is
not upstream yet, I've added the "RFC" in the title):
br_multicast_has_querier_anywhere()
* adding compat stubs for two bridge multicast exports, to make
batman-adv compile- and usable even if a 3.16 kernel was compiled
without bridge code - the stubs are supposed to be upstream in the
bridge code in 3.17 (therefore just 'compat')
* updated kerneldocs for batadv_mcast_mla_bridge_get() and
batadv_mcast_mla_softif_get()
* The two sentences in the commit message starting with "Queriers: ..."
were slightly modified to include the third bridge multicast export
6 years, 9 months
[B.A.T.M.A.N.] pull request [net]: batman-adv 20160430
by Antonio Quartulli
Hello David,
this is another pull request intended for net.
I know that I sent another batch a few days ago, but after having gone
through my queue I thought that merging these last 4 patches would still
be worth it (there won't be any other pull request for linux-4.6 :)).
The description of the changes follows below.
Please pull or let me know of any issue!
Thanks a lot,
Antonio
The following changes since commit 1dfcd832b1a9ed45edac15b31d079b805fa0ae2a:
Merge branch 'bpf-fixes' (2016-04-28 17:29:46 -0400)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-fix-for-davem
for you to fetch changes up to abe59c65225ccd63a5964e2f2a73dd2995b948e7:
batman-adv: Fix reference counting of hardif_neigh_node object for neigh_node (2016-04-29 19:46:11 +0800)
----------------------------------------------------------------
In this small batch of patches you have:
- a fix for our Distributed ARP Table that makes sure that the input
provided to the hash function during a query is the same as the one
provided during an insert (so to prevent false negatives), by Antonio
Quartulli
- a fix for our new protocol implementation B.A.T.M.A.N. V that ensures
that a hard interface is properly re-activated when it is brought down
and then up again, by Antonio Quartulli
- two fixes respectively to the reference counting of the tt_local_entry
and neigh_node objects, by Sven Eckelmann. Such bug is rather severe
as it would prevent the netdev objects references by batman-adv from
being released after shutdown.
----------------------------------------------------------------
Antonio Quartulli (2):
batman-adv: fix DAT candidate selection (must use vid)
batman-adv: B.A.T.M.A.N V - make sure iface is reactivated upon NETDEV_UP event
Sven Eckelmann (2):
batman-adv: Fix reference counting of vlan object for tt_local_entry
batman-adv: Fix reference counting of hardif_neigh_node object for neigh_node
net/batman-adv/bat_v.c | 12 ++++++++++
net/batman-adv/distributed-arp-table.c | 17 ++++++++------
net/batman-adv/hard-interface.c | 3 +++
net/batman-adv/originator.c | 16 ++++---------
net/batman-adv/translation-table.c | 42 ++++------------------------------
net/batman-adv/types.h | 7 ++++++
6 files changed, 41 insertions(+), 56 deletions(-)
6 years, 9 months
[B.A.T.M.A.N.] [PATCH v2 1/3] batman-adv: return netdev status in the TX path
by Sven Eckelmann
From: Antonio Quartulli <antonio.quartulli(a)open-mesh.com>
Return the proper netdev TX status along the TX path so that the tp_meter
can understand when the queue is full and should stop sending packets.
Signed-off-by: Antonio Quartulli <antonio.quartulli(a)open-mesh.com>
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)open-mesh.com>
---
v2:
- Rebase on current master version
net/batman-adv/fragmentation.c | 41 +++++++++++++++++++++++++----------------
net/batman-adv/fragmentation.h | 6 +++---
net/batman-adv/main.c | 4 +++-
net/batman-adv/routing.c | 24 ++++++++++++++----------
net/batman-adv/send.c | 25 +++++++++++++------------
5 files changed, 58 insertions(+), 42 deletions(-)
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 65536db..4cb7da2 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -434,11 +434,12 @@ err:
* @orig_node: final destination of the created fragments
* @neigh_node: next-hop of the created fragments
*
- * Return: true on success, false otherwise.
+ * Return: the netdev tx status or -1 in case of error.
+ * When -1 is returned the skb is not consumed.
*/
-bool batadv_frag_send_packet(struct sk_buff *skb,
- struct batadv_orig_node *orig_node,
- struct batadv_neigh_node *neigh_node)
+int batadv_frag_send_packet(struct sk_buff *skb,
+ struct batadv_orig_node *orig_node,
+ struct batadv_neigh_node *neigh_node)
{
struct batadv_priv *bat_priv;
struct batadv_hard_iface *primary_if = NULL;
@@ -447,7 +448,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
unsigned int header_size = sizeof(frag_header);
unsigned int max_fragment_size, max_packet_size;
- bool ret = false;
+ int ret = -1;
/* To avoid merge and refragmentation at next-hops we never send
* fragments larger than BATADV_FRAG_MAX_FRAG_SIZE
@@ -458,12 +459,12 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
/* Don't even try to fragment, if we need more than 16 fragments */
if (skb->len > max_packet_size)
- goto out_err;
+ goto out;
bat_priv = orig_node->bat_priv;
primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
- goto out_err;
+ goto out;
/* Create one header to be copied to all fragments */
frag_header.packet_type = BATADV_UNICAST_FRAG;
@@ -480,23 +481,33 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
while (skb->len > max_fragment_size) {
skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
if (!skb_fragment)
- goto out_err;
+ goto out;
batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
skb_fragment->len + ETH_HLEN);
- batadv_send_unicast_skb(skb_fragment, neigh_node);
+ ret = batadv_send_unicast_skb(skb_fragment, neigh_node);
+ if (ret != NET_XMIT_SUCCESS) {
+ /* return -1 so that the caller can free the original
+ * skb
+ */
+ ret = -1;
+ goto out;
+ }
+
frag_header.no++;
/* The initial check in this function should cover this case */
- if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1)
- goto out_err;
+ if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
+ ret = -1;
+ goto out;
+ }
}
/* Make room for the fragment header. */
if (batadv_skb_head_push(skb, header_size) < 0 ||
pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0)
- goto out_err;
+ goto out;
memcpy(skb->data, &frag_header, header_size);
@@ -504,11 +515,9 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
skb->len + ETH_HLEN);
- batadv_send_unicast_skb(skb, neigh_node);
+ ret = batadv_send_unicast_skb(skb, neigh_node);
- ret = true;
-
-out_err:
+out:
if (primary_if)
batadv_hardif_put(primary_if);
diff --git a/net/batman-adv/fragmentation.h b/net/batman-adv/fragmentation.h
index 9ff77c7..3202fe3 100644
--- a/net/batman-adv/fragmentation.h
+++ b/net/batman-adv/fragmentation.h
@@ -34,9 +34,9 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
struct batadv_orig_node *orig_node_src);
bool batadv_frag_skb_buffer(struct sk_buff **skb,
struct batadv_orig_node *orig_node);
-bool batadv_frag_send_packet(struct sk_buff *skb,
- struct batadv_orig_node *orig_node,
- struct batadv_neigh_node *neigh_node);
+int batadv_frag_send_packet(struct sk_buff *skb,
+ struct batadv_orig_node *orig_node,
+ struct batadv_neigh_node *neigh_node);
/**
* batadv_frag_check_entry - check if a list of fragments has timed out
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index c8d8bc7..fff51ad 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -1195,6 +1195,7 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src,
unsigned char *tvlv_buff;
unsigned int tvlv_len;
ssize_t hdr_len = sizeof(*unicast_tvlv_packet);
+ int res;
orig_node = batadv_orig_hash_find(bat_priv, dst);
if (!orig_node)
@@ -1227,7 +1228,8 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src,
tvlv_buff += sizeof(*tvlv_hdr);
memcpy(tvlv_buff, tvlv_value, tvlv_value_len);
- if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP)
+ res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+ if (!(res != -1 && dev_xmit_complete(res)))
kfree_skb(skb);
out:
batadv_orig_node_put(orig_node);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 94b4356..fb0e5d6 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -268,7 +268,10 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
icmph->ttl = BATADV_TTL;
res = batadv_send_skb_to_orig(skb, orig_node, NULL);
- if (res != NET_XMIT_DROP)
+ if (res == -1)
+ goto out;
+
+ if (dev_xmit_complete(res))
ret = NET_RX_SUCCESS;
break;
@@ -290,7 +293,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
struct batadv_hard_iface *primary_if = NULL;
struct batadv_orig_node *orig_node = NULL;
struct batadv_icmp_packet *icmp_packet;
- int ret = NET_RX_DROP;
+ int res, ret = NET_RX_DROP;
icmp_packet = (struct batadv_icmp_packet *)skb->data;
@@ -321,7 +324,8 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
icmp_packet->ttl = BATADV_TTL;
- if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
+ res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+ if (res != -1 && dev_xmit_complete(res))
ret = NET_RX_SUCCESS;
out:
@@ -341,7 +345,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
struct ethhdr *ethhdr;
struct batadv_orig_node *orig_node = NULL;
int hdr_size = sizeof(struct batadv_icmp_header);
- int ret = NET_RX_DROP;
+ int res, ret = NET_RX_DROP;
/* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb, hdr_size)))
@@ -407,7 +411,8 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
icmph->ttl--;
/* route it */
- if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
+ res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
+ if (res != -1 && dev_xmit_complete(res))
ret = NET_RX_SUCCESS;
out:
@@ -642,6 +647,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
batadv_skb_set_priority(skb, hdr_len);
res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
+ if (res == -1)
+ goto out;
/* translate transmit result into receive result */
if (res == NET_XMIT_SUCCESS) {
@@ -649,12 +656,9 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
skb->len + ETH_HLEN);
-
- ret = NET_RX_SUCCESS;
- } else if (res == NET_XMIT_POLICED) {
- /* skb was buffered and consumed */
- ret = NET_RX_SUCCESS;
}
+ if (dev_xmit_complete(res))
+ ret = NET_RX_SUCCESS;
out:
if (orig_node)
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 724bd6e..d2713ca 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -155,8 +155,11 @@ int batadv_send_unicast_skb(struct sk_buff *skb,
* host, NULL can be passed as recv_if and no interface alternating is
* attempted.
*
- * Return: NET_XMIT_SUCCESS on success, NET_XMIT_DROP on failure, or
- * NET_XMIT_POLICED if the skb is buffered for later transmit.
+ * Return: -1 on failure (and the skb is not consumed), NET_XMIT_POLICED if the
+ * skb is buffered for later transmit or the NET_XMIT status returned by the
+ * lower routine if the packet has been passed down.
+ *
+ * If the returning value is not -1 the skb has been consumed.
*/
int batadv_send_skb_to_orig(struct sk_buff *skb,
struct batadv_orig_node *orig_node,
@@ -164,7 +167,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
{
struct batadv_priv *bat_priv = orig_node->bat_priv;
struct batadv_neigh_node *neigh_node;
- int ret = NET_XMIT_DROP;
+ int ret = -1;
/* batadv_find_router() increases neigh_nodes refcount if found. */
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
@@ -177,8 +180,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
if (atomic_read(&bat_priv->fragmentation) &&
skb->len > neigh_node->if_incoming->net_dev->mtu) {
/* Fragment and send packet. */
- if (batadv_frag_send_packet(skb, orig_node, neigh_node))
- ret = NET_XMIT_SUCCESS;
+ ret = batadv_frag_send_packet(skb, orig_node, neigh_node);
goto out;
}
@@ -187,12 +189,10 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
* (i.e. being forwarded). If the packet originates from this node or if
* network coding fails, then send the packet as usual.
*/
- if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) {
+ if (recv_if && batadv_nc_skb_forward(skb, neigh_node))
ret = NET_XMIT_POLICED;
- } else {
- batadv_send_unicast_skb(skb, neigh_node);
- ret = NET_XMIT_SUCCESS;
- }
+ else
+ ret = batadv_send_unicast_skb(skb, neigh_node);
out:
if (neigh_node)
@@ -318,7 +318,7 @@ int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
{
struct batadv_unicast_packet *unicast_packet;
struct ethhdr *ethhdr;
- int ret = NET_XMIT_DROP;
+ int res, ret = NET_XMIT_DROP;
if (!orig_node)
goto out;
@@ -355,7 +355,8 @@ int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
unicast_packet->ttvn = unicast_packet->ttvn - 1;
- if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
+ res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+ if (res != -1 && dev_xmit_complete(res))
ret = NET_XMIT_SUCCESS;
out:
--
2.8.0.rc3
6 years, 9 months