aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/rtnetlink.h2
-rw-r--r--include/uapi/linux/if_link.h1
-rw-r--r--net/core/rtnetlink.c13
3 files changed, 16 insertions, 0 deletions
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index e21b9f9653c0..6c6d5393fc34 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -46,6 +46,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
46 * to create when creating a new device. 46 * to create when creating a new device.
47 * @get_num_rx_queues: Function to determine number of receive queues 47 * @get_num_rx_queues: Function to determine number of receive queues
48 * to create when creating a new device. 48 * to create when creating a new device.
49 * @get_link_net: Function to get the i/o netns of the device
49 */ 50 */
50struct rtnl_link_ops { 51struct rtnl_link_ops {
51 struct list_head list; 52 struct list_head list;
@@ -93,6 +94,7 @@ struct rtnl_link_ops {
93 int (*fill_slave_info)(struct sk_buff *skb, 94 int (*fill_slave_info)(struct sk_buff *skb,
94 const struct net_device *dev, 95 const struct net_device *dev,
95 const struct net_device *slave_dev); 96 const struct net_device *slave_dev);
97 struct net *(*get_link_net)(const struct net_device *dev);
96}; 98};
97 99
98int __rtnl_link_register(struct rtnl_link_ops *ops); 100int __rtnl_link_register(struct rtnl_link_ops *ops);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 2a8380edbb7e..0deee3eeddbf 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -146,6 +146,7 @@ enum {
146 IFLA_PHYS_PORT_ID, 146 IFLA_PHYS_PORT_ID,
147 IFLA_CARRIER_CHANGES, 147 IFLA_CARRIER_CHANGES,
148 IFLA_PHYS_SWITCH_ID, 148 IFLA_PHYS_SWITCH_ID,
149 IFLA_LINK_NETNSID,
149 __IFLA_MAX 150 __IFLA_MAX
150}; 151};
151 152
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 47b39f3e867c..bd6370f0cb31 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -875,6 +875,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
875 + nla_total_size(1) /* IFLA_OPERSTATE */ 875 + nla_total_size(1) /* IFLA_OPERSTATE */
876 + nla_total_size(1) /* IFLA_LINKMODE */ 876 + nla_total_size(1) /* IFLA_LINKMODE */
877 + nla_total_size(4) /* IFLA_CARRIER_CHANGES */ 877 + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
878 + nla_total_size(4) /* IFLA_LINK_NETNSID */
878 + nla_total_size(ext_filter_mask 879 + nla_total_size(ext_filter_mask
879 & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ 880 & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
880 + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ 881 + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
@@ -1169,6 +1170,18 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
1169 goto nla_put_failure; 1170 goto nla_put_failure;
1170 } 1171 }
1171 1172
1173 if (dev->rtnl_link_ops &&
1174 dev->rtnl_link_ops->get_link_net) {
1175 struct net *link_net = dev->rtnl_link_ops->get_link_net(dev);
1176
1177 if (!net_eq(dev_net(dev), link_net)) {
1178 int id = peernet2id(dev_net(dev), link_net);
1179
1180 if (nla_put_s32(skb, IFLA_LINK_NETNSID, id))
1181 goto nla_put_failure;
1182 }
1183 }
1184
1172 if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC))) 1185 if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
1173 goto nla_put_failure; 1186 goto nla_put_failure;
1174 1187