Skip to content

Commit 5f02ce2

Browse files
David Aherndavem330
authored andcommitted
net: l3mdev: Allow the l3mdev to be a loopback
Allow an L3 master device to act as the loopback for that L3 domain. For IPv4 the device can also have the address 127.0.0.1. Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a8e3e1a commit 5f02ce2

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

include/net/l3mdev.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
9090
}
9191

9292
static inline
93-
const struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
93+
struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
9494
{
9595
/* netdev_master_upper_dev_get_rcu calls
9696
* list_first_or_null_rcu to walk the upper dev list.
@@ -99,7 +99,7 @@ const struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
9999
* typecast to remove the const
100100
*/
101101
struct net_device *dev = (struct net_device *)_dev;
102-
const struct net_device *master;
102+
struct net_device *master;
103103

104104
if (!dev)
105105
return NULL;
@@ -254,7 +254,7 @@ static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
254254
}
255255

256256
static inline
257-
const struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
257+
struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
258258
{
259259
return NULL;
260260
}

net/ipv4/route.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,7 +2018,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
20182018
return ERR_PTR(-EINVAL);
20192019

20202020
if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev)))
2021-
if (ipv4_is_loopback(fl4->saddr) && !(dev_out->flags & IFF_LOOPBACK))
2021+
if (ipv4_is_loopback(fl4->saddr) &&
2022+
!(dev_out->flags & IFF_LOOPBACK) &&
2023+
!netif_is_l3_master(dev_out))
20222024
return ERR_PTR(-EINVAL);
20232025

20242026
if (ipv4_is_lbcast(fl4->daddr))
@@ -2302,7 +2304,9 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
23022304
else
23032305
fl4->saddr = fl4->daddr;
23042306
}
2305-
dev_out = net->loopback_dev;
2307+
2308+
/* L3 master device is the loopback for that domain */
2309+
dev_out = l3mdev_master_dev_rcu(dev_out) ? : net->loopback_dev;
23062310
fl4->flowi4_oif = dev_out->ifindex;
23072311
flags |= RTCF_LOCAL;
23082312
goto make_route;

net/ipv6/route.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,8 +2558,16 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
25582558
{
25592559
u32 tb_id;
25602560
struct net *net = dev_net(idev->dev);
2561-
struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
2562-
DST_NOCOUNT);
2561+
struct net_device *dev = net->loopback_dev;
2562+
struct rt6_info *rt;
2563+
2564+
/* use L3 Master device as loopback for host routes if device
2565+
* is enslaved and address is not link local or multicast
2566+
*/
2567+
if (!rt6_need_strict(addr))
2568+
dev = l3mdev_master_dev_rcu(idev->dev) ? : dev;
2569+
2570+
rt = ip6_dst_alloc(net, dev, DST_NOCOUNT);
25632571
if (!rt)
25642572
return ERR_PTR(-ENOMEM);
25652573

0 commit comments

Comments
 (0)