summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/sockmap.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-11-07 04:32:44 -0500
committerIngo Molnar <mingo@kernel.org>2017-11-07 04:32:44 -0500
commit8c5db92a705d9e2c986adec475980d1120fa07b4 (patch)
tree9f0eea56889819707c0a1a8eb5b1fb2db3cdaf3d /kernel/bpf/sockmap.c
parentca5d376e17072c1b60c3fee66f3be58ef018952d (diff)
parente4880bc5dfb1f02b152e62a894b5c6f3e995b3cf (diff)
Merge branch 'linus' into locking/core, to resolve conflicts
Conflicts: include/linux/compiler-clang.h include/linux/compiler-gcc.h include/linux/compiler-intel.h include/uapi/linux/stddef.h Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/bpf/sockmap.c')
-rw-r--r--kernel/bpf/sockmap.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index 2b6eb35ae5d3..dbd7b322a86b 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -93,13 +93,27 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
93 return rcu_dereference_sk_user_data(sk); 93 return rcu_dereference_sk_user_data(sk);
94} 94}
95 95
96/* compute the linear packet data range [data, data_end) for skb when
97 * sk_skb type programs are in use.
98 */
99static inline void bpf_compute_data_end_sk_skb(struct sk_buff *skb)
100{
101 TCP_SKB_CB(skb)->bpf.data_end = skb->data + skb_headlen(skb);
102}
103
104enum __sk_action {
105 __SK_DROP = 0,
106 __SK_PASS,
107 __SK_REDIRECT,
108};
109
96static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb) 110static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
97{ 111{
98 struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict); 112 struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict);
99 int rc; 113 int rc;
100 114
101 if (unlikely(!prog)) 115 if (unlikely(!prog))
102 return SK_DROP; 116 return __SK_DROP;
103 117
104 skb_orphan(skb); 118 skb_orphan(skb);
105 /* We need to ensure that BPF metadata for maps is also cleared 119 /* We need to ensure that BPF metadata for maps is also cleared
@@ -108,13 +122,16 @@ static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
108 */ 122 */
109 TCP_SKB_CB(skb)->bpf.map = NULL; 123 TCP_SKB_CB(skb)->bpf.map = NULL;
110 skb->sk = psock->sock; 124 skb->sk = psock->sock;
111 bpf_compute_data_end(skb); 125 bpf_compute_data_end_sk_skb(skb);
112 preempt_disable(); 126 preempt_disable();
113 rc = (*prog->bpf_func)(skb, prog->insnsi); 127 rc = (*prog->bpf_func)(skb, prog->insnsi);
114 preempt_enable(); 128 preempt_enable();
115 skb->sk = NULL; 129 skb->sk = NULL;
116 130
117 return rc; 131 /* Moving return codes from UAPI namespace into internal namespace */
132 return rc == SK_PASS ?
133 (TCP_SKB_CB(skb)->bpf.map ? __SK_REDIRECT : __SK_PASS) :
134 __SK_DROP;
118} 135}
119 136
120static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb) 137static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
@@ -124,7 +141,7 @@ static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
124 141
125 rc = smap_verdict_func(psock, skb); 142 rc = smap_verdict_func(psock, skb);
126 switch (rc) { 143 switch (rc) {
127 case SK_REDIRECT: 144 case __SK_REDIRECT:
128 sk = do_sk_redirect_map(skb); 145 sk = do_sk_redirect_map(skb);
129 if (likely(sk)) { 146 if (likely(sk)) {
130 struct smap_psock *peer = smap_psock_sk(sk); 147 struct smap_psock *peer = smap_psock_sk(sk);
@@ -140,7 +157,7 @@ static void smap_do_verdict(struct smap_psock *psock, struct sk_buff *skb)
140 } 157 }
141 } 158 }
142 /* Fall through and free skb otherwise */ 159 /* Fall through and free skb otherwise */
143 case SK_DROP: 160 case __SK_DROP:
144 default: 161 default:
145 kfree_skb(skb); 162 kfree_skb(skb);
146 } 163 }
@@ -368,7 +385,7 @@ static int smap_parse_func_strparser(struct strparser *strp,
368 * any socket yet. 385 * any socket yet.
369 */ 386 */
370 skb->sk = psock->sock; 387 skb->sk = psock->sock;
371 bpf_compute_data_end(skb); 388 bpf_compute_data_end_sk_skb(skb);
372 rc = (*prog->bpf_func)(skb, prog->insnsi); 389 rc = (*prog->bpf_func)(skb, prog->insnsi);
373 skb->sk = NULL; 390 skb->sk = NULL;
374 rcu_read_unlock(); 391 rcu_read_unlock();