@@ -921,7 +921,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
921
921
+ nla_total_size (4 ) /* IFLA_EVENT */
922
922
+ nla_total_size (4 ) /* IFLA_NEW_NETNSID */
923
923
+ nla_total_size (1 ); /* IFLA_PROTO_DOWN */
924
-
924
+ + nla_total_size (4 ) /* IFLA_IF_NETNSID */
925
+ + 0 ;
925
926
}
926
927
927
928
static int rtnl_vf_ports_fill (struct sk_buff * skb , struct net_device * dev )
@@ -1370,13 +1371,14 @@ static noinline_for_stack int nla_put_ifalias(struct sk_buff *skb,
1370
1371
}
1371
1372
1372
1373
static int rtnl_fill_link_netnsid (struct sk_buff * skb ,
1373
- const struct net_device * dev )
1374
+ const struct net_device * dev ,
1375
+ struct net * src_net )
1374
1376
{
1375
1377
if (dev -> rtnl_link_ops && dev -> rtnl_link_ops -> get_link_net ) {
1376
1378
struct net * link_net = dev -> rtnl_link_ops -> get_link_net (dev );
1377
1379
1378
1380
if (!net_eq (dev_net (dev ), link_net )) {
1379
- int id = peernet2id_alloc (dev_net ( dev ) , link_net );
1381
+ int id = peernet2id_alloc (src_net , link_net );
1380
1382
1381
1383
if (nla_put_s32 (skb , IFLA_LINK_NETNSID , id ))
1382
1384
return - EMSGSIZE ;
@@ -1427,10 +1429,11 @@ static int rtnl_fill_link_af(struct sk_buff *skb,
1427
1429
return 0 ;
1428
1430
}
1429
1431
1430
- static int rtnl_fill_ifinfo (struct sk_buff * skb , struct net_device * dev ,
1432
+ static int rtnl_fill_ifinfo (struct sk_buff * skb ,
1433
+ struct net_device * dev , struct net * src_net ,
1431
1434
int type , u32 pid , u32 seq , u32 change ,
1432
1435
unsigned int flags , u32 ext_filter_mask ,
1433
- u32 event , int * new_nsid )
1436
+ u32 event , int * new_nsid , int tgt_netnsid )
1434
1437
{
1435
1438
struct ifinfomsg * ifm ;
1436
1439
struct nlmsghdr * nlh ;
@@ -1448,6 +1451,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
1448
1451
ifm -> ifi_flags = dev_get_flags (dev );
1449
1452
ifm -> ifi_change = change ;
1450
1453
1454
+ if (tgt_netnsid >= 0 && nla_put_s32 (skb , IFLA_IF_NETNSID , tgt_netnsid ))
1455
+ goto nla_put_failure ;
1456
+
1451
1457
if (nla_put_string (skb , IFLA_IFNAME , dev -> name ) ||
1452
1458
nla_put_u32 (skb , IFLA_TXQLEN , dev -> tx_queue_len ) ||
1453
1459
nla_put_u8 (skb , IFLA_OPERSTATE ,
@@ -1513,7 +1519,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
1513
1519
goto nla_put_failure ;
1514
1520
}
1515
1521
1516
- if (rtnl_fill_link_netnsid (skb , dev ))
1522
+ if (rtnl_fill_link_netnsid (skb , dev , src_net ))
1517
1523
goto nla_put_failure ;
1518
1524
1519
1525
if (new_nsid &&
@@ -1571,6 +1577,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
1571
1577
[IFLA_XDP ] = { .type = NLA_NESTED },
1572
1578
[IFLA_EVENT ] = { .type = NLA_U32 },
1573
1579
[IFLA_GROUP ] = { .type = NLA_U32 },
1580
+ [IFLA_IF_NETNSID ] = { .type = NLA_S32 },
1574
1581
};
1575
1582
1576
1583
static const struct nla_policy ifla_info_policy [IFLA_INFO_MAX + 1 ] = {
@@ -1674,9 +1681,28 @@ static bool link_dump_filtered(struct net_device *dev,
1674
1681
return false;
1675
1682
}
1676
1683
1684
+ static struct net * get_target_net (struct sk_buff * skb , int netnsid )
1685
+ {
1686
+ struct net * net ;
1687
+
1688
+ net = get_net_ns_by_id (sock_net (skb -> sk ), netnsid );
1689
+ if (!net )
1690
+ return ERR_PTR (- EINVAL );
1691
+
1692
+ /* For now, the caller is required to have CAP_NET_ADMIN in
1693
+ * the user namespace owning the target net ns.
1694
+ */
1695
+ if (!netlink_ns_capable (skb , net -> user_ns , CAP_NET_ADMIN )) {
1696
+ put_net (net );
1697
+ return ERR_PTR (- EACCES );
1698
+ }
1699
+ return net ;
1700
+ }
1701
+
1677
1702
static int rtnl_dump_ifinfo (struct sk_buff * skb , struct netlink_callback * cb )
1678
1703
{
1679
1704
struct net * net = sock_net (skb -> sk );
1705
+ struct net * tgt_net = net ;
1680
1706
int h , s_h ;
1681
1707
int idx = 0 , s_idx ;
1682
1708
struct net_device * dev ;
@@ -1686,6 +1712,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
1686
1712
const struct rtnl_link_ops * kind_ops = NULL ;
1687
1713
unsigned int flags = NLM_F_MULTI ;
1688
1714
int master_idx = 0 ;
1715
+ int netnsid = -1 ;
1689
1716
int err ;
1690
1717
int hdrlen ;
1691
1718
@@ -1704,6 +1731,15 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
1704
1731
1705
1732
if (nlmsg_parse (cb -> nlh , hdrlen , tb , IFLA_MAX ,
1706
1733
ifla_policy , NULL ) >= 0 ) {
1734
+ if (tb [IFLA_IF_NETNSID ]) {
1735
+ netnsid = nla_get_s32 (tb [IFLA_IF_NETNSID ]);
1736
+ tgt_net = get_target_net (skb , netnsid );
1737
+ if (IS_ERR (tgt_net )) {
1738
+ tgt_net = net ;
1739
+ netnsid = -1 ;
1740
+ }
1741
+ }
1742
+
1707
1743
if (tb [IFLA_EXT_MASK ])
1708
1744
ext_filter_mask = nla_get_u32 (tb [IFLA_EXT_MASK ]);
1709
1745
@@ -1719,17 +1755,19 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
1719
1755
1720
1756
for (h = s_h ; h < NETDEV_HASHENTRIES ; h ++ , s_idx = 0 ) {
1721
1757
idx = 0 ;
1722
- head = & net -> dev_index_head [h ];
1758
+ head = & tgt_net -> dev_index_head [h ];
1723
1759
hlist_for_each_entry (dev , head , index_hlist ) {
1724
1760
if (link_dump_filtered (dev , master_idx , kind_ops ))
1725
1761
goto cont ;
1726
1762
if (idx < s_idx )
1727
1763
goto cont ;
1728
- err = rtnl_fill_ifinfo (skb , dev , RTM_NEWLINK ,
1764
+ err = rtnl_fill_ifinfo (skb , dev , net ,
1765
+ RTM_NEWLINK ,
1729
1766
NETLINK_CB (cb -> skb ).portid ,
1730
1767
cb -> nlh -> nlmsg_seq , 0 ,
1731
1768
flags ,
1732
- ext_filter_mask , 0 , NULL );
1769
+ ext_filter_mask , 0 , NULL ,
1770
+ netnsid );
1733
1771
1734
1772
if (err < 0 ) {
1735
1773
if (likely (skb -> len ))
@@ -1748,6 +1786,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
1748
1786
cb -> args [0 ] = h ;
1749
1787
cb -> seq = net -> dev_base_seq ;
1750
1788
nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
1789
+ if (netnsid >= 0 )
1790
+ put_net (tgt_net );
1751
1791
1752
1792
return err ;
1753
1793
}
@@ -2360,6 +2400,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
2360
2400
if (err < 0 )
2361
2401
goto errout ;
2362
2402
2403
+ if (tb [IFLA_IF_NETNSID ])
2404
+ return - EOPNOTSUPP ;
2405
+
2363
2406
if (tb [IFLA_IFNAME ])
2364
2407
nla_strlcpy (ifname , tb [IFLA_IFNAME ], IFNAMSIZ );
2365
2408
else
@@ -2454,6 +2497,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
2454
2497
if (err < 0 )
2455
2498
return err ;
2456
2499
2500
+ if (tb [IFLA_IF_NETNSID ])
2501
+ return - EOPNOTSUPP ;
2502
+
2457
2503
if (tb [IFLA_IFNAME ])
2458
2504
nla_strlcpy (ifname , tb [IFLA_IFNAME ], IFNAMSIZ );
2459
2505
@@ -2585,6 +2631,9 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
2585
2631
if (err < 0 )
2586
2632
return err ;
2587
2633
2634
+ if (tb [IFLA_IF_NETNSID ])
2635
+ return - EOPNOTSUPP ;
2636
+
2588
2637
if (tb [IFLA_IFNAME ])
2589
2638
nla_strlcpy (ifname , tb [IFLA_IFNAME ], IFNAMSIZ );
2590
2639
else
@@ -2818,47 +2867,64 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
2818
2867
struct netlink_ext_ack * extack )
2819
2868
{
2820
2869
struct net * net = sock_net (skb -> sk );
2870
+ struct net * tgt_net = net ;
2821
2871
struct ifinfomsg * ifm ;
2822
2872
char ifname [IFNAMSIZ ];
2823
2873
struct nlattr * tb [IFLA_MAX + 1 ];
2824
2874
struct net_device * dev = NULL ;
2825
2875
struct sk_buff * nskb ;
2876
+ int netnsid = -1 ;
2826
2877
int err ;
2827
2878
u32 ext_filter_mask = 0 ;
2828
2879
2829
2880
err = nlmsg_parse (nlh , sizeof (* ifm ), tb , IFLA_MAX , ifla_policy , extack );
2830
2881
if (err < 0 )
2831
2882
return err ;
2832
2883
2884
+ if (tb [IFLA_IF_NETNSID ]) {
2885
+ netnsid = nla_get_s32 (tb [IFLA_IF_NETNSID ]);
2886
+ tgt_net = get_target_net (skb , netnsid );
2887
+ if (IS_ERR (tgt_net ))
2888
+ return PTR_ERR (tgt_net );
2889
+ }
2890
+
2833
2891
if (tb [IFLA_IFNAME ])
2834
2892
nla_strlcpy (ifname , tb [IFLA_IFNAME ], IFNAMSIZ );
2835
2893
2836
2894
if (tb [IFLA_EXT_MASK ])
2837
2895
ext_filter_mask = nla_get_u32 (tb [IFLA_EXT_MASK ]);
2838
2896
2897
+ err = - EINVAL ;
2839
2898
ifm = nlmsg_data (nlh );
2840
2899
if (ifm -> ifi_index > 0 )
2841
- dev = __dev_get_by_index (net , ifm -> ifi_index );
2900
+ dev = __dev_get_by_index (tgt_net , ifm -> ifi_index );
2842
2901
else if (tb [IFLA_IFNAME ])
2843
- dev = __dev_get_by_name (net , ifname );
2902
+ dev = __dev_get_by_name (tgt_net , ifname );
2844
2903
else
2845
- return - EINVAL ;
2904
+ goto out ;
2846
2905
2906
+ err = - ENODEV ;
2847
2907
if (dev == NULL )
2848
- return - ENODEV ;
2908
+ goto out ;
2849
2909
2910
+ err = - ENOBUFS ;
2850
2911
nskb = nlmsg_new (if_nlmsg_size (dev , ext_filter_mask ), GFP_KERNEL );
2851
2912
if (nskb == NULL )
2852
- return - ENOBUFS ;
2913
+ goto out ;
2853
2914
2854
- err = rtnl_fill_ifinfo (nskb , dev , RTM_NEWLINK , NETLINK_CB (skb ).portid ,
2855
- nlh -> nlmsg_seq , 0 , 0 , ext_filter_mask , 0 , NULL );
2915
+ err = rtnl_fill_ifinfo (nskb , dev , net ,
2916
+ RTM_NEWLINK , NETLINK_CB (skb ).portid ,
2917
+ nlh -> nlmsg_seq , 0 , 0 , ext_filter_mask ,
2918
+ 0 , NULL , netnsid );
2856
2919
if (err < 0 ) {
2857
2920
/* -EMSGSIZE implies BUG in if_nlmsg_size */
2858
2921
WARN_ON (err == - EMSGSIZE );
2859
2922
kfree_skb (nskb );
2860
2923
} else
2861
2924
err = rtnl_unicast (nskb , net , NETLINK_CB (skb ).portid );
2925
+ out :
2926
+ if (netnsid >= 0 )
2927
+ put_net (tgt_net );
2862
2928
2863
2929
return err ;
2864
2930
}
@@ -2948,8 +3014,9 @@ struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
2948
3014
if (skb == NULL )
2949
3015
goto errout ;
2950
3016
2951
- err = rtnl_fill_ifinfo (skb , dev , type , 0 , 0 , change , 0 , 0 , event ,
2952
- new_nsid );
3017
+ err = rtnl_fill_ifinfo (skb , dev , dev_net (dev ),
3018
+ type , 0 , 0 , change , 0 , 0 , event ,
3019
+ new_nsid , -1 );
2953
3020
if (err < 0 ) {
2954
3021
/* -EMSGSIZE implies BUG in if_nlmsg_size() */
2955
3022
WARN_ON (err == - EMSGSIZE );
0 commit comments