UPSTREAM: bpf: Allow to specify ifindex for skb in bpf_prog_test_run_skb
Now skb->dev is unconditionally set to the loopback device in current net namespace. But if we want to test bpf program which contains code branch based on ifindex condition (eg filters out localhost packets) it is useful to allow specifying of ifindex from userspace. This patch adds such option through ctx_in (__sk_buff) parameter. Change-Id: Ib0568cdb7b429771ee3647aaef68a929c6828799 Signed-off-by: Dmitry Yakunin <zeil@yandex-team.ru> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20200803090545.82046-3-zeil@yandex-team.ru
This commit is contained in:
committed by
Michael Bestas
parent
e70ba00513
commit
5544575953
@@ -331,6 +331,12 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
|
||||
/* priority is allowed */
|
||||
|
||||
if (!range_is_zero(__skb, offsetofend(struct __sk_buff, priority),
|
||||
offsetof(struct __sk_buff, ifindex)))
|
||||
return -EINVAL;
|
||||
|
||||
/* ifindex is allowed */
|
||||
|
||||
if (!range_is_zero(__skb, offsetofend(struct __sk_buff, ifindex),
|
||||
offsetof(struct __sk_buff, cb)))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -385,6 +391,7 @@ static void convert_skb_to___skb(struct sk_buff *skb, struct __sk_buff *__skb)
|
||||
|
||||
__skb->mark = skb->mark;
|
||||
__skb->priority = skb->priority;
|
||||
__skb->ifindex = skb->dev->ifindex;
|
||||
__skb->tstamp = skb->tstamp;
|
||||
memcpy(__skb->cb, &cb->data, QDISC_CB_PRIV_LEN);
|
||||
__skb->wire_len = cb->pkt_len;
|
||||
@@ -395,6 +402,8 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr)
|
||||
{
|
||||
bool is_l2 = false, is_direct_pkt_access = false;
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
struct net_device *dev = net->loopback_dev;
|
||||
u32 size = kattr->test.data_size_in;
|
||||
u32 repeat = kattr->test.repeat;
|
||||
struct __sk_buff *ctx = NULL;
|
||||
@@ -436,7 +445,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
kfree(ctx);
|
||||
return -ENOMEM;
|
||||
}
|
||||
sock_net_set(sk, current->nsproxy->net_ns);
|
||||
sock_net_set(sk, net);
|
||||
sock_init_data(NULL, sk);
|
||||
|
||||
skb = build_skb(data, 0);
|
||||
@@ -450,7 +459,14 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
|
||||
skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
|
||||
__skb_put(skb, size);
|
||||
skb->protocol = eth_type_trans(skb, current->nsproxy->net_ns->loopback_dev);
|
||||
if (ctx && ctx->ifindex > 1) {
|
||||
dev = dev_get_by_index(net, ctx->ifindex);
|
||||
if (!dev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
switch (skb->protocol) {
|
||||
@@ -506,6 +522,8 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
ret = bpf_ctx_finish(kattr, uattr, ctx,
|
||||
sizeof(struct __sk_buff));
|
||||
out:
|
||||
if (dev && dev != net->loopback_dev)
|
||||
dev_put(dev);
|
||||
kfree_skb(skb);
|
||||
bpf_sk_storage_free(sk);
|
||||
kfree(sk);
|
||||
|
||||
Reference in New Issue
Block a user