Hi,
this patchset is about cleaning up the pskb_may_pull(skb, hdr_size) in
batadv_interface_rx. This was pointed out by Marek while he checked the
"pskb_may_pull(skb, ETH_HLEN)"/"pskb_may_pull(skb, VLAN_ETH_HLEN)" fix [1].
This patchset *does not* replace the other fix.
The patchset contains three patches because:
* first one is there to make clear that batadv_interface_rx is not
responsible for checking hdr_size
* second one is a bonus. Just noticed this useless parameter while writing
the kernel-doc
* the last patch then really removes this extra check.
Kind regards,
Sven
[1] https://patchwork.open-mesh.org/patch/15853/
The encapsulated ethernet and VLAN header may be outside the received
ethernet frame. Thus the skb buffer size has to be checked before it can be
parsed to find out if it encapsulates another batman-adv packet.
Fixes: 48628bb9419f ("batman-adv: softif bridge loop avoidance")
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
net/batman-adv/soft-interface.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 0710379..8a136b6 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface,
*/
nf_reset(skb);
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ goto dropped;
+
vid = batadv_get_vid(skb, 0);
ethhdr = eth_hdr(skb);
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q:
+ if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
+ goto dropped;
+
vhdr = (struct vlan_ethhdr *)skb->data;
if (vhdr->h_vlan_encapsulated_proto != ethertype)
@@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface,
}
/* skb->dev & skb->pkt_type are set here */
- if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
- goto dropped;
skb->protocol = eth_type_trans(skb, soft_iface);
/* should not be necessary anymore as we use skb_pull_rcsum()
--
2.7.0
When running within a network namespace, access to files within
debugfs have to take into account the network name space. Each
namespace has its own directory under
/sys/kernel/debug/batman_adv/netns.
Add example how this can be used in the README.
Signed-off-by: Andrew Lunn <andrew(a)lunn.ch>
---
v2: README additions
---
README | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
debug.h | 2 +-
debugfs.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/README b/README
index f87c551..431c62e 100644
--- a/README
+++ b/README
@@ -520,3 +520,61 @@ where:
- IPv4 is the IP address of a client in the mesh network
- MAC is the MAC address associated to that IP
- last-seen is the amount of time since last refresh of this entry
+
+batctl and network name spaces
+==============================
+
+The batman-adv kernel module is netns aware. Mesh instances can be
+created in name spaces, and interfaces in that name space added to the
+mesh. The mesh interface cannot be moved between name spaces, as is
+typical for virtual interfaces.
+
+The following example creates two network namespaces, and uses veth
+pairs to connect them together into a mesh of three nodes.
+
+EMU1="ip netns exec emu1"
+EMU2="ip netns exec emu2"
+
+ip netns add emu1
+ip netns add emu2
+
+ip link add emu1-veth1 type veth peer name emu2-veth1
+ip link set emu1-veth1 netns emu1
+ip link set emu2-veth1 netns emu2
+
+$EMU1 ip link set emu1-veth1 name veth1
+$EMU2 ip link set emu2-veth1 name veth1
+
+$EMU1 ip link set veth1 up
+$EMU2 ip link set veth1 up
+
+ip link add emu1-veth2 type veth peer name veth2
+ip link set emu1-veth2 netns emu1
+$EMU1 ip link set emu1-veth2 name veth2
+
+$EMU1 ip link set veth2 up
+ip link set veth2 up
+
+$EMU1 batctl if add veth1
+$EMU1 batctl if add veth2
+$EMU1 ip link set bat0 up
+
+$EMU2 batctl if add veth1
+$EMU2 ip link set bat0 up
+
+batctl if add veth2
+ip link set bat0 up
+
+alfred and batadv-vis can also be used with name spaces. In this
+example, only netns has been used, so there are no filesystem name
+spaces. Hence the unix domain socket used by alfred needs to be given
+a unique name per instance.
+
+($EMU1 alfred -m -i bat0 -u /var/run/emu1-alfred.soc) &
+($EMU2 alfred -m -i bat0 -u /var/run/emu2-alfred.soc) &
+alfred -m -i bat0 &
+
+($EMU1 batadv-vis -s -u /var/run/emu1-alfred.soc) &
+($EMU2 batadv-vis -s -u /var/run/emu2-alfred.soc) &
+batadv-vis -s &
+
diff --git a/debug.h b/debug.h
index df65f50..ac7a97b 100644
--- a/debug.h
+++ b/debug.h
@@ -25,7 +25,7 @@
#include <stddef.h>
#include "main.h"
-#define DEBUG_BATIF_PATH_FMT "%s/batman_adv/%s"
+#define DEBUG_BATIF_PATH_FMT "%s/batman_adv/%s%s"
#define DEBUG_TRANSTABLE_GLOBAL "transtable_global"
#define DEBUG_LOG "log"
#define DEBUG_ROUTING_ALGOS "routing_algos"
diff --git a/debugfs.c b/debugfs.c
index 3c58195..a66dbdd 100644
--- a/debugfs.c
+++ b/debugfs.c
@@ -20,11 +20,15 @@
#include "debugfs.h"
#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statfs.h>
+#include <sys/types.h>
+#include <unistd.h>
#ifndef DEBUGFS_MAGIC
#define DEBUGFS_MAGIC 0x64626720
@@ -39,15 +43,58 @@ static const char *debugfs_known_mountpoints[] = {
NULL,
};
+/* Return the current net namespace number. 0 is never a valid
+ * namespace, so use it to return that there is no name space
+ * support.
+ */
+
+static unsigned int debugfs_get_netns_inum(void)
+{
+ char net_path[] = "/proc/self/ns/net";
+ struct stat netst;
+ int netns;
+
+ netns = open(net_path, O_RDONLY);
+ if (netns < 0) {
+ if (errno == ENOENT)
+ /* Probably means no netns support in the kernel */
+ return 0;
+
+ fprintf(stderr,
+ "Error - can't open /proc/self/ns/net for read: %s\n",
+ strerror(errno));
+ return 0;
+ }
+
+ if (fstat(netns, &netst) < 0) {
+ fprintf(stderr, "Stat of netns failed: %s\n",
+ strerror(errno));
+ return 0;
+ }
+ close (netns);
+
+ return netst.st_ino;
+}
+
/* construct a full path to a debugfs element */
int debugfs_make_path(const char *fmt, char *mesh_iface, char *buffer, int size)
{
+ unsigned int ns = debugfs_get_netns_inum();
+ char ns_dir[PATH_MAX];
+
if (strlen(debugfs_mountpoint) == 0) {
buffer[0] = '\0';
return -1;
}
- return snprintf(buffer, size, fmt, debugfs_mountpoint, mesh_iface);
+ if (ns) {
+ snprintf(ns_dir, PATH_MAX, "netns/%u/", ns);
+ return snprintf(buffer, size, fmt, debugfs_mountpoint, ns_dir,
+ mesh_iface);
+ } else {
+ return snprintf(buffer, size, fmt, debugfs_mountpoint, "",
+ mesh_iface);
+ }
}
static int debugfs_found;
--
2.7.0.rc3
Hi,
This patchset makes batman-adv network namespace aware. A soft
interface can be creates in a namespace and hard interfaces added to
it. soft interfaces cannot be moved between name spaces.
The biggest change is to debugfs, which is not natively netns aware,
unlike sysfs which is. A new netns directory has been added and within
that, a directory per network name space which batman is used within.
The changes are backwards compatible, in that interfaces in the global
namespace are not placed into a subdirectory.
v3:
- Added new system to add patches to the build (in case the build against an
older kernel is not possible otherwise)
- Rearranged the retrieval of the link netns
- Rearranged the retrieval netns id for debugfs
- Fix header includes
- Add compat-include for linux/ns_common.h
- Add compat-patch for netdev->rtnl_link_ops->get_link_net
- Add compat-patch for net->ns.inum
- Fix alignment errors
Kind regards,
Sven
This patch adds the multicast debug level to check for own
multicast flag changes for instance.
Signed-off-by: Linus Lüssing <linus.luessing(a)web.de>
---
Changes in v3:
* none
Changes in v2:
* added a sentence about 'mcast' log level to manpage
README | 1 +
man/batctl.8 | 6 +++---
sys.c | 5 +++++
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/README b/README
index b5fd259..c5e3575 100644
--- a/README
+++ b/README
@@ -389,6 +389,7 @@ $ batctl loglevel
[ ] messages related to bridge loop avoidance (bla)
[ ] messages related to arp snooping and distributed arp table (dat)
[ ] messages related to network coding (nc)
+[ ] messages related to multicast (mcast)
batctl nc_nodes
===============
diff --git a/man/batctl.8 b/man/batctl.8
index 110020e..66c28bb 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -98,9 +98,9 @@ level. Level 'none' disables all verbose logging. Level 'batman' enables message
Level 'routes' enables messages related to routes being added / changed / deleted. Level 'tt' enables messages related to
translation table operations. Level 'bla' enables messages related to the bridge loop avoidance. Level 'dat' enables
messages related to ARP snooping and the Distributed Arp Table. Level 'nc' enables messages related to network coding.
-Level 'all' enables all messages. The messages are sent to the batman-adv debug log. Use \fBbatctl log\fP to retrieve it.
-Make sure to have debugging output enabled when compiling the module otherwise the output as well as the loglevel options
-won't be available.
+Level 'mcast' enables messages related to multicast optimizations. Level 'all' enables all messages. The messages
+are sent to the batman-adv debug log. Use \fBbatctl log\fP to retrieve it. Make sure to have debugging output enabled
+when compiling the module otherwise the output as well as the loglevel options won't be available.
.br
.IP "\fBlog\fP|\fBl\fP [\fB\-n\fP]\fP"
batctl will read the batman-adv debug log which has to be compiled into the kernel module. If "\-n" is given batctl will not
diff --git a/sys.c b/sys.c
index 676bef1..4fa0e24 100644
--- a/sys.c
+++ b/sys.c
@@ -280,6 +280,7 @@ static void log_level_usage(void)
fprintf(stderr, " \t bla Messages related to bridge loop avoidance\n");
fprintf(stderr, " \t dat Messages related to arp snooping and distributed arp table\n");
fprintf(stderr, " \t nc Messages related to network coding\n");
+ fprintf(stderr, " \t mcast Messages related to multicast\n");
}
int handle_loglevel(char *mesh_iface, int argc, char **argv)
@@ -325,6 +326,8 @@ int handle_loglevel(char *mesh_iface, int argc, char **argv)
log_level |= BIT(4);
else if (strcmp(argv[i], "nc") == 0)
log_level |= BIT(5);
+ else if (strcmp(argv[i], "mcast") == 0)
+ log_level |= BIT(6);
else {
log_level_usage();
goto out;
@@ -359,6 +362,8 @@ int handle_loglevel(char *mesh_iface, int argc, char **argv)
"messages related to arp snooping and distributed arp table", "dat");
printf("[%c] %s (%s)\n", (log_level & BIT(5)) ? 'x' : ' ',
"messages related to network coding", "nc");
+ printf("[%c] %s (%s)\n", (log_level & BIT(6)) ? 'x' : ' ',
+ "messages related to multicast", "mcast");
out:
free(path_buff);
--
1.7.10.4
The server will only overwrite the mac if it is zero.
Ths allows acting in place of (non-alfred) legacy clients
by injecting their data with the correct source mac.
Signed-off-by: Dominik Heidler <dominik(a)heidler.eu>
---
unix_sock.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/unix_sock.c b/unix_sock.c
index 3c7e583..d7578a3 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -119,7 +119,13 @@ static int unix_sock_add_data(struct globals *globals,
data = push->data;
data_len = ntohs(data->header.length);
- memcpy(data->source, &interface->hwaddr, sizeof(interface->hwaddr));
+
+ /* clients should set the source mac to 00:00:00:00:00:00
+ * to make the server set the source for them
+ */
+ static const char zero[ETH_ALEN] = { 0 };
+ if (!memcmp(zero, data->source, sizeof(data->source)))
+ memcpy(data->source, &interface->hwaddr, sizeof(interface->hwaddr));
if ((int)(data_len + sizeof(*data)) > len)
goto err;
--
2.7.2
The server will only overwrite the mac if it is zero.
Signed-off-by: Dominik Heidler <dominik(a)heidler.eu>
---
The alfred client sets the mac to zero by default
so this shouldn't break existing behaviour.
unix_sock.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/unix_sock.c b/unix_sock.c
index 3c7e583..12a10e6 100644
--- a/unix_sock.c
+++ b/unix_sock.c
@@ -119,7 +119,9 @@ static int unix_sock_add_data(struct globals *globals,
data = push->data;
data_len = ntohs(data->header.length);
- memcpy(data->source, &interface->hwaddr, sizeof(interface->hwaddr));
+ static const char zero[ETH_ALEN] = { 0 };
+ if (!memcmp(zero, data->source, sizeof(data->source)))
+ memcpy(data->source, &interface->hwaddr, sizeof(interface->hwaddr));
if ((int)(data_len + sizeof(*data)) > len)
goto err;
--
2.7.0