From patchwork Thu Jun 9 14:54:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Wunderlich X-Patchwork-Id: 16337 X-Patchwork-Delegate: mareklindner@neomailbox.ch Return-Path: X-Original-To: patchwork@open-mesh.org Delivered-To: patchwork@open-mesh.org Received: from open-mesh.org (localhost [IPv6:::1]) by open-mesh.org (Postfix) with ESMTP id DA7BE81CEF; Thu, 9 Jun 2016 16:55:00 +0200 (CEST) Authentication-Results: open-mesh.org; dmarc=none header.from=simonwunderlich.de Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=79.140.42.25; helo=mail.mail.packetmixer.de; envelope-from=sw@simonwunderlich.de; receiver=b.a.t.m.a.n@lists.open-mesh.org Authentication-Results: open-mesh.org; dmarc=none header.from=simonwunderlich.de Received: from mail.mail.packetmixer.de (packetmixer.de [79.140.42.25]) by open-mesh.org (Postfix) with ESMTPS id D6E7581C52 for ; Thu, 9 Jun 2016 16:54:51 +0200 (CEST) Received: from kero.packetmixer.de (p2003007C6F7E2400527B9DFFFECE2EDC.dip0.t-ipconnect.de [IPv6:2003:7c:6f7e:2400:527b:9dff:fece:2edc]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mail.packetmixer.de (Postfix) with ESMTPSA id D7F28174001; Thu, 9 Jun 2016 16:54:51 +0200 (CEST) From: Simon Wunderlich To: b.a.t.m.a.n@lists.open-mesh.org Date: Thu, 9 Jun 2016 16:54:33 +0200 Message-Id: <1465484086-7974-2-git-send-email-sw@simonwunderlich.de> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1465484086-7974-1-git-send-email-sw@simonwunderlich.de> References: <1465484086-7974-1-git-send-email-sw@simonwunderlich.de> Subject: [B.A.T.M.A.N.] [PATCH v9 01/14] batman-adv: Handle parent interfaces in a different netns X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking Errors-To: b.a.t.m.a.n-bounces@lists.open-mesh.org Sender: "B.A.T.M.A.N" From: Andrew Lunn batman-adv tries to prevent the user from placing a batX soft interface into another batman mesh as a hard interface. It does this by walking up the devices list of parents and ensures they are all none batX interfaces. iflink can point to an interface in a different namespace, so also retrieve the parents name space when finding the parent and use it when doing the comparison. Signed-off-by: Andrew Lunn [sven@narfation.org: Fix alignments, simplify parent netns retrieval] Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- compat.h | 7 ++++++ net/batman-adv/hard-interface.c | 50 +++++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/compat.h b/compat.h index 7d5c8b6..fc78948 100644 --- a/compat.h +++ b/compat.h @@ -146,6 +146,13 @@ static int __batadv_interface_kill_vid(struct net_device *dev, __be16 proto,\ #endif /* < KERNEL_VERSION(3, 15, 0) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) + +/* WARNING for batadv_getlink_net */ +#define get_link_net get_xstats_size || 1 || netdev->rtnl_link_ops->get_xstats_size + +#endif /* < KERNEL_VERSION(4, 0, 0) */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) #define IFF_NO_QUEUE 0; dev->tx_queue_len = 0 diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 1f90808..9524c1a 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "bat_v.h" #include "bridge_loop_avoidance.h" @@ -85,25 +87,55 @@ out: } /** + * batadv_getlink_net - return link net namespace (of use fallback) + * @netdev: net_device to check + * @fallback_net: return in case get_link_net is not available for @netdev + * + * Return: result of rtnl_link_ops->get_link_net or @fallback_net + */ +static const struct net *batadv_getlink_net(const struct net_device *netdev, + const struct net *fallback_net) +{ + if (!netdev->rtnl_link_ops) + return fallback_net; + + if (!netdev->rtnl_link_ops->get_link_net) + return fallback_net; + + return netdev->rtnl_link_ops->get_link_net(netdev); +} + +/** * batadv_mutual_parents - check if two devices are each others parent - * @dev1: 1st net_device - * @dev2: 2nd net_device + * @dev1: 1st net dev + * @net1: 1st devices netns + * @dev2: 2nd net dev + * @net2: 2nd devices netns * * veth devices come in pairs and each is the parent of the other! * * Return: true if the devices are each others parent, otherwise false */ static bool batadv_mutual_parents(const struct net_device *dev1, - const struct net_device *dev2) + const struct net *net1, + const struct net_device *dev2, + const struct net *net2) { int dev1_parent_iflink = dev_get_iflink(dev1); int dev2_parent_iflink = dev_get_iflink(dev2); + const struct net *dev1_parent_net; + const struct net *dev2_parent_net; + + dev1_parent_net = batadv_getlink_net(dev1, net1); + dev2_parent_net = batadv_getlink_net(dev2, net2); if (!dev1_parent_iflink || !dev2_parent_iflink) return false; return (dev1_parent_iflink == dev2->ifindex) && - (dev2_parent_iflink == dev1->ifindex); + (dev2_parent_iflink == dev1->ifindex) && + net_eq(dev1_parent_net, net2) && + net_eq(dev2_parent_net, net1); } /** @@ -121,8 +153,9 @@ static bool batadv_mutual_parents(const struct net_device *dev1, */ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) { - struct net_device *parent_dev; struct net *net = dev_net(net_dev); + struct net_device *parent_dev; + const struct net *parent_net; bool ret; /* check if this is a batman-adv mesh interface */ @@ -134,13 +167,16 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) dev_get_iflink(net_dev) == net_dev->ifindex) return false; + parent_net = batadv_getlink_net(net_dev, net); + /* recurse over the parent device */ - parent_dev = __dev_get_by_index(net, dev_get_iflink(net_dev)); + parent_dev = __dev_get_by_index((struct net *)parent_net, + dev_get_iflink(net_dev)); /* if we got a NULL parent_dev there is something broken.. */ if (WARN(!parent_dev, "Cannot find parent device")) return false; - if (batadv_mutual_parents(net_dev, parent_dev)) + if (batadv_mutual_parents(net_dev, net, parent_dev, parent_net)) return false; ret = batadv_is_on_batman_iface(parent_dev);