On 02/17/2017 05:01 AM, David Ahern wrote:
On 2/16/17 3:08 AM, Daniel Borkmann wrote:
Is there anything that speaks against doing the comparison itself
outside of the helper? Meaning, the helper would get a buffer
passed from stack f.e. struct foo { u64 ns_dev; u64 ns_ino; }
and fills both out with the netns info belonging to the sk/skb.
How do you handle CONFIG_NET_NS not set?
You call something like bpf_get_netns_id(sk, &foo), it has to exist
regardless of the config. What should it return if netns is disabled?
In rough semi pseudo code, it could look like the below. In case we have
!CONFIG_NET_NS then that would be hidden behind the netns_get_kstat() (or
whatever function name it has) as a static inline that just returns an
error such as -ENOTSUPP.
If the entity installing the program is aware that CONFIG_NET_NS is set
and that the input is exactly of size struct bpf_netns, then it can also
skip the error test in the BPF program itself. Anyway, just a thought
so that the helper could be more flexible and used as a key for lookups
on maps, too ...
BPF_CALL_3(bpf_sk_netns_get, struct sock *, sk, struct bpf_netns *, ns,
u32, size)
{
struct ns_kstat tmp;
int ret;
if (unlikely(size != sizeof(struct bpf_netns)))
return -EINVAL;
ret = netns_get_kstat(sock_net(sk), &tmp);
if (unlikely(ret))
return ret;
ns->dev = tmp.dev;
ns->ino = tmp.ino;
return 0;
}
static const struct bpf_func_proto bpf_sk_netns_get_proto = {
.func = bpf_sk_netns_get,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_PTR_TO_UNINIT_MEM,
.arg3_type = ARG_CONST_SIZE,
};
Thanks,
Daniel