@@ -1750,6 +1750,9 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
17501750 [IFLA_CARRIER_DOWN_COUNT ] = { .type = NLA_U32 },
17511751 [IFLA_MIN_MTU ] = { .type = NLA_U32 },
17521752 [IFLA_MAX_MTU ] = { .type = NLA_U32 },
1753+ [IFLA_PROP_LIST ] = { .type = NLA_NESTED },
1754+ [IFLA_ALT_IFNAME ] = { .type = NLA_STRING ,
1755+ .len = ALTIFNAMSIZ - 1 },
17531756};
17541757
17551758static const struct nla_policy ifla_info_policy [IFLA_INFO_MAX + 1 ] = {
@@ -3373,6 +3376,103 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
33733376 return err ;
33743377}
33753378
3379+ static int rtnl_alt_ifname (int cmd , struct net_device * dev , struct nlattr * attr ,
3380+ bool * changed , struct netlink_ext_ack * extack )
3381+ {
3382+ char * alt_ifname ;
3383+ int err ;
3384+
3385+ err = nla_validate (attr , attr -> nla_len , IFLA_MAX , ifla_policy , extack );
3386+ if (err )
3387+ return err ;
3388+
3389+ alt_ifname = nla_data (attr );
3390+ if (cmd == RTM_NEWLINKPROP ) {
3391+ alt_ifname = kstrdup (alt_ifname , GFP_KERNEL );
3392+ if (!alt_ifname )
3393+ return - ENOMEM ;
3394+ err = netdev_name_node_alt_create (dev , alt_ifname );
3395+ if (err ) {
3396+ kfree (alt_ifname );
3397+ return err ;
3398+ }
3399+ } else if (cmd == RTM_DELLINKPROP ) {
3400+ err = netdev_name_node_alt_destroy (dev , alt_ifname );
3401+ if (err )
3402+ return err ;
3403+ } else {
3404+ WARN_ON (1 );
3405+ return 0 ;
3406+ }
3407+
3408+ * changed = true;
3409+ return 0 ;
3410+ }
3411+
3412+ static int rtnl_linkprop (int cmd , struct sk_buff * skb , struct nlmsghdr * nlh ,
3413+ struct netlink_ext_ack * extack )
3414+ {
3415+ struct net * net = sock_net (skb -> sk );
3416+ struct nlattr * tb [IFLA_MAX + 1 ];
3417+ struct net_device * dev ;
3418+ struct ifinfomsg * ifm ;
3419+ bool changed = false;
3420+ struct nlattr * attr ;
3421+ int err , rem ;
3422+
3423+ err = nlmsg_parse (nlh , sizeof (* ifm ), tb , IFLA_MAX , ifla_policy , extack );
3424+ if (err )
3425+ return err ;
3426+
3427+ err = rtnl_ensure_unique_netns (tb , extack , true);
3428+ if (err )
3429+ return err ;
3430+
3431+ ifm = nlmsg_data (nlh );
3432+ if (ifm -> ifi_index > 0 ) {
3433+ dev = __dev_get_by_index (net , ifm -> ifi_index );
3434+ } else if (tb [IFLA_IFNAME ]) {
3435+ char ifname [IFNAMSIZ ];
3436+
3437+ nla_strlcpy (ifname , tb [IFLA_IFNAME ], IFNAMSIZ );
3438+ dev = __dev_get_by_name (net , ifname );
3439+ } else {
3440+ return - EINVAL ;
3441+ }
3442+
3443+ if (!dev )
3444+ return - ENODEV ;
3445+
3446+ if (!tb [IFLA_PROP_LIST ])
3447+ return 0 ;
3448+
3449+ nla_for_each_nested (attr , tb [IFLA_PROP_LIST ], rem ) {
3450+ switch (nla_type (attr )) {
3451+ case IFLA_ALT_IFNAME :
3452+ err = rtnl_alt_ifname (cmd , dev , attr , & changed , extack );
3453+ if (err )
3454+ return err ;
3455+ break ;
3456+ }
3457+ }
3458+
3459+ if (changed )
3460+ netdev_state_change (dev );
3461+ return 0 ;
3462+ }
3463+
3464+ static int rtnl_newlinkprop (struct sk_buff * skb , struct nlmsghdr * nlh ,
3465+ struct netlink_ext_ack * extack )
3466+ {
3467+ return rtnl_linkprop (RTM_NEWLINKPROP , skb , nlh , extack );
3468+ }
3469+
3470+ static int rtnl_dellinkprop (struct sk_buff * skb , struct nlmsghdr * nlh ,
3471+ struct netlink_ext_ack * extack )
3472+ {
3473+ return rtnl_linkprop (RTM_DELLINKPROP , skb , nlh , extack );
3474+ }
3475+
33763476static u16 rtnl_calcit (struct sk_buff * skb , struct nlmsghdr * nlh )
33773477{
33783478 struct net * net = sock_net (skb -> sk );
@@ -5331,6 +5431,9 @@ void __init rtnetlink_init(void)
53315431 rtnl_register (PF_UNSPEC , RTM_GETROUTE , NULL , rtnl_dump_all , 0 );
53325432 rtnl_register (PF_UNSPEC , RTM_GETNETCONF , NULL , rtnl_dump_all , 0 );
53335433
5434+ rtnl_register (PF_UNSPEC , RTM_NEWLINKPROP , rtnl_newlinkprop , NULL , 0 );
5435+ rtnl_register (PF_UNSPEC , RTM_DELLINKPROP , rtnl_dellinkprop , NULL , 0 );
5436+
53345437 rtnl_register (PF_BRIDGE , RTM_NEWNEIGH , rtnl_fdb_add , NULL , 0 );
53355438 rtnl_register (PF_BRIDGE , RTM_DELNEIGH , rtnl_fdb_del , NULL , 0 );
53365439 rtnl_register (PF_BRIDGE , RTM_GETNEIGH , rtnl_fdb_get , rtnl_fdb_dump , 0 );
0 commit comments