|
54 | 54 | #include <net/ip6_fib.h> |
55 | 55 | #include <net/ip6_route.h> |
56 | 56 | #include <net/ip6_tunnel.h> |
| 57 | +#include <net/gre.h> |
57 | 58 |
|
58 | 59 |
|
59 | 60 | static bool log_ecn_error = true; |
@@ -443,137 +444,40 @@ static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
443 | 444 | t->err_time = jiffies; |
444 | 445 | } |
445 | 446 |
|
446 | | -static int ip6gre_rcv(struct sk_buff *skb) |
| 447 | +static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi) |
447 | 448 | { |
448 | 449 | const struct ipv6hdr *ipv6h; |
449 | | - u8 *h; |
450 | | - __be16 flags; |
451 | | - __sum16 csum = 0; |
452 | | - __be32 key = 0; |
453 | | - u32 seqno = 0; |
454 | 450 | struct ip6_tnl *tunnel; |
455 | | - int offset = 4; |
456 | | - __be16 gre_proto; |
457 | | - int err; |
458 | | - |
459 | | - if (!pskb_may_pull(skb, sizeof(struct in6_addr))) |
460 | | - goto drop; |
461 | 451 |
|
462 | 452 | ipv6h = ipv6_hdr(skb); |
463 | | - h = skb->data; |
464 | | - flags = *(__be16 *)h; |
465 | | - |
466 | | - if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) { |
467 | | - /* - Version must be 0. |
468 | | - - We do not support routing headers. |
469 | | - */ |
470 | | - if (flags&(GRE_VERSION|GRE_ROUTING)) |
471 | | - goto drop; |
472 | | - |
473 | | - if (flags&GRE_CSUM) { |
474 | | - csum = skb_checksum_simple_validate(skb); |
475 | | - offset += 4; |
476 | | - } |
477 | | - if (flags&GRE_KEY) { |
478 | | - key = *(__be32 *)(h + offset); |
479 | | - offset += 4; |
480 | | - } |
481 | | - if (flags&GRE_SEQ) { |
482 | | - seqno = ntohl(*(__be32 *)(h + offset)); |
483 | | - offset += 4; |
484 | | - } |
485 | | - } |
486 | | - |
487 | | - gre_proto = *(__be16 *)(h + 2); |
488 | | - |
489 | 453 | tunnel = ip6gre_tunnel_lookup(skb->dev, |
490 | | - &ipv6h->saddr, &ipv6h->daddr, key, |
491 | | - gre_proto); |
| 454 | + &ipv6h->saddr, &ipv6h->daddr, tpi->key, |
| 455 | + tpi->proto); |
492 | 456 | if (tunnel) { |
493 | | - struct pcpu_sw_netstats *tstats; |
494 | | - |
495 | | - if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
496 | | - goto drop; |
497 | | - |
498 | | - if (!ip6_tnl_rcv_ctl(tunnel, &ipv6h->daddr, &ipv6h->saddr)) { |
499 | | - tunnel->dev->stats.rx_dropped++; |
500 | | - goto drop; |
501 | | - } |
502 | | - |
503 | | - skb->protocol = gre_proto; |
504 | | - /* WCCP version 1 and 2 protocol decoding. |
505 | | - * - Change protocol to IPv6 |
506 | | - * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header |
507 | | - */ |
508 | | - if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) { |
509 | | - skb->protocol = htons(ETH_P_IPV6); |
510 | | - if ((*(h + offset) & 0xF0) != 0x40) |
511 | | - offset += 4; |
512 | | - } |
| 457 | + ip6_tnl_rcv(tunnel, skb, tpi, NULL, false); |
513 | 458 |
|
514 | | - skb->mac_header = skb->network_header; |
515 | | - __pskb_pull(skb, offset); |
516 | | - skb_postpull_rcsum(skb, skb_transport_header(skb), offset); |
517 | | - |
518 | | - if (((flags&GRE_CSUM) && csum) || |
519 | | - (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { |
520 | | - tunnel->dev->stats.rx_crc_errors++; |
521 | | - tunnel->dev->stats.rx_errors++; |
522 | | - goto drop; |
523 | | - } |
524 | | - if (tunnel->parms.i_flags&GRE_SEQ) { |
525 | | - if (!(flags&GRE_SEQ) || |
526 | | - (tunnel->i_seqno && |
527 | | - (s32)(seqno - tunnel->i_seqno) < 0)) { |
528 | | - tunnel->dev->stats.rx_fifo_errors++; |
529 | | - tunnel->dev->stats.rx_errors++; |
530 | | - goto drop; |
531 | | - } |
532 | | - tunnel->i_seqno = seqno + 1; |
533 | | - } |
534 | | - |
535 | | - /* Warning: All skb pointers will be invalidated! */ |
536 | | - if (tunnel->dev->type == ARPHRD_ETHER) { |
537 | | - if (!pskb_may_pull(skb, ETH_HLEN)) { |
538 | | - tunnel->dev->stats.rx_length_errors++; |
539 | | - tunnel->dev->stats.rx_errors++; |
540 | | - goto drop; |
541 | | - } |
542 | | - |
543 | | - ipv6h = ipv6_hdr(skb); |
544 | | - skb->protocol = eth_type_trans(skb, tunnel->dev); |
545 | | - skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); |
546 | | - } |
547 | | - |
548 | | - __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); |
| 459 | + return PACKET_RCVD; |
| 460 | + } |
549 | 461 |
|
550 | | - skb_reset_network_header(skb); |
| 462 | + return PACKET_REJECT; |
| 463 | +} |
551 | 464 |
|
552 | | - err = IP6_ECN_decapsulate(ipv6h, skb); |
553 | | - if (unlikely(err)) { |
554 | | - if (log_ecn_error) |
555 | | - net_info_ratelimited("non-ECT from %pI6 with dsfield=%#x\n", |
556 | | - &ipv6h->saddr, |
557 | | - ipv6_get_dsfield(ipv6h)); |
558 | | - if (err > 1) { |
559 | | - ++tunnel->dev->stats.rx_frame_errors; |
560 | | - ++tunnel->dev->stats.rx_errors; |
561 | | - goto drop; |
562 | | - } |
563 | | - } |
| 465 | +static int gre_rcv(struct sk_buff *skb) |
| 466 | +{ |
| 467 | + struct tnl_ptk_info tpi; |
| 468 | + bool csum_err = false; |
| 469 | + int hdr_len; |
564 | 470 |
|
565 | | - tstats = this_cpu_ptr(tunnel->dev->tstats); |
566 | | - u64_stats_update_begin(&tstats->syncp); |
567 | | - tstats->rx_packets++; |
568 | | - tstats->rx_bytes += skb->len; |
569 | | - u64_stats_update_end(&tstats->syncp); |
| 471 | + if (gre_parse_header(skb, &tpi, &csum_err, &hdr_len) < 0) |
| 472 | + goto drop; |
570 | 473 |
|
571 | | - netif_rx(skb); |
| 474 | + if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) |
| 475 | + goto drop; |
572 | 476 |
|
| 477 | + if (ip6gre_rcv(skb, &tpi) == PACKET_RCVD) |
573 | 478 | return 0; |
574 | | - } |
575 | | - icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); |
576 | 479 |
|
| 480 | + icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); |
577 | 481 | drop: |
578 | 482 | kfree_skb(skb); |
579 | 483 | return 0; |
@@ -1075,6 +979,8 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev, |
1075 | 979 | struct net *net = t->net; |
1076 | 980 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); |
1077 | 981 |
|
| 982 | + memset(&p1, 0, sizeof(p1)); |
| 983 | + |
1078 | 984 | switch (cmd) { |
1079 | 985 | case SIOCGETTUNNEL: |
1080 | 986 | if (dev == ign->fb_tunnel_dev) { |
@@ -1318,7 +1224,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev) |
1318 | 1224 |
|
1319 | 1225 |
|
1320 | 1226 | static struct inet6_protocol ip6gre_protocol __read_mostly = { |
1321 | | - .handler = ip6gre_rcv, |
| 1227 | + .handler = gre_rcv, |
1322 | 1228 | .err_handler = ip6gre_err, |
1323 | 1229 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
1324 | 1230 | }; |
|
0 commit comments