aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/ip6_tunnel.c96
1 files changed, 62 insertions, 34 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index fdf1a2fa3a3d..22debbf28b8a 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -494,6 +494,27 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
494 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) 494 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
495 IP6_ECN_set_ce(inner_iph); 495 IP6_ECN_set_ce(inner_iph);
496} 496}
497static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
498{
499 struct ip6_tnl_parm *p = &t->parms;
500 int ret = 0;
501
502 if (p->flags & IP6_TNL_F_CAP_RCV) {
503 struct net_device *ldev = NULL;
504
505 if (p->link)
506 ldev = dev_get_by_index(p->link);
507
508 if ((ipv6_addr_is_multicast(&p->laddr) ||
509 likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
510 likely(!ipv6_chk_addr(&p->raddr, NULL, 0)))
511 ret = 1;
512
513 if (ldev)
514 dev_put(ldev);
515 }
516 return ret;
517}
497 518
498/** 519/**
499 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally 520 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally
@@ -518,7 +539,7 @@ ip6ip6_rcv(struct sk_buff *skb)
518 goto discard; 539 goto discard;
519 } 540 }
520 541
521 if (!(t->parms.flags & IP6_TNL_F_CAP_RCV)) { 542 if (!ip6_tnl_rcv_ctl(t)) {
522 t->stat.rx_dropped++; 543 t->stat.rx_dropped++;
523 read_unlock(&ip6ip6_lock); 544 read_unlock(&ip6ip6_lock);
524 goto discard; 545 goto discard;
@@ -597,6 +618,34 @@ ip6ip6_tnl_addr_conflict(struct ip6_tnl *t, struct ipv6hdr *hdr)
597 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); 618 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
598} 619}
599 620
621static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
622{
623 struct ip6_tnl_parm *p = &t->parms;
624 int ret = 0;
625
626 if (p->flags & IP6_TNL_F_CAP_XMIT) {
627 struct net_device *ldev = NULL;
628
629 if (p->link)
630 ldev = dev_get_by_index(p->link);
631
632 if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
633 printk(KERN_WARNING
634 "%s xmit: Local address not yet configured!\n",
635 p->name);
636 else if (!ipv6_addr_is_multicast(&p->raddr) &&
637 unlikely(ipv6_chk_addr(&p->raddr, NULL, 0)))
638 printk(KERN_WARNING
639 "%s xmit: Routing loop! "
640 "Remote address found on this node!\n",
641 p->name);
642 else
643 ret = 1;
644 if (ldev)
645 dev_put(ldev);
646 }
647 return ret;
648}
600/** 649/**
601 * ip6ip6_tnl_xmit - encapsulate packet and send 650 * ip6ip6_tnl_xmit - encapsulate packet and send
602 * @skb: the outgoing socket buffer 651 * @skb: the outgoing socket buffer
@@ -634,10 +683,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
634 goto tx_err; 683 goto tx_err;
635 } 684 }
636 if (skb->protocol != htons(ETH_P_IPV6) || 685 if (skb->protocol != htons(ETH_P_IPV6) ||
637 !(t->parms.flags & IP6_TNL_F_CAP_XMIT) || 686 !ip6_tnl_xmit_ctl(t) || ip6ip6_tnl_addr_conflict(t, ipv6h))
638 ip6ip6_tnl_addr_conflict(t, ipv6h)) {
639 goto tx_err; 687 goto tx_err;
640 } 688
641 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) { 689 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
642 struct ipv6_tlv_tnl_enc_lim *tel; 690 struct ipv6_tlv_tnl_enc_lim *tel;
643 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset]; 691 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
@@ -768,39 +816,19 @@ tx_err:
768static void ip6_tnl_set_cap(struct ip6_tnl *t) 816static void ip6_tnl_set_cap(struct ip6_tnl *t)
769{ 817{
770 struct ip6_tnl_parm *p = &t->parms; 818 struct ip6_tnl_parm *p = &t->parms;
771 struct in6_addr *laddr = &p->laddr; 819 int ltype = ipv6_addr_type(&p->laddr);
772 struct in6_addr *raddr = &p->raddr; 820 int rtype = ipv6_addr_type(&p->raddr);
773 int ltype = ipv6_addr_type(laddr);
774 int rtype = ipv6_addr_type(raddr);
775 821
776 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV); 822 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV);
777 823
778 if (ltype != IPV6_ADDR_ANY && rtype != IPV6_ADDR_ANY && 824 if (ltype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
779 ((ltype|rtype) & 825 rtype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
780 (IPV6_ADDR_UNICAST| 826 !((ltype|rtype) & IPV6_ADDR_LOOPBACK) &&
781 IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL| 827 !((ltype|rtype) & IPV6_ADDR_LINKLOCAL)) {
782 IPV6_ADDR_MAPPED|IPV6_ADDR_RESERVED)) == IPV6_ADDR_UNICAST) { 828 if (ltype&IPV6_ADDR_UNICAST)
783 struct net_device *ldev = NULL; 829 p->flags |= IP6_TNL_F_CAP_XMIT;
784 int l_ok = 1; 830 if (rtype&IPV6_ADDR_UNICAST)
785 int r_ok = 1; 831 p->flags |= IP6_TNL_F_CAP_RCV;
786
787 if (p->link)
788 ldev = dev_get_by_index(p->link);
789
790 if (ltype&IPV6_ADDR_UNICAST && !ipv6_chk_addr(laddr, ldev, 0))
791 l_ok = 0;
792
793 if (rtype&IPV6_ADDR_UNICAST && ipv6_chk_addr(raddr, NULL, 0))
794 r_ok = 0;
795
796 if (l_ok && r_ok) {
797 if (ltype&IPV6_ADDR_UNICAST)
798 p->flags |= IP6_TNL_F_CAP_XMIT;
799 if (rtype&IPV6_ADDR_UNICAST)
800 p->flags |= IP6_TNL_F_CAP_RCV;
801 }
802 if (ldev)
803 dev_put(ldev);
804 } 832 }
805} 833}
806 834