@@ -365,6 +365,22 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops)
365
365
}
366
366
EXPORT_SYMBOL_GPL (rtnl_link_unregister );
367
367
368
+ static size_t rtnl_link_get_slave_info_data_size (const struct net_device * dev )
369
+ {
370
+ struct net_device * master_dev ;
371
+ const struct rtnl_link_ops * ops ;
372
+
373
+ master_dev = netdev_master_upper_dev_get ((struct net_device * ) dev );
374
+ if (!master_dev )
375
+ return 0 ;
376
+ ops = master_dev -> rtnl_link_ops ;
377
+ if (!ops -> get_slave_size )
378
+ return 0 ;
379
+ /* IFLA_INFO_SLAVE_DATA + nested data */
380
+ return nla_total_size (sizeof (struct nlattr )) +
381
+ ops -> get_slave_size (master_dev , dev );
382
+ }
383
+
368
384
static size_t rtnl_link_get_size (const struct net_device * dev )
369
385
{
370
386
const struct rtnl_link_ops * ops = dev -> rtnl_link_ops ;
@@ -385,6 +401,8 @@ static size_t rtnl_link_get_size(const struct net_device *dev)
385
401
/* IFLA_INFO_XSTATS */
386
402
size += nla_total_size (ops -> get_xstats_size (dev ));
387
403
404
+ size += rtnl_link_get_slave_info_data_size (dev );
405
+
388
406
return size ;
389
407
}
390
408
@@ -459,40 +477,101 @@ static size_t rtnl_link_get_af_size(const struct net_device *dev)
459
477
return size ;
460
478
}
461
479
462
- static int rtnl_link_fill ( struct sk_buff * skb , const struct net_device * dev )
480
+ static bool rtnl_have_link_slave_info ( const struct net_device * dev )
463
481
{
464
- const struct rtnl_link_ops * ops = dev -> rtnl_link_ops ;
465
- struct nlattr * linkinfo , * data ;
466
- int err = - EMSGSIZE ;
482
+ struct net_device * master_dev ;
467
483
468
- linkinfo = nla_nest_start (skb , IFLA_LINKINFO );
469
- if (linkinfo == NULL )
470
- goto out ;
484
+ master_dev = netdev_master_upper_dev_get ((struct net_device * ) dev );
485
+ if (master_dev && master_dev -> rtnl_link_ops &&
486
+ master_dev -> rtnl_link_ops -> fill_slave_info )
487
+ return true;
488
+ return false;
489
+ }
490
+
491
+ static int rtnl_link_slave_info_fill (struct sk_buff * skb ,
492
+ const struct net_device * dev )
493
+ {
494
+ struct net_device * master_dev ;
495
+ const struct rtnl_link_ops * ops ;
496
+ struct nlattr * slave_data ;
497
+ int err ;
471
498
499
+ master_dev = netdev_master_upper_dev_get ((struct net_device * ) dev );
500
+ if (!master_dev )
501
+ return 0 ;
502
+ ops = master_dev -> rtnl_link_ops ;
503
+ if (!ops )
504
+ return 0 ;
505
+ if (nla_put_string (skb , IFLA_INFO_SLAVE_KIND , ops -> kind ) < 0 )
506
+ return - EMSGSIZE ;
507
+ if (ops -> fill_slave_info ) {
508
+ slave_data = nla_nest_start (skb , IFLA_INFO_SLAVE_DATA );
509
+ if (!slave_data )
510
+ return - EMSGSIZE ;
511
+ err = ops -> fill_slave_info (skb , master_dev , dev );
512
+ if (err < 0 )
513
+ goto err_cancel_slave_data ;
514
+ nla_nest_end (skb , slave_data );
515
+ }
516
+ return 0 ;
517
+
518
+ err_cancel_slave_data :
519
+ nla_nest_cancel (skb , slave_data );
520
+ return err ;
521
+ }
522
+
523
+ static int rtnl_link_info_fill (struct sk_buff * skb ,
524
+ const struct net_device * dev )
525
+ {
526
+ const struct rtnl_link_ops * ops = dev -> rtnl_link_ops ;
527
+ struct nlattr * data ;
528
+ int err ;
529
+
530
+ if (!ops )
531
+ return 0 ;
472
532
if (nla_put_string (skb , IFLA_INFO_KIND , ops -> kind ) < 0 )
473
- goto err_cancel_link ;
533
+ return - EMSGSIZE ;
474
534
if (ops -> fill_xstats ) {
475
535
err = ops -> fill_xstats (skb , dev );
476
536
if (err < 0 )
477
- goto err_cancel_link ;
537
+ return err ;
478
538
}
479
539
if (ops -> fill_info ) {
480
540
data = nla_nest_start (skb , IFLA_INFO_DATA );
481
- if (data == NULL ) {
482
- err = - EMSGSIZE ;
483
- goto err_cancel_link ;
484
- }
541
+ if (data == NULL )
542
+ return - EMSGSIZE ;
485
543
err = ops -> fill_info (skb , dev );
486
544
if (err < 0 )
487
545
goto err_cancel_data ;
488
546
nla_nest_end (skb , data );
489
547
}
490
-
491
- nla_nest_end (skb , linkinfo );
492
548
return 0 ;
493
549
494
550
err_cancel_data :
495
551
nla_nest_cancel (skb , data );
552
+ return err ;
553
+ }
554
+
555
+ static int rtnl_link_fill (struct sk_buff * skb , const struct net_device * dev )
556
+ {
557
+ struct nlattr * linkinfo ;
558
+ int err = - EMSGSIZE ;
559
+
560
+ linkinfo = nla_nest_start (skb , IFLA_LINKINFO );
561
+ if (linkinfo == NULL )
562
+ goto out ;
563
+
564
+ err = rtnl_link_info_fill (skb , dev );
565
+ if (err < 0 )
566
+ goto err_cancel_link ;
567
+
568
+ err = rtnl_link_slave_info_fill (skb , dev );
569
+ if (err < 0 )
570
+ goto err_cancel_link ;
571
+
572
+ nla_nest_end (skb , linkinfo );
573
+ return 0 ;
574
+
496
575
err_cancel_link :
497
576
nla_nest_cancel (skb , linkinfo );
498
577
out :
@@ -1052,10 +1131,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
1052
1131
if (rtnl_port_fill (skb , dev ))
1053
1132
goto nla_put_failure ;
1054
1133
1055
- if (rtnl_bond_slave_fill (skb , dev ))
1056
- goto nla_put_failure ;
1057
-
1058
- if (dev -> rtnl_link_ops ) {
1134
+ if (dev -> rtnl_link_ops || rtnl_have_link_slave_info (dev )) {
1059
1135
if (rtnl_link_fill (skb , dev ) < 0 )
1060
1136
goto nla_put_failure ;
1061
1137
}
@@ -1178,6 +1254,8 @@ EXPORT_SYMBOL(ifla_policy);
1178
1254
static const struct nla_policy ifla_info_policy [IFLA_INFO_MAX + 1 ] = {
1179
1255
[IFLA_INFO_KIND ] = { .type = NLA_STRING },
1180
1256
[IFLA_INFO_DATA ] = { .type = NLA_NESTED },
1257
+ [IFLA_INFO_SLAVE_KIND ] = { .type = NLA_STRING },
1258
+ [IFLA_INFO_SLAVE_DATA ] = { .type = NLA_NESTED },
1181
1259
};
1182
1260
1183
1261
static const struct nla_policy ifla_vfinfo_policy [IFLA_VF_INFO_MAX + 1 ] = {
@@ -1765,7 +1843,9 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
1765
1843
{
1766
1844
struct net * net = sock_net (skb -> sk );
1767
1845
const struct rtnl_link_ops * ops ;
1846
+ const struct rtnl_link_ops * m_ops = NULL ;
1768
1847
struct net_device * dev ;
1848
+ struct net_device * master_dev = NULL ;
1769
1849
struct ifinfomsg * ifm ;
1770
1850
char kind [MODULE_NAME_LEN ];
1771
1851
char ifname [IFNAMSIZ ];
@@ -1795,6 +1875,12 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
1795
1875
dev = NULL ;
1796
1876
}
1797
1877
1878
+ if (dev ) {
1879
+ master_dev = netdev_master_upper_dev_get (dev );
1880
+ if (master_dev )
1881
+ m_ops = master_dev -> rtnl_link_ops ;
1882
+ }
1883
+
1798
1884
err = validate_linkmsg (dev , tb );
1799
1885
if (err < 0 )
1800
1886
return err ;
@@ -1816,7 +1902,10 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
1816
1902
}
1817
1903
1818
1904
if (1 ) {
1819
- struct nlattr * attr [ops ? ops -> maxtype + 1 : 0 ], * * data = NULL ;
1905
+ struct nlattr * attr [ops ? ops -> maxtype + 1 : 0 ];
1906
+ struct nlattr * slave_attr [m_ops ? m_ops -> slave_maxtype + 1 : 0 ];
1907
+ struct nlattr * * data = NULL ;
1908
+ struct nlattr * * slave_data = NULL ;
1820
1909
struct net * dest_net ;
1821
1910
1822
1911
if (ops ) {
@@ -1835,6 +1924,24 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
1835
1924
}
1836
1925
}
1837
1926
1927
+ if (m_ops ) {
1928
+ if (m_ops -> slave_maxtype &&
1929
+ linkinfo [IFLA_INFO_SLAVE_DATA ]) {
1930
+ err = nla_parse_nested (slave_attr ,
1931
+ m_ops -> slave_maxtype ,
1932
+ linkinfo [IFLA_INFO_SLAVE_DATA ],
1933
+ m_ops -> slave_policy );
1934
+ if (err < 0 )
1935
+ return err ;
1936
+ slave_data = slave_attr ;
1937
+ }
1938
+ if (m_ops -> slave_validate ) {
1939
+ err = m_ops -> slave_validate (tb , slave_data );
1940
+ if (err < 0 )
1941
+ return err ;
1942
+ }
1943
+ }
1944
+
1838
1945
if (dev ) {
1839
1946
int modified = 0 ;
1840
1947
@@ -1854,6 +1961,17 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh)
1854
1961
modified = 1 ;
1855
1962
}
1856
1963
1964
+ if (linkinfo [IFLA_INFO_SLAVE_DATA ]) {
1965
+ if (!m_ops || !m_ops -> slave_changelink )
1966
+ return - EOPNOTSUPP ;
1967
+
1968
+ err = m_ops -> slave_changelink (master_dev , dev ,
1969
+ tb , slave_data );
1970
+ if (err < 0 )
1971
+ return err ;
1972
+ modified = 1 ;
1973
+ }
1974
+
1857
1975
return do_setlink (dev , ifm , tb , ifname , modified );
1858
1976
}
1859
1977
0 commit comments