[01/10] batman-adv: Handle parent interfaces in a different netns
Commit Message
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
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
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
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
@@ -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);