aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita V. Shirokov <tehnerd@fb.com>2018-03-26 11:36:57 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-03-28 15:05:35 -0400
commit6f5c39fa5cd4a78c5432021e981aa8f79437a32c (patch)
treeca8000b083f974d4d87861ea89cb43e25049fa77
parent20cfb7a04f0a8b7f8f45cf630e23524d51bb3cd9 (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.c35
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);