aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_tunnel.c')
-rw-r--r--net/ipv6/ip6_tunnel.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 6022fc5e557a..985d106dff6d 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -513,14 +513,17 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
513 return 0; 513 return 0;
514} 514}
515 515
516static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph, 516static void ip6ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
517 struct sk_buff *skb) 517 struct ipv6hdr *ipv6h,
518 struct sk_buff *skb)
518{ 519{
519 struct ipv6hdr *inner_iph = skb->nh.ipv6h; 520 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
521 ipv6_copy_dscp(ipv6h, skb->nh.ipv6h);
520 522
521 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) 523 if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h)))
522 IP6_ECN_set_ce(inner_iph); 524 IP6_ECN_set_ce(skb->nh.ipv6h);
523} 525}
526
524static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t) 527static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
525{ 528{
526 struct ip6_tnl_parm *p = &t->parms; 529 struct ip6_tnl_parm *p = &t->parms;
@@ -546,12 +549,16 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
546/** 549/**
547 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally 550 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally
548 * @skb: received socket buffer 551 * @skb: received socket buffer
552 * @protocol: ethernet protocol ID
553 * @dscp_ecn_decapsulate: the function to decapsulate DSCP code and ECN
549 * 554 *
550 * Return: 0 555 * Return: 0
551 **/ 556 **/
552 557
553static int 558static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
554ip6ip6_rcv(struct sk_buff *skb) 559 void (*dscp_ecn_decapsulate)(struct ip6_tnl *t,
560 struct ipv6hdr *ipv6h,
561 struct sk_buff *skb))
555{ 562{
556 struct ipv6hdr *ipv6h; 563 struct ipv6hdr *ipv6h;
557 struct ip6_tnl *t; 564 struct ip6_tnl *t;
@@ -574,16 +581,16 @@ ip6ip6_rcv(struct sk_buff *skb)
574 secpath_reset(skb); 581 secpath_reset(skb);
575 skb->mac.raw = skb->nh.raw; 582 skb->mac.raw = skb->nh.raw;
576 skb->nh.raw = skb->data; 583 skb->nh.raw = skb->data;
577 skb->protocol = htons(ETH_P_IPV6); 584 skb->protocol = htons(protocol);
578 skb->pkt_type = PACKET_HOST; 585 skb->pkt_type = PACKET_HOST;
579 memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); 586 memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
580 skb->dev = t->dev; 587 skb->dev = t->dev;
581 dst_release(skb->dst); 588 dst_release(skb->dst);
582 skb->dst = NULL; 589 skb->dst = NULL;
583 nf_reset(skb); 590 nf_reset(skb);
584 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) 591
585 ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); 592 dscp_ecn_decapsulate(t, ipv6h, skb);
586 ip6ip6_ecn_decapsulate(ipv6h, skb); 593
587 t->stat.rx_packets++; 594 t->stat.rx_packets++;
588 t->stat.rx_bytes += skb->len; 595 t->stat.rx_bytes += skb->len;
589 netif_rx(skb); 596 netif_rx(skb);
@@ -598,6 +605,11 @@ discard:
598 return 0; 605 return 0;
599} 606}
600 607
608static int ip6ip6_rcv(struct sk_buff *skb)
609{
610 return ip6_tnl_rcv(skb, ETH_P_IPV6, ip6ip6_dscp_ecn_decapsulate);
611}
612
601struct ipv6_tel_txoption { 613struct ipv6_tel_txoption {
602 struct ipv6_txoptions ops; 614 struct ipv6_txoptions ops;
603 __u8 dst_opt[8]; 615 __u8 dst_opt[8];