aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/filter.c86
-rw-r--r--net/core/sock.c4
-rw-r--r--net/core/sock_reuseport.c24
3 files changed, 114 insertions, 0 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index 949adc3d9abb..2014d76e0d2a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -5695,6 +5695,46 @@ BPF_CALL_1(bpf_skb_ecn_set_ce, struct sk_buff *, skb)
5695 return INET_ECN_set_ce(skb); 5695 return INET_ECN_set_ce(skb);
5696} 5696}
5697 5697
5698bool bpf_xdp_sock_is_valid_access(int off, int size, enum bpf_access_type type,
5699 struct bpf_insn_access_aux *info)
5700{
5701 if (off < 0 || off >= offsetofend(struct bpf_xdp_sock, queue_id))
5702 return false;
5703
5704 if (off % size != 0)
5705 return false;
5706
5707 switch (off) {
5708 default:
5709 return size == sizeof(__u32);
5710 }
5711}
5712
5713u32 bpf_xdp_sock_convert_ctx_access(enum bpf_access_type type,
5714 const struct bpf_insn *si,
5715 struct bpf_insn *insn_buf,
5716 struct bpf_prog *prog, u32 *target_size)
5717{
5718 struct bpf_insn *insn = insn_buf;
5719
5720#define BPF_XDP_SOCK_GET(FIELD) \
5721 do { \
5722 BUILD_BUG_ON(FIELD_SIZEOF(struct xdp_sock, FIELD) > \
5723 FIELD_SIZEOF(struct bpf_xdp_sock, FIELD)); \
5724 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_sock, FIELD),\
5725 si->dst_reg, si->src_reg, \
5726 offsetof(struct xdp_sock, FIELD)); \
5727 } while (0)
5728
5729 switch (si->off) {
5730 case offsetof(struct bpf_xdp_sock, queue_id):
5731 BPF_XDP_SOCK_GET(queue_id);
5732 break;
5733 }
5734
5735 return insn - insn_buf;
5736}
5737
5698static const struct bpf_func_proto bpf_skb_ecn_set_ce_proto = { 5738static const struct bpf_func_proto bpf_skb_ecn_set_ce_proto = {
5699 .func = bpf_skb_ecn_set_ce, 5739 .func = bpf_skb_ecn_set_ce,
5700 .gpl_only = false, 5740 .gpl_only = false,
@@ -5897,6 +5937,10 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
5897 case BPF_FUNC_skc_lookup_tcp: 5937 case BPF_FUNC_skc_lookup_tcp:
5898 return &bpf_sock_addr_skc_lookup_tcp_proto; 5938 return &bpf_sock_addr_skc_lookup_tcp_proto;
5899#endif /* CONFIG_INET */ 5939#endif /* CONFIG_INET */
5940 case BPF_FUNC_sk_storage_get:
5941 return &bpf_sk_storage_get_proto;
5942 case BPF_FUNC_sk_storage_delete:
5943 return &bpf_sk_storage_delete_proto;
5900 default: 5944 default:
5901 return bpf_base_func_proto(func_id); 5945 return bpf_base_func_proto(func_id);
5902 } 5946 }
@@ -5934,6 +5978,10 @@ cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
5934 return &bpf_sk_storage_get_proto; 5978 return &bpf_sk_storage_get_proto;
5935 case BPF_FUNC_sk_storage_delete: 5979 case BPF_FUNC_sk_storage_delete:
5936 return &bpf_sk_storage_delete_proto; 5980 return &bpf_sk_storage_delete_proto;
5981#ifdef CONFIG_SOCK_CGROUP_DATA
5982 case BPF_FUNC_skb_cgroup_id:
5983 return &bpf_skb_cgroup_id_proto;
5984#endif
5937#ifdef CONFIG_INET 5985#ifdef CONFIG_INET
5938 case BPF_FUNC_tcp_sock: 5986 case BPF_FUNC_tcp_sock:
5939 return &bpf_tcp_sock_proto; 5987 return &bpf_tcp_sock_proto;
@@ -6114,6 +6162,14 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
6114 return &bpf_get_local_storage_proto; 6162 return &bpf_get_local_storage_proto;
6115 case BPF_FUNC_perf_event_output: 6163 case BPF_FUNC_perf_event_output:
6116 return &bpf_sockopt_event_output_proto; 6164 return &bpf_sockopt_event_output_proto;
6165 case BPF_FUNC_sk_storage_get:
6166 return &bpf_sk_storage_get_proto;
6167 case BPF_FUNC_sk_storage_delete:
6168 return &bpf_sk_storage_delete_proto;
6169#ifdef CONFIG_INET
6170 case BPF_FUNC_tcp_sock:
6171 return &bpf_tcp_sock_proto;
6172#endif /* CONFIG_INET */
6117 default: 6173 default:
6118 return bpf_base_func_proto(func_id); 6174 return bpf_base_func_proto(func_id);
6119 } 6175 }
@@ -6801,6 +6857,13 @@ static bool sock_addr_is_valid_access(int off, int size,
6801 if (size != size_default) 6857 if (size != size_default)
6802 return false; 6858 return false;
6803 break; 6859 break;
6860 case offsetof(struct bpf_sock_addr, sk):
6861 if (type != BPF_READ)
6862 return false;
6863 if (size != sizeof(__u64))
6864 return false;
6865 info->reg_type = PTR_TO_SOCKET;
6866 break;
6804 default: 6867 default:
6805 if (type == BPF_READ) { 6868 if (type == BPF_READ) {
6806 if (size != size_default) 6869 if (size != size_default)
@@ -6844,6 +6907,11 @@ static bool sock_ops_is_valid_access(int off, int size,
6844 if (size != sizeof(__u64)) 6907 if (size != sizeof(__u64))
6845 return false; 6908 return false;
6846 break; 6909 break;
6910 case offsetof(struct bpf_sock_ops, sk):
6911 if (size != sizeof(__u64))
6912 return false;
6913 info->reg_type = PTR_TO_SOCKET_OR_NULL;
6914 break;
6847 default: 6915 default:
6848 if (size != size_default) 6916 if (size != size_default)
6849 return false; 6917 return false;
@@ -7751,6 +7819,11 @@ static u32 sock_addr_convert_ctx_access(enum bpf_access_type type,
7751 struct bpf_sock_addr_kern, struct in6_addr, t_ctx, 7819 struct bpf_sock_addr_kern, struct in6_addr, t_ctx,
7752 s6_addr32[0], BPF_SIZE(si->code), off, tmp_reg); 7820 s6_addr32[0], BPF_SIZE(si->code), off, tmp_reg);
7753 break; 7821 break;
7822 case offsetof(struct bpf_sock_addr, sk):
7823 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sock_addr_kern, sk),
7824 si->dst_reg, si->src_reg,
7825 offsetof(struct bpf_sock_addr_kern, sk));
7826 break;
7754 } 7827 }
7755 7828
7756 return insn - insn_buf; 7829 return insn - insn_buf;
@@ -8010,6 +8083,19 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
8010 SOCK_OPS_GET_OR_SET_FIELD(sk_txhash, sk_txhash, 8083 SOCK_OPS_GET_OR_SET_FIELD(sk_txhash, sk_txhash,
8011 struct sock, type); 8084 struct sock, type);
8012 break; 8085 break;
8086 case offsetof(struct bpf_sock_ops, sk):
8087 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
8088 struct bpf_sock_ops_kern,
8089 is_fullsock),
8090 si->dst_reg, si->src_reg,
8091 offsetof(struct bpf_sock_ops_kern,
8092 is_fullsock));
8093 *insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 1);
8094 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
8095 struct bpf_sock_ops_kern, sk),
8096 si->dst_reg, si->src_reg,
8097 offsetof(struct bpf_sock_ops_kern, sk));
8098 break;
8013 } 8099 }
8014 return insn - insn_buf; 8100 return insn - insn_buf;
8015} 8101}
diff --git a/net/core/sock.c b/net/core/sock.c
index af09a23e4822..ef471f643c95 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1039,6 +1039,10 @@ set_rcvbuf:
1039 } 1039 }
1040 break; 1040 break;
1041 1041
1042 case SO_DETACH_REUSEPORT_BPF:
1043 ret = reuseport_detach_prog(sk);
1044 break;
1045
1042 case SO_DETACH_FILTER: 1046 case SO_DETACH_FILTER:
1043 ret = sk_detach_filter(sk); 1047 ret = sk_detach_filter(sk);
1044 break; 1048 break;
diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
index dc4aefdf2a08..9408f9264d05 100644
--- a/net/core/sock_reuseport.c
+++ b/net/core/sock_reuseport.c
@@ -332,3 +332,27 @@ int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog)
332 return 0; 332 return 0;
333} 333}
334EXPORT_SYMBOL(reuseport_attach_prog); 334EXPORT_SYMBOL(reuseport_attach_prog);
335
336int reuseport_detach_prog(struct sock *sk)
337{
338 struct sock_reuseport *reuse;
339 struct bpf_prog *old_prog;
340
341 if (!rcu_access_pointer(sk->sk_reuseport_cb))
342 return sk->sk_reuseport ? -ENOENT : -EINVAL;
343
344 old_prog = NULL;
345 spin_lock_bh(&reuseport_lock);
346 reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
347 lockdep_is_held(&reuseport_lock));
348 rcu_swap_protected(reuse->prog, old_prog,
349 lockdep_is_held(&reuseport_lock));
350 spin_unlock_bh(&reuseport_lock);
351
352 if (!old_prog)
353 return -ENOENT;
354
355 sk_reuseport_prog_free(old_prog);
356 return 0;
357}
358EXPORT_SYMBOL(reuseport_detach_prog);