diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 8d71a832cb17..aa5add519625 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1492,8 +1492,14 @@ int macvlan_common_newlink(struct net_device *dev, /* When creating macvlans or macvtaps on top of other macvlans - use * the real device as the lowerdev. */ - if (netif_is_macvlan(lowerdev)) + if (netif_is_macvlan(lowerdev)) { lowerdev = macvlan_dev_real_dev(lowerdev); + if (!rtnl_dev_link_net_capable(dev, dev_net(lowerdev))) { + NL_SET_ERR_MSG(extack, + "Creating a macvlan on a lower device in another network namespace requires CAP_NET_ADMIN in that namespace"); + return -EPERM; + } + } if (!tb[IFLA_MTU]) dev->mtu = lowerdev->mtu; @@ -1632,6 +1638,14 @@ static int macvlan_changelink(struct net_device *dev, enum macvlan_macaddr_mode macmode; int ret; + if (data && + (data[IFLA_MACVLAN_BC_QUEUE_LEN] || data[IFLA_MACVLAN_BC_CUTOFF]) && + !rtnl_dev_link_net_capable(dev, dev_net(vlan->lowerdev))) { + NL_SET_ERR_MSG(extack, + "Changing shared macvlan port settings requires CAP_NET_ADMIN in the lower device network namespace"); + return -EPERM; + } + /* Validate mode, but don't set yet: setting flags may fail. */ if (data && data[IFLA_MACVLAN_MODE]) { set_mode = true;