diff options
author | Nikita V. Shirokov <tehnerd@fb.com> | 2018-03-26 11:36:57 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-03-28 15:05:35 -0400 |
commit | 6f5c39fa5cd4a78c5432021e981aa8f79437a32c (patch) | |
tree | ca8000b083f974d4d87861ea89cb43e25049fa77 | |
parent | 20cfb7a04f0a8b7f8f45cf630e23524d51bb3cd9 (diff) |
bpf: Add sock_ops R/W access to ipv4 tos
Sample usage for tos ...
bpf_getsockopt(skops, SOL_IP, IP_TOS, &v, sizeof(v))
... where skops is a pointer to the ctx (struct bpf_sock_ops).
Signed-off-by: Nikita V. Shirokov <tehnerd@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r-- | net/core/filter.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 00c711c5f1a2..afd825534ac4 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -3462,6 +3462,27 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, | |||
3462 | ret = -EINVAL; | 3462 | ret = -EINVAL; |
3463 | } | 3463 | } |
3464 | #ifdef CONFIG_INET | 3464 | #ifdef CONFIG_INET |
3465 | } else if (level == SOL_IP) { | ||
3466 | if (optlen != sizeof(int) || sk->sk_family != AF_INET) | ||
3467 | return -EINVAL; | ||
3468 | |||
3469 | val = *((int *)optval); | ||
3470 | /* Only some options are supported */ | ||
3471 | switch (optname) { | ||
3472 | case IP_TOS: | ||
3473 | if (val < -1 || val > 0xff) { | ||
3474 | ret = -EINVAL; | ||
3475 | } else { | ||
3476 | struct inet_sock *inet = inet_sk(sk); | ||
3477 | |||
3478 | if (val == -1) | ||
3479 | val = 0; | ||
3480 | inet->tos = val; | ||
3481 | } | ||
3482 | break; | ||
3483 | default: | ||
3484 | ret = -EINVAL; | ||
3485 | } | ||
3465 | #if IS_ENABLED(CONFIG_IPV6) | 3486 | #if IS_ENABLED(CONFIG_IPV6) |
3466 | } else if (level == SOL_IPV6) { | 3487 | } else if (level == SOL_IPV6) { |
3467 | if (optlen != sizeof(int) || sk->sk_family != AF_INET6) | 3488 | if (optlen != sizeof(int) || sk->sk_family != AF_INET6) |
@@ -3561,6 +3582,20 @@ BPF_CALL_5(bpf_getsockopt, struct bpf_sock_ops_kern *, bpf_sock, | |||
3561 | } else { | 3582 | } else { |
3562 | goto err_clear; | 3583 | goto err_clear; |
3563 | } | 3584 | } |
3585 | } else if (level == SOL_IP) { | ||
3586 | struct inet_sock *inet = inet_sk(sk); | ||
3587 | |||
3588 | if (optlen != sizeof(int) || sk->sk_family != AF_INET) | ||
3589 | goto err_clear; | ||
3590 | |||
3591 | /* Only some options are supported */ | ||
3592 | switch (optname) { | ||
3593 | case IP_TOS: | ||
3594 | *((int *)optval) = (int)inet->tos; | ||
3595 | break; | ||
3596 | default: | ||
3597 | goto err_clear; | ||
3598 | } | ||
3564 | #if IS_ENABLED(CONFIG_IPV6) | 3599 | #if IS_ENABLED(CONFIG_IPV6) |
3565 | } else if (level == SOL_IPV6) { | 3600 | } else if (level == SOL_IPV6) { |
3566 | struct ipv6_pinfo *np = inet6_sk(sk); | 3601 | struct ipv6_pinfo *np = inet6_sk(sk); |