@@ -3505,6 +3505,78 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
3505
3505
}
3506
3506
EXPORT_SYMBOL (rtnl_create_link );
3507
3507
3508
+ struct rtnl_newlink_tbs {
3509
+ struct nlattr * tb [IFLA_MAX + 1 ];
3510
+ struct nlattr * linkinfo [IFLA_INFO_MAX + 1 ];
3511
+ struct nlattr * attr [RTNL_MAX_TYPE + 1 ];
3512
+ struct nlattr * slave_attr [RTNL_SLAVE_MAX_TYPE + 1 ];
3513
+ };
3514
+
3515
+ static int rtnl_changelink (const struct sk_buff * skb , struct nlmsghdr * nlh ,
3516
+ const struct rtnl_link_ops * ops ,
3517
+ struct net_device * dev ,
3518
+ struct rtnl_newlink_tbs * tbs ,
3519
+ struct nlattr * * data ,
3520
+ struct netlink_ext_ack * extack )
3521
+ {
3522
+ struct nlattr * * const linkinfo = tbs -> linkinfo ;
3523
+ struct nlattr * * const tb = tbs -> tb ;
3524
+ int status = 0 ;
3525
+ int err ;
3526
+
3527
+ if (nlh -> nlmsg_flags & NLM_F_EXCL )
3528
+ return - EEXIST ;
3529
+
3530
+ if (nlh -> nlmsg_flags & NLM_F_REPLACE )
3531
+ return - EOPNOTSUPP ;
3532
+
3533
+ if (linkinfo [IFLA_INFO_DATA ]) {
3534
+ if (!ops || ops != dev -> rtnl_link_ops || !ops -> changelink )
3535
+ return - EOPNOTSUPP ;
3536
+
3537
+ err = ops -> changelink (dev , tb , data , extack );
3538
+ if (err < 0 )
3539
+ return err ;
3540
+
3541
+ status |= DO_SETLINK_NOTIFY ;
3542
+ }
3543
+
3544
+ if (linkinfo [IFLA_INFO_SLAVE_DATA ]) {
3545
+ const struct rtnl_link_ops * m_ops = NULL ;
3546
+ struct nlattr * * slave_data = NULL ;
3547
+ struct net_device * master_dev ;
3548
+
3549
+ master_dev = netdev_master_upper_dev_get (dev );
3550
+ if (master_dev )
3551
+ m_ops = master_dev -> rtnl_link_ops ;
3552
+
3553
+ if (!m_ops || !m_ops -> slave_changelink )
3554
+ return - EOPNOTSUPP ;
3555
+
3556
+ if (m_ops -> slave_maxtype > RTNL_SLAVE_MAX_TYPE )
3557
+ return - EINVAL ;
3558
+
3559
+ if (m_ops -> slave_maxtype ) {
3560
+ err = nla_parse_nested_deprecated (tbs -> slave_attr ,
3561
+ m_ops -> slave_maxtype ,
3562
+ linkinfo [IFLA_INFO_SLAVE_DATA ],
3563
+ m_ops -> slave_policy , extack );
3564
+ if (err < 0 )
3565
+ return err ;
3566
+
3567
+ slave_data = tbs -> slave_attr ;
3568
+ }
3569
+
3570
+ err = m_ops -> slave_changelink (master_dev , dev , tb , slave_data , extack );
3571
+ if (err < 0 )
3572
+ return err ;
3573
+
3574
+ status |= DO_SETLINK_NOTIFY ;
3575
+ }
3576
+
3577
+ return do_setlink (skb , dev , nlmsg_data (nlh ), extack , tb , status );
3578
+ }
3579
+
3508
3580
static int rtnl_group_changelink (const struct sk_buff * skb ,
3509
3581
struct net * net , int group ,
3510
3582
struct ifinfomsg * ifm ,
@@ -3617,24 +3689,14 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
3617
3689
goto out ;
3618
3690
}
3619
3691
3620
- struct rtnl_newlink_tbs {
3621
- struct nlattr * tb [IFLA_MAX + 1 ];
3622
- struct nlattr * linkinfo [IFLA_INFO_MAX + 1 ];
3623
- struct nlattr * attr [RTNL_MAX_TYPE + 1 ];
3624
- struct nlattr * slave_attr [RTNL_SLAVE_MAX_TYPE + 1 ];
3625
- };
3626
-
3627
3692
static int __rtnl_newlink (struct sk_buff * skb , struct nlmsghdr * nlh ,
3628
3693
struct rtnl_newlink_tbs * tbs ,
3629
3694
struct netlink_ext_ack * extack )
3630
3695
{
3631
3696
struct nlattr * * const linkinfo = tbs -> linkinfo ;
3632
3697
struct nlattr * * const tb = tbs -> tb ;
3633
- const struct rtnl_link_ops * m_ops ;
3634
- struct net_device * master_dev ;
3635
3698
struct net * net = sock_net (skb -> sk );
3636
3699
const struct rtnl_link_ops * ops ;
3637
- struct nlattr * * slave_data ;
3638
3700
char kind [MODULE_NAME_LEN ];
3639
3701
struct net_device * dev ;
3640
3702
struct ifinfomsg * ifm ;
@@ -3669,14 +3731,6 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3669
3731
dev = NULL ;
3670
3732
}
3671
3733
3672
- master_dev = NULL ;
3673
- m_ops = NULL ;
3674
- if (dev ) {
3675
- master_dev = netdev_master_upper_dev_get (dev );
3676
- if (master_dev )
3677
- m_ops = master_dev -> rtnl_link_ops ;
3678
- }
3679
-
3680
3734
if (tb [IFLA_LINKINFO ]) {
3681
3735
err = nla_parse_nested_deprecated (linkinfo , IFLA_INFO_MAX ,
3682
3736
tb [IFLA_LINKINFO ],
@@ -3715,56 +3769,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3715
3769
}
3716
3770
}
3717
3771
3718
- slave_data = NULL ;
3719
- if (m_ops ) {
3720
- if (m_ops -> slave_maxtype > RTNL_SLAVE_MAX_TYPE )
3721
- return - EINVAL ;
3722
-
3723
- if (m_ops -> slave_maxtype &&
3724
- linkinfo [IFLA_INFO_SLAVE_DATA ]) {
3725
- err = nla_parse_nested_deprecated (tbs -> slave_attr ,
3726
- m_ops -> slave_maxtype ,
3727
- linkinfo [IFLA_INFO_SLAVE_DATA ],
3728
- m_ops -> slave_policy ,
3729
- extack );
3730
- if (err < 0 )
3731
- return err ;
3732
- slave_data = tbs -> slave_attr ;
3733
- }
3734
- }
3735
-
3736
- if (dev ) {
3737
- int status = 0 ;
3738
-
3739
- if (nlh -> nlmsg_flags & NLM_F_EXCL )
3740
- return - EEXIST ;
3741
- if (nlh -> nlmsg_flags & NLM_F_REPLACE )
3742
- return - EOPNOTSUPP ;
3743
-
3744
- if (linkinfo [IFLA_INFO_DATA ]) {
3745
- if (!ops || ops != dev -> rtnl_link_ops ||
3746
- !ops -> changelink )
3747
- return - EOPNOTSUPP ;
3748
-
3749
- err = ops -> changelink (dev , tb , data , extack );
3750
- if (err < 0 )
3751
- return err ;
3752
- status |= DO_SETLINK_NOTIFY ;
3753
- }
3754
-
3755
- if (linkinfo [IFLA_INFO_SLAVE_DATA ]) {
3756
- if (!m_ops || !m_ops -> slave_changelink )
3757
- return - EOPNOTSUPP ;
3758
-
3759
- err = m_ops -> slave_changelink (master_dev , dev , tb ,
3760
- slave_data , extack );
3761
- if (err < 0 )
3762
- return err ;
3763
- status |= DO_SETLINK_NOTIFY ;
3764
- }
3765
-
3766
- return do_setlink (skb , dev , ifm , extack , tb , status );
3767
- }
3772
+ if (dev )
3773
+ return rtnl_changelink (skb , nlh , ops , dev , tbs , data , extack );
3768
3774
3769
3775
if (!(nlh -> nlmsg_flags & NLM_F_CREATE )) {
3770
3776
/* No dev found and NLM_F_CREATE not set. Requested dev does not exist,
0 commit comments