aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/seg6_local.c
diff options
context:
space:
mode:
authorMathieu Xhonneux <m.xhonneux@gmail.com>2018-05-20 09:58:13 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-05-24 05:57:35 -0400
commit1c1e761ef1a08a878a040e67979711015cfc163e (patch)
tree599b0d5c23abc9d80472c0c813c00a9c8b9deaab /net/ipv6/seg6_local.c
parent63526e1c805b5a8992d25386d315009fcabac8e2 (diff)
ipv6: sr: export function lookup_nexthop
The function lookup_nexthop is essential to implement most of the seg6local actions. As we want to provide a BPF helper allowing to apply some of these actions on the packet being processed, the helper should be able to call this function, hence the need to make it public. Moreover, if one argument is incorrect or if the next hop can not be found, an error should be returned by the BPF helper so the BPF program can adapt its processing of the packet (return an error, properly force the drop, ...). This patch hence makes this function return dst->error to indicate a possible error. Signed-off-by: Mathieu Xhonneux <m.xhonneux@gmail.com> Acked-by: David Lebrun <dlebrun@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'net/ipv6/seg6_local.c')
-rw-r--r--net/ipv6/seg6_local.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 45722327375a..e9b23fb924ad 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -30,6 +30,7 @@
30#ifdef CONFIG_IPV6_SEG6_HMAC 30#ifdef CONFIG_IPV6_SEG6_HMAC
31#include <net/seg6_hmac.h> 31#include <net/seg6_hmac.h>
32#endif 32#endif
33#include <net/seg6_local.h>
33#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
34 35
35struct seg6_local_lwt; 36struct seg6_local_lwt;
@@ -140,8 +141,8 @@ static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
140 *daddr = *addr; 141 *daddr = *addr;
141} 142}
142 143
143static void lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr, 144int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
144 u32 tbl_id) 145 u32 tbl_id)
145{ 146{
146 struct net *net = dev_net(skb->dev); 147 struct net *net = dev_net(skb->dev);
147 struct ipv6hdr *hdr = ipv6_hdr(skb); 148 struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -187,6 +188,7 @@ out:
187 188
188 skb_dst_drop(skb); 189 skb_dst_drop(skb);
189 skb_dst_set(skb, dst); 190 skb_dst_set(skb, dst);
191 return dst->error;
190} 192}
191 193
192/* regular endpoint function */ 194/* regular endpoint function */
@@ -200,7 +202,7 @@ static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt)
200 202
201 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 203 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
202 204
203 lookup_nexthop(skb, NULL, 0); 205 seg6_lookup_nexthop(skb, NULL, 0);
204 206
205 return dst_input(skb); 207 return dst_input(skb);
206 208
@@ -220,7 +222,7 @@ static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt)
220 222
221 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 223 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
222 224
223 lookup_nexthop(skb, &slwt->nh6, 0); 225 seg6_lookup_nexthop(skb, &slwt->nh6, 0);
224 226
225 return dst_input(skb); 227 return dst_input(skb);
226 228
@@ -239,7 +241,7 @@ static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt)
239 241
240 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); 242 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
241 243
242 lookup_nexthop(skb, NULL, slwt->table); 244 seg6_lookup_nexthop(skb, NULL, slwt->table);
243 245
244 return dst_input(skb); 246 return dst_input(skb);
245 247
@@ -331,7 +333,7 @@ static int input_action_end_dx6(struct sk_buff *skb,
331 if (!ipv6_addr_any(&slwt->nh6)) 333 if (!ipv6_addr_any(&slwt->nh6))
332 nhaddr = &slwt->nh6; 334 nhaddr = &slwt->nh6;
333 335
334 lookup_nexthop(skb, nhaddr, 0); 336 seg6_lookup_nexthop(skb, nhaddr, 0);
335 337
336 return dst_input(skb); 338 return dst_input(skb);
337drop: 339drop:
@@ -380,7 +382,7 @@ static int input_action_end_dt6(struct sk_buff *skb,
380 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 382 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
381 goto drop; 383 goto drop;
382 384
383 lookup_nexthop(skb, NULL, slwt->table); 385 seg6_lookup_nexthop(skb, NULL, slwt->table);
384 386
385 return dst_input(skb); 387 return dst_input(skb);
386 388
@@ -406,7 +408,7 @@ static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
406 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 408 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
407 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 409 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
408 410
409 lookup_nexthop(skb, NULL, 0); 411 seg6_lookup_nexthop(skb, NULL, 0);
410 412
411 return dst_input(skb); 413 return dst_input(skb);
412 414
@@ -438,7 +440,7 @@ static int input_action_end_b6_encap(struct sk_buff *skb,
438 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 440 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
439 skb_set_transport_header(skb, sizeof(struct ipv6hdr)); 441 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
440 442
441 lookup_nexthop(skb, NULL, 0); 443 seg6_lookup_nexthop(skb, NULL, 0);
442 444
443 return dst_input(skb); 445 return dst_input(skb);
444 446