|
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