Commit f4ac8292 authored by David S. Miller's avatar David S. Miller

Merge branch 'link_netns_advertise'

Nicolas Dichtel says:

====================
netns: advertise netns via netlink

The first patch of the series fix a bug of the previous series (present in
net-next only).
The rest of the series adds an attribute to advertise the peer netns for
rtnetlink messages where this information is needed by userland to be able to
interpret fully the received message.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d7924450 193523bf
...@@ -1471,11 +1471,17 @@ int macvlan_link_register(struct rtnl_link_ops *ops) ...@@ -1471,11 +1471,17 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
}; };
EXPORT_SYMBOL_GPL(macvlan_link_register); EXPORT_SYMBOL_GPL(macvlan_link_register);
static struct net *macvlan_get_link_net(const struct net_device *dev)
{
return dev_net(macvlan_dev_real_dev(dev));
}
static struct rtnl_link_ops macvlan_link_ops = { static struct rtnl_link_ops macvlan_link_ops = {
.kind = "macvlan", .kind = "macvlan",
.setup = macvlan_setup, .setup = macvlan_setup,
.newlink = macvlan_newlink, .newlink = macvlan_newlink,
.dellink = macvlan_dellink, .dellink = macvlan_dellink,
.get_link_net = macvlan_get_link_net,
}; };
static int macvlan_device_event(struct notifier_block *unused, static int macvlan_device_event(struct notifier_block *unused,
......
...@@ -469,6 +469,14 @@ static const struct nla_policy veth_policy[VETH_INFO_MAX + 1] = { ...@@ -469,6 +469,14 @@ static const struct nla_policy veth_policy[VETH_INFO_MAX + 1] = {
[VETH_INFO_PEER] = { .len = sizeof(struct ifinfomsg) }, [VETH_INFO_PEER] = { .len = sizeof(struct ifinfomsg) },
}; };
static struct net *veth_get_link_net(const struct net_device *dev)
{
struct veth_priv *priv = netdev_priv(dev);
struct net_device *peer = rtnl_dereference(priv->peer);
return peer ? dev_net(peer) : dev_net(dev);
}
static struct rtnl_link_ops veth_link_ops = { static struct rtnl_link_ops veth_link_ops = {
.kind = DRV_NAME, .kind = DRV_NAME,
.priv_size = sizeof(struct veth_priv), .priv_size = sizeof(struct veth_priv),
...@@ -478,6 +486,7 @@ static struct rtnl_link_ops veth_link_ops = { ...@@ -478,6 +486,7 @@ static struct rtnl_link_ops veth_link_ops = {
.dellink = veth_dellink, .dellink = veth_dellink,
.policy = veth_policy, .policy = veth_policy,
.maxtype = VETH_INFO_MAX, .maxtype = VETH_INFO_MAX,
.get_link_net = veth_get_link_net,
}; };
/* /*
......
...@@ -339,6 +339,11 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, ...@@ -339,6 +339,11 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
ndm->ndm_flags = fdb->flags; ndm->ndm_flags = fdb->flags;
ndm->ndm_type = RTN_UNICAST; ndm->ndm_type = RTN_UNICAST;
if (!net_eq(dev_net(vxlan->dev), vxlan->net) &&
nla_put_s32(skb, NDA_NDM_IFINDEX_NETNSID,
peernet2id(vxlan->net, dev_net(vxlan->dev))))
goto nla_put_failure;
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr)) if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
goto nla_put_failure; goto nla_put_failure;
......
...@@ -25,6 +25,7 @@ enum { ...@@ -25,6 +25,7 @@ enum {
NDA_VNI, NDA_VNI,
NDA_IFINDEX, NDA_IFINDEX,
NDA_MASTER, NDA_MASTER,
NDA_NDM_IFINDEX_NETNSID,
__NDA_MAX __NDA_MAX
}; };
......
...@@ -238,6 +238,13 @@ static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) ...@@ -238,6 +238,13 @@ static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
return -EMSGSIZE; return -EMSGSIZE;
} }
static struct net *vlan_get_link_net(const struct net_device *dev)
{
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
return dev_net(real_dev);
}
struct rtnl_link_ops vlan_link_ops __read_mostly = { struct rtnl_link_ops vlan_link_ops __read_mostly = {
.kind = "vlan", .kind = "vlan",
.maxtype = IFLA_VLAN_MAX, .maxtype = IFLA_VLAN_MAX,
...@@ -250,6 +257,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = { ...@@ -250,6 +257,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = {
.dellink = unregister_vlan_dev, .dellink = unregister_vlan_dev,
.get_size = vlan_get_size, .get_size = vlan_get_size,
.fill_info = vlan_fill_info, .fill_info = vlan_fill_info,
.get_link_net = vlan_get_link_net,
}; };
int __init vlan_netlink_init(void) int __init vlan_netlink_init(void)
......
...@@ -202,6 +202,7 @@ int peernet2id(struct net *net, struct net *peer) ...@@ -202,6 +202,7 @@ int peernet2id(struct net *net, struct net *peer)
return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED; return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED;
} }
EXPORT_SYMBOL(peernet2id);
struct net *get_net_ns_by_id(struct net *net, int id) struct net *get_net_ns_by_id(struct net *net, int id)
{ {
......
...@@ -2172,8 +2172,11 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh) ...@@ -2172,8 +2172,11 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
goto out; goto out;
} }
if (link_net) if (link_net) {
err = dev_change_net_namespace(dev, dest_net, ifname); err = dev_change_net_namespace(dev, dest_net, ifname);
if (err < 0)
unregister_netdevice(dev);
}
out: out:
if (link_net) if (link_net)
put_net(link_net); put_net(link_net);
......
...@@ -1676,6 +1676,7 @@ static struct rtnl_link_ops ip6gre_tap_ops __read_mostly = { ...@@ -1676,6 +1676,7 @@ static struct rtnl_link_ops ip6gre_tap_ops __read_mostly = {
.changelink = ip6gre_changelink, .changelink = ip6gre_changelink,
.get_size = ip6gre_get_size, .get_size = ip6gre_get_size,
.fill_info = ip6gre_fill_info, .fill_info = ip6gre_fill_info,
.get_link_net = ip6_tnl_get_link_net,
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment