History

bpf: Add ingress_ifindex to bpf_sk_lookup

It may be helpful to have access to the ifindex during bpf socket lookup. An example may be to scope certain socket lookup logic to specific interfaces, i.e. an interface may be made exempt from custom lookup code. Add the ifindex of the arriving connection to the bpf_sk_lookup API.

Mark Pashmfouroush committed 5 years ago

Commit f8931561 parent 1a8b5978 files · +30 −18Browse files

Unified · Split

8 files
  1. include/linux/filter.h +5 −2
  2. include/uapi/linux/bpf.h +1 −0
  3. net/core/filter.c +7 −0
  4. net/ipv4/inet_hashtables.c +4 −4
  5. net/ipv4/udp.c +4 −4
  6. net/ipv6/inet6_hashtables.c +4 −4
  7. net/ipv6/udp.c +4 −4
  8. tools/include/uapi/linux/bpf.h +1 −0
include/linux/filter.h+5−2
@@ -1374,6 +1374,7 @@ struct bpf_sk_lookup_kern { · 1373 unmodified lines
13741374 const struct in6_addr *daddr;
13751375 } v6;
13761376 struct sock *selected_sk;
1377+ u32 ingress_ifindex;
13771378 bool no_reuseport;
13781379 };
13791380
@@ -1436,7 +1437,7 @@ extern struct static_key_false bpf_sk_lookup_enabled; · 56 unmodified lines
14361437 static inline bool bpf_sk_lookup_run_v4(struct net *net, int protocol,
14371438 const __be32 saddr, const __be16 sport,
14381439 const __be32 daddr, const u16 dport,
1439− struct sock **psk)
1440+ const int ifindex, struct sock **psk)
14401441 {
14411442 struct bpf_prog_array *run_array;
14421443 struct sock *selected_sk = NULL;
@@ -1452,6 +1453,7 @@ static inline bool bpf_sk_lookup_run_v4(struct net *net, int protocol, · 9 unmodified lines
14521453 .v4.daddr = daddr,
14531454 .sport = sport,
14541455 .dport = dport,
1456+ .ingress_ifindex = ifindex,
14551457 };
14561458 u32 act;
14571459
@@ -1474,7 +1476,7 @@ static inline bool bpf_sk_lookup_run_v6(struct net *net, int protocol, · 16 unmodified lines
14741476 const __be16 sport,
14751477 const struct in6_addr *daddr,
14761478 const u16 dport,
1477− struct sock **psk)
1479+ const int ifindex, struct sock **psk)
14781480 {
14791481 struct bpf_prog_array *run_array;
14801482 struct sock *selected_sk = NULL;
@@ -1490,6 +1492,7 @@ static inline bool bpf_sk_lookup_run_v6(struct net *net, int protocol, · 9 unmodified lines
14901492 .v6.daddr = daddr,
14911493 .sport = sport,
14921494 .dport = dport,
1495+ .ingress_ifindex = ifindex,
14931496 };
14941497 u32 act;
14951498
include/uapi/linux/bpf.h+1−0
@@ -6316,6 +6316,7 @@ struct bpf_sk_lookup { · 6315 unmodified lines
63166316 __u32 local_ip4; /* Network byte order */
63176317 __u32 local_ip6[4]; /* Network byte order */
63186318 __u32 local_port; /* Host byte order */
6319+ __u32 ingress_ifindex; /* The arriving interface. Determined by inet_iif. */
63196320 };
63206321
63216322 /*
net/core/filter.c+7−0
@@ -10491,6 +10491,7 @@ static bool sk_lookup_is_valid_access(int off, int size, · 10490 unmodified lines
1049110491 case bpf_ctx_range_till(struct bpf_sk_lookup, local_ip6[0], local_ip6[3]):
1049210492 case bpf_ctx_range(struct bpf_sk_lookup, remote_port):
1049310493 case bpf_ctx_range(struct bpf_sk_lookup, local_port):
10494+ case bpf_ctx_range(struct bpf_sk_lookup, ingress_ifindex):
1049410495 bpf_ctx_record_field_size(info, sizeof(__u32));
1049510496 return bpf_ctx_narrow_access_ok(off, size, sizeof(__u32));
1049610497
@@ -10580,6 +10581,12 @@ static u32 sk_lookup_convert_ctx_access(enum bpf_access_type type, · 83 unmodified lines
1058010581 bpf_target_off(struct bpf_sk_lookup_kern,
1058110582 dport, 2, target_size));
1058210583 break;
10584+
10585+ case offsetof(struct bpf_sk_lookup, ingress_ifindex):
10586+ *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg,
10587+ bpf_target_off(struct bpf_sk_lookup_kern,
10588+ ingress_ifindex, 4, target_size));
10589+ break;
1058310590 }
1058410591
1058510592 return insn - insn_buf;
net/ipv4/inet_hashtables.c+4−4
@@ -307,7 +307,7 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, · 306 unmodified lines
307307 struct inet_hashinfo *hashinfo,
308308 struct sk_buff *skb, int doff,
309309 __be32 saddr, __be16 sport,
310− __be32 daddr, u16 hnum)
310+ __be32 daddr, u16 hnum, const int dif)
311311 {
312312 struct sock *sk, *reuse_sk;
313313 bool no_reuseport;
@@ -315,8 +315,8 @@ static inline struct sock *inet_lookup_run_bpf(struct net *net, · 1 unmodified line
315315 if (hashinfo != &tcp_hashinfo)
316316 return NULL; /* only TCP is supported */
317317
318− no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_TCP,
319− saddr, sport, daddr, hnum, &sk);
318+ no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_TCP, saddr, sport,
319+ daddr, hnum, dif, &sk);
320320 if (no_reuseport || IS_ERR_OR_NULL(sk))
321321 return sk;
322322
@@ -340,7 +340,7 @@ struct sock *__inet_lookup_listener(struct net *net, · 17 unmodified lines
340340 /* Lookup redirect from BPF */
341341 if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
342342 result = inet_lookup_run_bpf(net, hashinfo, skb, doff,
343− saddr, sport, daddr, hnum);
343+ saddr, sport, daddr, hnum, dif);
344344 if (result)
345345 goto done;
346346 }
net/ipv4/udp.c+4−4
@@ -460,7 +460,7 @@ static struct sock *udp4_lookup_run_bpf(struct net *net, · 459 unmodified lines
460460 struct udp_table *udptable,
461461 struct sk_buff *skb,
462462 __be32 saddr, __be16 sport,
463− __be32 daddr, u16 hnum)
463+ __be32 daddr, u16 hnum, const int dif)
464464 {
465465 struct sock *sk, *reuse_sk;
466466 bool no_reuseport;
@@ -468,8 +468,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net, · 1 unmodified line
468468 if (udptable != &udp_table)
469469 return NULL; /* only UDP is supported */
470470
471− no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP,
472− saddr, sport, daddr, hnum, &sk);
471+ no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP, saddr, sport,
472+ daddr, hnum, dif, &sk);
473473 if (no_reuseport || IS_ERR_OR_NULL(sk))
474474 return sk;
475475
@@ -505,7 +505,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, · 29 unmodified lines
505505 /* Lookup redirect from BPF */
506506 if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
507507 sk = udp4_lookup_run_bpf(net, udptable, skb,
508− saddr, sport, daddr, hnum);
508+ saddr, sport, daddr, hnum, dif);
509509 if (sk) {
510510 result = sk;
511511 goto done;
net/ipv6/inet6_hashtables.c+4−4
@@ -165,7 +165,7 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, · 164 unmodified lines
165165 const struct in6_addr *saddr,
166166 const __be16 sport,
167167 const struct in6_addr *daddr,
168− const u16 hnum)
168+ const u16 hnum, const int dif)
169169 {
170170 struct sock *sk, *reuse_sk;
171171 bool no_reuseport;
@@ -173,8 +173,8 @@ static inline struct sock *inet6_lookup_run_bpf(struct net *net, · 1 unmodified line
173173 if (hashinfo != &tcp_hashinfo)
174174 return NULL; /* only TCP is supported */
175175
176− no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_TCP,
177− saddr, sport, daddr, hnum, &sk);
176+ no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_TCP, saddr, sport,
177+ daddr, hnum, dif, &sk);
178178 if (no_reuseport || IS_ERR_OR_NULL(sk))
179179 return sk;
180180
@@ -198,7 +198,7 @@ struct sock *inet6_lookup_listener(struct net *net, · 17 unmodified lines
198198 /* Lookup redirect from BPF */
199199 if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
200200 result = inet6_lookup_run_bpf(net, hashinfo, skb, doff,
201− saddr, sport, daddr, hnum);
201+ saddr, sport, daddr, hnum, dif);
202202 if (result)
203203 goto done;
204204 }
net/ipv6/udp.c+4−4
@@ -195,7 +195,7 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net, · 194 unmodified lines
195195 const struct in6_addr *saddr,
196196 __be16 sport,
197197 const struct in6_addr *daddr,
198− u16 hnum)
198+ u16 hnum, const int dif)
199199 {
200200 struct sock *sk, *reuse_sk;
201201 bool no_reuseport;
@@ -203,8 +203,8 @@ static inline struct sock *udp6_lookup_run_bpf(struct net *net, · 1 unmodified line
203203 if (udptable != &udp_table)
204204 return NULL; /* only UDP is supported */
205205
206− no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_UDP,
207− saddr, sport, daddr, hnum, &sk);
206+ no_reuseport = bpf_sk_lookup_run_v6(net, IPPROTO_UDP, saddr, sport,
207+ daddr, hnum, dif, &sk);
208208 if (no_reuseport || IS_ERR_OR_NULL(sk))
209209 return sk;
210210
@@ -240,7 +240,7 @@ struct sock *__udp6_lib_lookup(struct net *net, · 29 unmodified lines
240240 /* Lookup redirect from BPF */
241241 if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {
242242 sk = udp6_lookup_run_bpf(net, udptable, skb,
243− saddr, sport, daddr, hnum);
243+ saddr, sport, daddr, hnum, dif);
244244 if (sk) {
245245 result = sk;
246246 goto done;
tools/include/uapi/linux/bpf.h+1−0
@@ -6316,6 +6316,7 @@ struct bpf_sk_lookup { · 6315 unmodified lines
63166316 __u32 local_ip4; /* Network byte order */
63176317 __u32 local_ip6[4]; /* Network byte order */
63186318 __u32 local_port; /* Host byte order */
6319+ __u32 ingress_ifindex; /* The arriving interface. Determined by inet_iif. */
63196320 };
63206321
63216322 /*