[01/10] batman-adv: Handle parent interfaces in a different netns

Message ID 1461875848-11720-2-git-send-email-andrew@lunn.ch (mailing list archive)
State Superseded, archived
Delegated to: Marek Lindner
Headers

Commit Message

Andrew Lunn April 28, 2016, 8:37 p.m. UTC
  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 <andrew@lunn.ch>
Acked-by: Antonio Quartulli <a@untable.cc>
---
 net/batman-adv/hard-interface.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)
  

Comments

Sven Eckelmann April 29, 2016, 5:52 a.m. UTC | #1
On Thursday 28 April 2016 22:37:19 Andrew Lunn wrote:
> 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 <andrew@lunn.ch>
> Acked-by: Antonio Quartulli <a@untable.cc>
> ---

You are unfortunately reverting back to an older version of the patch which is 
harder to make compile on older kernels.

Kind regards,
	Sven
  
Andrew Lunn April 29, 2016, 12:14 p.m. UTC | #2
On Fri, Apr 29, 2016 at 07:52:42AM +0200, Sven Eckelmann wrote:
> On Thursday 28 April 2016 22:37:19 Andrew Lunn wrote:
> > 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 <andrew@lunn.ch>
> > Acked-by: Antonio Quartulli <a@untable.cc>
> > ---
> 
> You are unfortunately reverting back to an older version of the patch which is 
> harder to make compile on older kernels.

Hi Sven

Please point me at the version you would prefer.

       Andrew
  
Sven Eckelmann April 29, 2016, 12:59 p.m. UTC | #3
On Friday 29 April 2016 14:14:27 Andrew Lunn wrote:
> On Fri, Apr 29, 2016 at 07:52:42AM +0200, Sven Eckelmann wrote:
> > On Thursday 28 April 2016 22:37:19 Andrew Lunn wrote:
> > > 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 <andrew@lunn.ch>
> > > Acked-by: Antonio Quartulli <a@untable.cc>
> > > ---
> > 
> > You are unfortunately reverting back to an older version of the patch
> > which is harder to make compile on older kernels.
> 
> Hi Sven
> 
> Please point me at the version you would prefer.

Partially this one: https://patchwork.open-mesh.org/patch/15921/

I know that your current submission doesn't contain the compat-patches part
(which I find rather ugly) but this version has only a single function
handling the batadv_getlink_net and thus could be easier to create some wild
#defines working around the compat problem on older versions. But it will most
likely end with a warning and being a big NOP on older kernels.

It is something like (untested):

    /* WARNING dirty hack for batadv_getlink_net */
    #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
    	#define get_link_net get_xstats_size || 1 || netdev->rtnl_link_ops->get_xstats_size
    #endif

It is the version of the "share your drugs" hack from earlier compat hacks.

Kind regards,
	Sven
  

Patch

diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 8c2f399..e0cd7ce 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -84,24 +84,37 @@  out:
 
 /**
  * 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 = net1;
+	const struct net *dev2_parent_net = net2;
+
+	if (dev1->rtnl_link_ops && dev1->rtnl_link_ops->get_link_net)
+		dev1_parent_net = dev1->rtnl_link_ops->get_link_net(dev1);
+	if (dev2->rtnl_link_ops && dev2->rtnl_link_ops->get_link_net)
+		dev2_parent_net = dev2->rtnl_link_ops->get_link_net(dev2);
 
 	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);
 }
 
 /**
@@ -119,8 +132,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;
+	struct net *parent_net = net;
 	bool ret;
 
 	/* check if this is a batman-adv mesh interface */
@@ -132,13 +146,16 @@  static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
 	    dev_get_iflink(net_dev) == net_dev->ifindex)
 		return false;
 
+	if (net_dev->rtnl_link_ops && net_dev->rtnl_link_ops->get_link_net)
+		parent_net = net_dev->rtnl_link_ops->get_link_net(net_dev);
+
 	/* recurse over the parent device */
-	parent_dev = __dev_get_by_index(net, dev_get_iflink(net_dev));
+	parent_dev = __dev_get_by_index(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);