linux_dsm_epyc7002/net/core
Andrey Ignatov 4fbac77d2d bpf: Hooks for sys_bind
== The problem ==

There is a use-case when all processes inside a cgroup should use one
single IP address on a host that has multiple IP configured.  Those
processes should use the IP for both ingress and egress, for TCP and UDP
traffic. So TCP/UDP servers should be bound to that IP to accept
incoming connections on it, and TCP/UDP clients should make outgoing
connections from that IP. It should not require changing application
code since it's often not possible.

Currently it's solved by intercepting glibc wrappers around syscalls
such as `bind(2)` and `connect(2)`. It's done by a shared library that
is preloaded for every process in a cgroup so that whenever TCP/UDP
server calls `bind(2)`, the library replaces IP in sockaddr before
passing arguments to syscall. When application calls `connect(2)` the
library transparently binds the local end of connection to that IP
(`bind(2)` with `IP_BIND_ADDRESS_NO_PORT` to avoid performance penalty).

Shared library approach is fragile though, e.g.:
* some applications clear env vars (incl. `LD_PRELOAD`);
* `/etc/ld.so.preload` doesn't help since some applications are linked
  with option `-z nodefaultlib`;
* other applications don't use glibc and there is nothing to intercept.

== The solution ==

The patch provides much more reliable in-kernel solution for the 1st
part of the problem: binding TCP/UDP servers on desired IP. It does not
depend on application environment and implementation details (whether
glibc is used or not).

It adds new eBPF program type `BPF_PROG_TYPE_CGROUP_SOCK_ADDR` and
attach types `BPF_CGROUP_INET4_BIND` and `BPF_CGROUP_INET6_BIND`
(similar to already existing `BPF_CGROUP_INET_SOCK_CREATE`).

The new program type is intended to be used with sockets (`struct sock`)
in a cgroup and provided by user `struct sockaddr`. Pointers to both of
them are parts of the context passed to programs of newly added types.

The new attach types provides hooks in `bind(2)` system call for both
IPv4 and IPv6 so that one can write a program to override IP addresses
and ports user program tries to bind to and apply such a program for
whole cgroup.

== Implementation notes ==

[1]
Separate attach types for `AF_INET` and `AF_INET6` are added
intentionally to prevent reading/writing to offsets that don't make
sense for corresponding socket family. E.g. if user passes `sockaddr_in`
it doesn't make sense to read from / write to `user_ip6[]` context
fields.

[2]
The write access to `struct bpf_sock_addr_kern` is implemented using
special field as an additional "register".

There are just two registers in `sock_addr_convert_ctx_access`: `src`
with value to write and `dst` with pointer to context that can't be
changed not to break later instructions. But the fields, allowed to
write to, are not available directly and to access them address of
corresponding pointer has to be loaded first. To get additional register
the 1st not used by `src` and `dst` one is taken, its content is saved
to `bpf_sock_addr_kern.tmp_reg`, then the register is used to load
address of pointer field, and finally the register's content is restored
from the temporary field after writing `src` value.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-03-31 02:15:18 +02:00
..
datagram.c vfs: do bulk POLL* -> EPOLL* replacement 2018-02-11 14:34:03 -08:00
dev_addr_lists.c
dev_ioctl.c net: don't unnecessarily load kernel modules in dev_ioctl() 2018-03-07 15:12:58 -05:00
dev.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2018-03-23 11:31:58 -04:00
devlink.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2018-03-23 11:31:58 -04:00
drop_monitor.c
dst_cache.c net: core: dst_cache_set_ip6: Rename 'addr' parameter to 'saddr' for consistency 2018-03-05 12:52:45 -05:00
dst.c
ethtool.c net: ethtool: extend RXNFC API to support RSS spreading of filter matches 2018-03-08 21:54:52 -05:00
fib_notifier.c net: Convert fib_* pernet_operations, registered via subsys_initcall 2018-02-13 10:36:07 -05:00
fib_rules.c net: fib_rules: support for match on ip_proto, sport and dport 2018-02-28 22:44:43 -05:00
filter.c bpf: Hooks for sys_bind 2018-03-31 02:15:18 +02:00
flow_dissector.c net: Remove unused get_hash_from_flow functions 2018-03-04 13:04:23 -05:00
gen_estimator.c net_sched: gen_estimator: fix broken estimators based on percpu stats 2018-02-23 12:35:46 -05:00
gen_stats.c
gro_cells.c
hwbm.c
link_watch.c
lwt_bpf.c
lwtunnel.c
Makefile
neighbour.c
net_namespace.c net: Replace ip_ra_lock with per-net mutex 2018-03-22 15:12:56 -04:00
net-procfs.c net: Convert pernet_subsys ops, registered via net_dev_init() 2018-02-13 10:36:07 -05:00
net-sysfs.c
net-sysfs.h
net-traces.c
netclassid_cgroup.c
netevent.c
netpoll.c
netprio_cgroup.c
pktgen.c pktgen: Fix memory leak in pktgen_if_write 2018-03-14 10:02:15 -04:00
ptp_classifier.c
request_sock.c
rtnetlink.c net: Add rtnl_lock_killable() 2018-03-16 12:31:19 -04:00
scm.c
secure_seq.c
skbuff.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2018-03-23 11:31:58 -04:00
sock_diag.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2018-03-23 11:31:58 -04:00
sock_reuseport.c
sock.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2018-03-23 11:31:58 -04:00
stream.c vfs: do bulk POLL* -> EPOLL* replacement 2018-02-11 14:34:03 -08:00
sysctl_net_core.c net: do not create fallback tunnels for non-default namespaces 2018-03-09 11:23:11 -05:00
timestamping.c
tso.c
utils.c
xdp.c