@@ -338,6 +338,7 @@ static int netkit_new_link(struct net *peer_net, struct net_device *dev,
338338 enum netkit_scrub scrub_peer = NETKIT_SCRUB_DEFAULT ;
339339 enum netkit_mode mode = NETKIT_L3 ;
340340 unsigned char ifname_assign_type ;
341+ u16 headroom = 0 , tailroom = 0 ;
341342 struct ifinfomsg * ifmp = NULL ;
342343 struct net_device * peer ;
343344 char ifname [IFNAMSIZ ];
@@ -371,6 +372,10 @@ static int netkit_new_link(struct net *peer_net, struct net_device *dev,
371372 if (err < 0 )
372373 return err ;
373374 }
375+ if (data [IFLA_NETKIT_HEADROOM ])
376+ headroom = nla_get_u16 (data [IFLA_NETKIT_HEADROOM ]);
377+ if (data [IFLA_NETKIT_TAILROOM ])
378+ tailroom = nla_get_u16 (data [IFLA_NETKIT_TAILROOM ]);
374379 }
375380
376381 if (ifmp && tbp [IFLA_IFNAME ]) {
@@ -390,6 +395,14 @@ static int netkit_new_link(struct net *peer_net, struct net_device *dev,
390395 return PTR_ERR (peer );
391396
392397 netif_inherit_tso_max (peer , dev );
398+ if (headroom ) {
399+ peer -> needed_headroom = headroom ;
400+ dev -> needed_headroom = headroom ;
401+ }
402+ if (tailroom ) {
403+ peer -> needed_tailroom = tailroom ;
404+ dev -> needed_tailroom = tailroom ;
405+ }
393406
394407 if (mode == NETKIT_L2 && !(ifmp && tbp [IFLA_ADDRESS ]))
395408 eth_hw_addr_random (peer );
@@ -401,6 +414,7 @@ static int netkit_new_link(struct net *peer_net, struct net_device *dev,
401414 nk -> policy = policy_peer ;
402415 nk -> scrub = scrub_peer ;
403416 nk -> mode = mode ;
417+ nk -> headroom = headroom ;
404418 bpf_mprog_bundle_init (& nk -> bundle );
405419
406420 err = register_netdevice (peer );
@@ -426,6 +440,7 @@ static int netkit_new_link(struct net *peer_net, struct net_device *dev,
426440 nk -> policy = policy_prim ;
427441 nk -> scrub = scrub_prim ;
428442 nk -> mode = mode ;
443+ nk -> headroom = headroom ;
429444 bpf_mprog_bundle_init (& nk -> bundle );
430445
431446 err = register_netdevice (dev );
@@ -850,36 +865,33 @@ static int netkit_change_link(struct net_device *dev, struct nlattr *tb[],
850865 struct net_device * peer = rtnl_dereference (nk -> peer );
851866 enum netkit_action policy ;
852867 struct nlattr * attr ;
853- int err ;
868+ int err , i ;
869+ struct {
870+ u32 attr ;
871+ char * name ;
872+ } fixed_params [] = {
873+ { IFLA_NETKIT_MODE , "operating mode" },
874+ { IFLA_NETKIT_SCRUB , "scrubbing" },
875+ { IFLA_NETKIT_PEER_SCRUB , "peer scrubbing" },
876+ { IFLA_NETKIT_PEER_INFO , "peer info" },
877+ { IFLA_NETKIT_HEADROOM , "headroom" },
878+ { IFLA_NETKIT_TAILROOM , "tailroom" },
879+ };
854880
855881 if (!nk -> primary ) {
856882 NL_SET_ERR_MSG (extack ,
857883 "netkit link settings can be changed only through the primary device" );
858884 return - EACCES ;
859885 }
860886
861- if (data [IFLA_NETKIT_MODE ]) {
862- NL_SET_ERR_MSG_ATTR (extack , data [IFLA_NETKIT_MODE ],
863- "netkit link operating mode cannot be changed after device creation" );
864- return - EACCES ;
865- }
866-
867- if (data [IFLA_NETKIT_SCRUB ]) {
868- NL_SET_ERR_MSG_ATTR (extack , data [IFLA_NETKIT_SCRUB ],
869- "netkit scrubbing cannot be changed after device creation" );
870- return - EACCES ;
871- }
872-
873- if (data [IFLA_NETKIT_PEER_SCRUB ]) {
874- NL_SET_ERR_MSG_ATTR (extack , data [IFLA_NETKIT_PEER_SCRUB ],
875- "netkit scrubbing cannot be changed after device creation" );
876- return - EACCES ;
877- }
878-
879- if (data [IFLA_NETKIT_PEER_INFO ]) {
880- NL_SET_ERR_MSG_ATTR (extack , data [IFLA_NETKIT_PEER_INFO ],
881- "netkit peer info cannot be changed after device creation" );
882- return - EINVAL ;
887+ for (i = 0 ; i < ARRAY_SIZE (fixed_params ); i ++ ) {
888+ attr = data [fixed_params [i ].attr ];
889+ if (attr ) {
890+ NL_SET_ERR_MSG_ATTR_FMT (extack , attr ,
891+ "netkit link %s cannot be changed after device creation" ,
892+ fixed_params [i ].name );
893+ return - EACCES ;
894+ }
883895 }
884896
885897 if (data [IFLA_NETKIT_POLICY ]) {
@@ -914,6 +926,8 @@ static size_t netkit_get_size(const struct net_device *dev)
914926 nla_total_size (sizeof (u32 )) + /* IFLA_NETKIT_PEER_SCRUB */
915927 nla_total_size (sizeof (u32 )) + /* IFLA_NETKIT_MODE */
916928 nla_total_size (sizeof (u8 )) + /* IFLA_NETKIT_PRIMARY */
929+ nla_total_size (sizeof (u16 )) + /* IFLA_NETKIT_HEADROOM */
930+ nla_total_size (sizeof (u16 )) + /* IFLA_NETKIT_TAILROOM */
917931 0 ;
918932}
919933
@@ -930,6 +944,10 @@ static int netkit_fill_info(struct sk_buff *skb, const struct net_device *dev)
930944 return - EMSGSIZE ;
931945 if (nla_put_u32 (skb , IFLA_NETKIT_SCRUB , nk -> scrub ))
932946 return - EMSGSIZE ;
947+ if (nla_put_u16 (skb , IFLA_NETKIT_HEADROOM , dev -> needed_headroom ))
948+ return - EMSGSIZE ;
949+ if (nla_put_u16 (skb , IFLA_NETKIT_TAILROOM , dev -> needed_tailroom ))
950+ return - EMSGSIZE ;
933951
934952 if (peer ) {
935953 nk = netkit_priv (peer );
@@ -947,6 +965,8 @@ static const struct nla_policy netkit_policy[IFLA_NETKIT_MAX + 1] = {
947965 [IFLA_NETKIT_MODE ] = NLA_POLICY_MAX (NLA_U32 , NETKIT_L3 ),
948966 [IFLA_NETKIT_POLICY ] = { .type = NLA_U32 },
949967 [IFLA_NETKIT_PEER_POLICY ] = { .type = NLA_U32 },
968+ [IFLA_NETKIT_HEADROOM ] = { .type = NLA_U16 },
969+ [IFLA_NETKIT_TAILROOM ] = { .type = NLA_U16 },
950970 [IFLA_NETKIT_SCRUB ] = NLA_POLICY_MAX (NLA_U32 , NETKIT_SCRUB_DEFAULT ),
951971 [IFLA_NETKIT_PEER_SCRUB ] = NLA_POLICY_MAX (NLA_U32 , NETKIT_SCRUB_DEFAULT ),
952972 [IFLA_NETKIT_PRIMARY ] = { .type = NLA_REJECT ,
0 commit comments