aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r--net/ipv4/ipip.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 618bde867ac1..e15b45297c09 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -120,6 +120,10 @@
120#define HASH_SIZE 16 120#define HASH_SIZE 16
121#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) 121#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
122 122
123static bool log_ecn_error = true;
124module_param(log_ecn_error, bool, 0644);
125MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
126
123static int ipip_net_id __read_mostly; 127static int ipip_net_id __read_mostly;
124struct ipip_net { 128struct ipip_net {
125 struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE]; 129 struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE];
@@ -400,28 +404,18 @@ out:
400 return err; 404 return err;
401} 405}
402 406
403static inline void ipip_ecn_decapsulate(const struct iphdr *outer_iph,
404 struct sk_buff *skb)
405{
406 struct iphdr *inner_iph = ip_hdr(skb);
407
408 if (INET_ECN_is_ce(outer_iph->tos))
409 IP_ECN_set_ce(inner_iph);
410}
411
412static int ipip_rcv(struct sk_buff *skb) 407static int ipip_rcv(struct sk_buff *skb)
413{ 408{
414 struct ip_tunnel *tunnel; 409 struct ip_tunnel *tunnel;
415 const struct iphdr *iph = ip_hdr(skb); 410 const struct iphdr *iph = ip_hdr(skb);
411 int err;
416 412
417 tunnel = ipip_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr); 413 tunnel = ipip_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr);
418 if (tunnel != NULL) { 414 if (tunnel != NULL) {
419 struct pcpu_tstats *tstats; 415 struct pcpu_tstats *tstats;
420 416
421 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { 417 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
422 kfree_skb(skb); 418 goto drop;
423 return 0;
424 }
425 419
426 secpath_reset(skb); 420 secpath_reset(skb);
427 421
@@ -430,21 +424,35 @@ static int ipip_rcv(struct sk_buff *skb)
430 skb->protocol = htons(ETH_P_IP); 424 skb->protocol = htons(ETH_P_IP);
431 skb->pkt_type = PACKET_HOST; 425 skb->pkt_type = PACKET_HOST;
432 426
427 __skb_tunnel_rx(skb, tunnel->dev);
428
429 err = IP_ECN_decapsulate(iph, skb);
430 if (unlikely(err)) {
431 if (log_ecn_error)
432 net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
433 &iph->saddr, iph->tos);
434 if (err > 1) {
435 ++tunnel->dev->stats.rx_frame_errors;
436 ++tunnel->dev->stats.rx_errors;
437 goto drop;
438 }
439 }
440
433 tstats = this_cpu_ptr(tunnel->dev->tstats); 441 tstats = this_cpu_ptr(tunnel->dev->tstats);
434 u64_stats_update_begin(&tstats->syncp); 442 u64_stats_update_begin(&tstats->syncp);
435 tstats->rx_packets++; 443 tstats->rx_packets++;
436 tstats->rx_bytes += skb->len; 444 tstats->rx_bytes += skb->len;
437 u64_stats_update_end(&tstats->syncp); 445 u64_stats_update_end(&tstats->syncp);
438 446
439 __skb_tunnel_rx(skb, tunnel->dev);
440
441 ipip_ecn_decapsulate(iph, skb);
442
443 netif_rx(skb); 447 netif_rx(skb);
444 return 0; 448 return 0;
445 } 449 }
446 450
447 return -1; 451 return -1;
452
453drop:
454 kfree_skb(skb);
455 return 0;
448} 456}
449 457
450/* 458/*