aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/ip6_tunnel.c49
-rw-r--r--net/ipv6/sit.c33
2 files changed, 53 insertions, 29 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index fb828e9fe8e0..a14f28b280f5 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -74,6 +74,10 @@ MODULE_ALIAS_NETDEV("ip6tnl0");
74#define HASH_SIZE_SHIFT 5 74#define HASH_SIZE_SHIFT 5
75#define HASH_SIZE (1 << HASH_SIZE_SHIFT) 75#define HASH_SIZE (1 << HASH_SIZE_SHIFT)
76 76
77static bool log_ecn_error = true;
78module_param(log_ecn_error, bool, 0644);
79MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
80
77static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) 81static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
78{ 82{
79 u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); 83 u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
@@ -683,28 +687,26 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
683 return 0; 687 return 0;
684} 688}
685 689
686static void ip4ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t, 690static int ip4ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t,
687 const struct ipv6hdr *ipv6h, 691 const struct ipv6hdr *ipv6h,
688 struct sk_buff *skb) 692 struct sk_buff *skb)
689{ 693{
690 __u8 dsfield = ipv6_get_dsfield(ipv6h) & ~INET_ECN_MASK; 694 __u8 dsfield = ipv6_get_dsfield(ipv6h) & ~INET_ECN_MASK;
691 695
692 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) 696 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
693 ipv4_change_dsfield(ip_hdr(skb), INET_ECN_MASK, dsfield); 697 ipv4_change_dsfield(ip_hdr(skb), INET_ECN_MASK, dsfield);
694 698
695 if (INET_ECN_is_ce(dsfield)) 699 return IP6_ECN_decapsulate(ipv6h, skb);
696 IP_ECN_set_ce(ip_hdr(skb));
697} 700}
698 701
699static void ip6ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t, 702static int ip6ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t,
700 const struct ipv6hdr *ipv6h, 703 const struct ipv6hdr *ipv6h,
701 struct sk_buff *skb) 704 struct sk_buff *skb)
702{ 705{
703 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) 706 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
704 ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb)); 707 ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb));
705 708
706 if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h))) 709 return IP6_ECN_decapsulate(ipv6h, skb);
707 IP6_ECN_set_ce(ipv6_hdr(skb));
708} 710}
709 711
710__u32 ip6_tnl_get_cap(struct ip6_tnl *t, 712__u32 ip6_tnl_get_cap(struct ip6_tnl *t,
@@ -768,12 +770,13 @@ EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl);
768 770
769static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, 771static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
770 __u8 ipproto, 772 __u8 ipproto,
771 void (*dscp_ecn_decapsulate)(const struct ip6_tnl *t, 773 int (*dscp_ecn_decapsulate)(const struct ip6_tnl *t,
772 const struct ipv6hdr *ipv6h, 774 const struct ipv6hdr *ipv6h,
773 struct sk_buff *skb)) 775 struct sk_buff *skb))
774{ 776{
775 struct ip6_tnl *t; 777 struct ip6_tnl *t;
776 const struct ipv6hdr *ipv6h = ipv6_hdr(skb); 778 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
779 int err;
777 780
778 rcu_read_lock(); 781 rcu_read_lock();
779 782
@@ -803,14 +806,26 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
803 skb->pkt_type = PACKET_HOST; 806 skb->pkt_type = PACKET_HOST;
804 memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); 807 memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
805 808
809 __skb_tunnel_rx(skb, t->dev);
810
811 err = dscp_ecn_decapsulate(t, ipv6h, skb);
812 if (unlikely(err)) {
813 if (log_ecn_error)
814 net_info_ratelimited("non-ECT from %pI6 with dsfield=%#x\n",
815 &ipv6h->saddr,
816 ipv6_get_dsfield(ipv6h));
817 if (err > 1) {
818 ++t->dev->stats.rx_frame_errors;
819 ++t->dev->stats.rx_errors;
820 rcu_read_unlock();
821 goto discard;
822 }
823 }
824
806 tstats = this_cpu_ptr(t->dev->tstats); 825 tstats = this_cpu_ptr(t->dev->tstats);
807 tstats->rx_packets++; 826 tstats->rx_packets++;
808 tstats->rx_bytes += skb->len; 827 tstats->rx_bytes += skb->len;
809 828
810 __skb_tunnel_rx(skb, t->dev);
811
812 dscp_ecn_decapsulate(t, ipv6h, skb);
813
814 netif_rx(skb); 829 netif_rx(skb);
815 830
816 rcu_read_unlock(); 831 rcu_read_unlock();
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 80cb3829831c..cfba99b2c2a4 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -65,6 +65,10 @@
65#define HASH_SIZE 16 65#define HASH_SIZE 16
66#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) 66#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
67 67
68static bool log_ecn_error = true;
69module_param(log_ecn_error, bool, 0644);
70MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
71
68static int ipip6_tunnel_init(struct net_device *dev); 72static int ipip6_tunnel_init(struct net_device *dev);
69static void ipip6_tunnel_setup(struct net_device *dev); 73static void ipip6_tunnel_setup(struct net_device *dev);
70static void ipip6_dev_free(struct net_device *dev); 74static void ipip6_dev_free(struct net_device *dev);
@@ -106,6 +110,7 @@ static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev,
106 } 110 }
107 111
108 tot->rx_errors = dev->stats.rx_errors; 112 tot->rx_errors = dev->stats.rx_errors;
113 tot->rx_frame_errors = dev->stats.rx_frame_errors;
109 tot->tx_fifo_errors = dev->stats.tx_fifo_errors; 114 tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
110 tot->tx_carrier_errors = dev->stats.tx_carrier_errors; 115 tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
111 tot->tx_dropped = dev->stats.tx_dropped; 116 tot->tx_dropped = dev->stats.tx_dropped;
@@ -585,16 +590,11 @@ out:
585 return err; 590 return err;
586} 591}
587 592
588static inline void ipip6_ecn_decapsulate(const struct iphdr *iph, struct sk_buff *skb)
589{
590 if (INET_ECN_is_ce(iph->tos))
591 IP6_ECN_set_ce(ipv6_hdr(skb));
592}
593
594static int ipip6_rcv(struct sk_buff *skb) 593static int ipip6_rcv(struct sk_buff *skb)
595{ 594{
596 const struct iphdr *iph; 595 const struct iphdr *iph;
597 struct ip_tunnel *tunnel; 596 struct ip_tunnel *tunnel;
597 int err;
598 598
599 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 599 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
600 goto out; 600 goto out;
@@ -616,18 +616,27 @@ static int ipip6_rcv(struct sk_buff *skb)
616 if ((tunnel->dev->priv_flags & IFF_ISATAP) && 616 if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
617 !isatap_chksrc(skb, iph, tunnel)) { 617 !isatap_chksrc(skb, iph, tunnel)) {
618 tunnel->dev->stats.rx_errors++; 618 tunnel->dev->stats.rx_errors++;
619 kfree_skb(skb); 619 goto out;
620 return 0; 620 }
621
622 __skb_tunnel_rx(skb, tunnel->dev);
623
624 err = IP_ECN_decapsulate(iph, skb);
625 if (unlikely(err)) {
626 if (log_ecn_error)
627 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
628 &iph->saddr, iph->tos);
629 if (err > 1) {
630 ++tunnel->dev->stats.rx_frame_errors;
631 ++tunnel->dev->stats.rx_errors;
632 goto out;
633 }
621 } 634 }
622 635
623 tstats = this_cpu_ptr(tunnel->dev->tstats); 636 tstats = this_cpu_ptr(tunnel->dev->tstats);
624 tstats->rx_packets++; 637 tstats->rx_packets++;
625 tstats->rx_bytes += skb->len; 638 tstats->rx_bytes += skb->len;
626 639
627 __skb_tunnel_rx(skb, tunnel->dev);
628
629 ipip6_ecn_decapsulate(iph, skb);
630
631 netif_rx(skb); 640 netif_rx(skb);
632 641
633 return 0; 642 return 0;