Skip to content

Commit b9ed315

Browse files
committed
netkit: Allow for configuring needed_{head,tail}room
Allow the user to configure needed_{head,tail}room for both netkit devices. The idea is similar to 163e529 ("veth: implement ndo_set_rx_headroom") with the difference that the two parameters can be specified upon device creation. By default the current behavior stays as is which is needed_{head,tail}room is 0. In case of Cilium, for example, the netkit devices are not enslaved into a bridge or openvswitch device (rather, BPF-based redirection is used out of tcx), and as such these parameters are not propagated into the Pod's netns via peer device. Given Cilium can run in vxlan/geneve tunneling mode (needed_headroom) and/or be used in combination with WireGuard (needed_{head,tail}room), allow the Cilium CNI plugin to specify these two upon netkit device creation. Signed-off-by: Daniel Borkmann <[email protected]> Reviewed-by: Jakub Kicinski <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent dad704e commit b9ed315

File tree

3 files changed

+47
-23
lines changed

3 files changed

+47
-23
lines changed

drivers/net/netkit.c

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
static const 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,

include/uapi/linux/if_link.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,8 @@ enum {
13151315
IFLA_NETKIT_MODE,
13161316
IFLA_NETKIT_SCRUB,
13171317
IFLA_NETKIT_PEER_SCRUB,
1318+
IFLA_NETKIT_HEADROOM,
1319+
IFLA_NETKIT_TAILROOM,
13181320
__IFLA_NETKIT_MAX,
13191321
};
13201322
#define IFLA_NETKIT_MAX (__IFLA_NETKIT_MAX - 1)

tools/include/uapi/linux/if_link.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,8 @@ enum {
13151315
IFLA_NETKIT_MODE,
13161316
IFLA_NETKIT_SCRUB,
13171317
IFLA_NETKIT_PEER_SCRUB,
1318+
IFLA_NETKIT_HEADROOM,
1319+
IFLA_NETKIT_TAILROOM,
13181320
__IFLA_NETKIT_MAX,
13191321
};
13201322
#define IFLA_NETKIT_MAX (__IFLA_NETKIT_MAX - 1)

0 commit comments

Comments
 (0)