sit.c (d94e5fcbf1420366dcb4102bafe04dbcfc0d0d4b) sit.c (fa857afcf77da669eb6b7031ec07ad14b912c307)
1/*
2 * IPv6 over IPv4 tunnel device - Simple Internet Transition (SIT)
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 147 unchanged lines hidden (view full) ---

156 struct ip_tunnel **tp = ipip6_bucket(sitn, t);
157
158 t->next = *tp;
159 write_lock_bh(&ipip6_lock);
160 *tp = t;
161 write_unlock_bh(&ipip6_lock);
162}
163
1/*
2 * IPv6 over IPv4 tunnel device - Simple Internet Transition (SIT)
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 147 unchanged lines hidden (view full) ---

156 struct ip_tunnel **tp = ipip6_bucket(sitn, t);
157
158 t->next = *tp;
159 write_lock_bh(&ipip6_lock);
160 *tp = t;
161 write_unlock_bh(&ipip6_lock);
162}
163
164static void ipip6_tunnel_clone_6rd(struct ip_tunnel *t, struct sit_net *sitn)
165{
166#ifdef CONFIG_IPV6_SIT_6RD
167 if (t->dev == sitn->fb_tunnel_dev) {
168 ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0);
169 t->ip6rd.relay_prefix = 0;
170 t->ip6rd.prefixlen = 16;
171 t->ip6rd.relay_prefixlen = 0;
172 } else {
173 struct ip_tunnel *t0 = netdev_priv(sitn->fb_tunnel_dev);
174 memcpy(&t->ip6rd, &t0->ip6rd, sizeof(t->ip6rd));
175 }
176#endif
177}
178
164static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
165 struct ip_tunnel_parm *parms, int create)
166{
167 __be32 remote = parms->iph.daddr;
168 __be32 local = parms->iph.saddr;
169 struct ip_tunnel *t, **tp, *nt;
170 struct net_device *dev;
171 char name[IFNAMSIZ];

--- 36 unchanged lines hidden (view full) ---

208 if (parms->i_flags & SIT_ISATAP)
209 dev->priv_flags |= IFF_ISATAP;
210
211 if (register_netdevice(dev) < 0)
212 goto failed_free;
213
214 dev_hold(dev);
215
179static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
180 struct ip_tunnel_parm *parms, int create)
181{
182 __be32 remote = parms->iph.daddr;
183 __be32 local = parms->iph.saddr;
184 struct ip_tunnel *t, **tp, *nt;
185 struct net_device *dev;
186 char name[IFNAMSIZ];

--- 36 unchanged lines hidden (view full) ---

223 if (parms->i_flags & SIT_ISATAP)
224 dev->priv_flags |= IFF_ISATAP;
225
226 if (register_netdevice(dev) < 0)
227 goto failed_free;
228
229 dev_hold(dev);
230
231 ipip6_tunnel_clone_6rd(t, sitn);
232
216 ipip6_tunnel_link(sitn, nt);
217 return nt;
218
219failed_free:
220 free_netdev(dev);
221failed:
222 return NULL;
223}

--- 303 unchanged lines hidden (view full) ---

527
528 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
529 read_unlock(&ipip6_lock);
530out:
531 kfree_skb(skb);
532 return 0;
533}
534
233 ipip6_tunnel_link(sitn, nt);
234 return nt;
235
236failed_free:
237 free_netdev(dev);
238failed:
239 return NULL;
240}

--- 303 unchanged lines hidden (view full) ---

544
545 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
546 read_unlock(&ipip6_lock);
547out:
548 kfree_skb(skb);
549 return 0;
550}
551
535/* Returns the embedded IPv4 address if the IPv6 address
536 comes from 6to4 (RFC 3056) addr space */
537
538static inline __be32 try_6to4(struct in6_addr *v6dst)
552/*
553 * Returns the embedded IPv4 address if the IPv6 address
554 * comes from 6rd / 6to4 (RFC 3056) addr space.
555 */
556static inline
557__be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel)
539{
540 __be32 dst = 0;
541
558{
559 __be32 dst = 0;
560
561#ifdef CONFIG_IPV6_SIT_6RD
562 if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix,
563 tunnel->ip6rd.prefixlen)) {
564 unsigned pbw0, pbi0;
565 int pbi1;
566 u32 d;
567
568 pbw0 = tunnel->ip6rd.prefixlen >> 5;
569 pbi0 = tunnel->ip6rd.prefixlen & 0x1f;
570
571 d = (ntohl(tunnel->ip6rd.prefix.s6_addr32[pbw0]) << pbi0) >>
572 tunnel->ip6rd.relay_prefixlen;
573
574 pbi1 = pbi0 - tunnel->ip6rd.relay_prefixlen;
575 if (pbi1 > 0)
576 d |= ntohl(tunnel->ip6rd.prefix.s6_addr32[pbw0 + 1]) >>
577 (32 - pbi1);
578
579 dst = tunnel->ip6rd.relay_prefix | htonl(d);
580 }
581#else
542 if (v6dst->s6_addr16[0] == htons(0x2002)) {
543 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
544 memcpy(&dst, &v6dst->s6_addr16[1], 4);
545 }
582 if (v6dst->s6_addr16[0] == htons(0x2002)) {
583 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
584 memcpy(&dst, &v6dst->s6_addr16[1], 4);
585 }
586#endif
546 return dst;
547}
548
549/*
550 * This function assumes it is being called from dev_queue_xmit()
551 * and that skb is filled properly by that function.
552 */
553
554static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
555 struct net_device *dev)
556{
557 struct ip_tunnel *tunnel = netdev_priv(dev);
587 return dst;
588}
589
590/*
591 * This function assumes it is being called from dev_queue_xmit()
592 * and that skb is filled properly by that function.
593 */
594
595static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
596 struct net_device *dev)
597{
598 struct ip_tunnel *tunnel = netdev_priv(dev);
558 struct net_device_stats *stats = &tunnel->dev->stats;
599 struct net_device_stats *stats = &dev->stats;
600 struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
559 struct iphdr *tiph = &tunnel->parms.iph;
560 struct ipv6hdr *iph6 = ipv6_hdr(skb);
561 u8 tos = tunnel->parms.iph.tos;
562 struct rtable *rt; /* Route to the other host */
563 struct net_device *tdev; /* Device to other host */
564 struct iphdr *iph; /* Our new IP header */
565 unsigned int max_headroom; /* The extra header space needed */
566 __be32 dst = tiph->daddr;

--- 23 unchanged lines hidden (view full) ---

590 if ((addr_type & IPV6_ADDR_UNICAST) &&
591 ipv6_addr_is_isatap(addr6))
592 dst = addr6->s6_addr32[3];
593 else
594 goto tx_error;
595 }
596
597 if (!dst)
601 struct iphdr *tiph = &tunnel->parms.iph;
602 struct ipv6hdr *iph6 = ipv6_hdr(skb);
603 u8 tos = tunnel->parms.iph.tos;
604 struct rtable *rt; /* Route to the other host */
605 struct net_device *tdev; /* Device to other host */
606 struct iphdr *iph; /* Our new IP header */
607 unsigned int max_headroom; /* The extra header space needed */
608 __be32 dst = tiph->daddr;

--- 23 unchanged lines hidden (view full) ---

632 if ((addr_type & IPV6_ADDR_UNICAST) &&
633 ipv6_addr_is_isatap(addr6))
634 dst = addr6->s6_addr32[3];
635 else
636 goto tx_error;
637 }
638
639 if (!dst)
598 dst = try_6to4(&iph6->daddr);
640 dst = try_6rd(&iph6->daddr, tunnel);
599
600 if (!dst) {
601 struct neighbour *neigh = NULL;
602
603 if (skb_dst(skb))
604 neigh = skb_dst(skb)->neighbour;
605
606 if (neigh == NULL) {

--- 76 unchanged lines hidden (view full) ---

683 */
684 max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
685
686 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
687 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
688 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
689 if (!new_skb) {
690 ip_rt_put(rt);
641
642 if (!dst) {
643 struct neighbour *neigh = NULL;
644
645 if (skb_dst(skb))
646 neigh = skb_dst(skb)->neighbour;
647
648 if (neigh == NULL) {

--- 76 unchanged lines hidden (view full) ---

725 */
726 max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
727
728 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
729 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
730 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
731 if (!new_skb) {
732 ip_rt_put(rt);
691 stats->tx_dropped++;
733 txq->tx_dropped++;
692 dev_kfree_skb(skb);
693 return NETDEV_TX_OK;
694 }
695 if (skb->sk)
696 skb_set_owner_w(new_skb, skb->sk);
697 dev_kfree_skb(skb);
698 skb = new_skb;
699 iph6 = ipv6_hdr(skb);

--- 80 unchanged lines hidden (view full) ---

780ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
781{
782 int err = 0;
783 struct ip_tunnel_parm p;
784 struct ip_tunnel_prl prl;
785 struct ip_tunnel *t;
786 struct net *net = dev_net(dev);
787 struct sit_net *sitn = net_generic(net, sit_net_id);
734 dev_kfree_skb(skb);
735 return NETDEV_TX_OK;
736 }
737 if (skb->sk)
738 skb_set_owner_w(new_skb, skb->sk);
739 dev_kfree_skb(skb);
740 skb = new_skb;
741 iph6 = ipv6_hdr(skb);

--- 80 unchanged lines hidden (view full) ---

822ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
823{
824 int err = 0;
825 struct ip_tunnel_parm p;
826 struct ip_tunnel_prl prl;
827 struct ip_tunnel *t;
828 struct net *net = dev_net(dev);
829 struct sit_net *sitn = net_generic(net, sit_net_id);
830#ifdef CONFIG_IPV6_SIT_6RD
831 struct ip_tunnel_6rd ip6rd;
832#endif
788
789 switch (cmd) {
790 case SIOCGETTUNNEL:
833
834 switch (cmd) {
835 case SIOCGETTUNNEL:
836#ifdef CONFIG_IPV6_SIT_6RD
837 case SIOCGET6RD:
838#endif
791 t = NULL;
792 if (dev == sitn->fb_tunnel_dev) {
793 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
794 err = -EFAULT;
795 break;
796 }
797 t = ipip6_tunnel_locate(net, &p, 0);
798 }
799 if (t == NULL)
800 t = netdev_priv(dev);
839 t = NULL;
840 if (dev == sitn->fb_tunnel_dev) {
841 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
842 err = -EFAULT;
843 break;
844 }
845 t = ipip6_tunnel_locate(net, &p, 0);
846 }
847 if (t == NULL)
848 t = netdev_priv(dev);
801 memcpy(&p, &t->parms, sizeof(p));
802 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
803 err = -EFAULT;
849
850 err = -EFAULT;
851 if (cmd == SIOCGETTUNNEL) {
852 memcpy(&p, &t->parms, sizeof(p));
853 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p,
854 sizeof(p)))
855 goto done;
856#ifdef CONFIG_IPV6_SIT_6RD
857 } else {
858 ipv6_addr_copy(&ip6rd.prefix, &t->ip6rd.prefix);
859 ip6rd.relay_prefix = t->ip6rd.relay_prefix;
860 ip6rd.prefixlen = t->ip6rd.prefixlen;
861 ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen;
862 if (copy_to_user(ifr->ifr_ifru.ifru_data, &ip6rd,
863 sizeof(ip6rd)))
864 goto done;
865#endif
866 }
867 err = 0;
804 break;
805
806 case SIOCADDTUNNEL:
807 case SIOCCHGTUNNEL:
808 err = -EPERM;
809 if (!capable(CAP_NET_ADMIN))
810 goto done;
811

--- 104 unchanged lines hidden (view full) ---

916 case SIOCADDPRL:
917 case SIOCCHGPRL:
918 err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
919 break;
920 }
921 netdev_state_change(dev);
922 break;
923
868 break;
869
870 case SIOCADDTUNNEL:
871 case SIOCCHGTUNNEL:
872 err = -EPERM;
873 if (!capable(CAP_NET_ADMIN))
874 goto done;
875

--- 104 unchanged lines hidden (view full) ---

980 case SIOCADDPRL:
981 case SIOCCHGPRL:
982 err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
983 break;
984 }
985 netdev_state_change(dev);
986 break;
987
988#ifdef CONFIG_IPV6_SIT_6RD
989 case SIOCADD6RD:
990 case SIOCCHG6RD:
991 case SIOCDEL6RD:
992 err = -EPERM;
993 if (!capable(CAP_NET_ADMIN))
994 goto done;
995
996 err = -EFAULT;
997 if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data,
998 sizeof(ip6rd)))
999 goto done;
1000
1001 t = netdev_priv(dev);
1002
1003 if (cmd != SIOCDEL6RD) {
1004 struct in6_addr prefix;
1005 __be32 relay_prefix;
1006
1007 err = -EINVAL;
1008 if (ip6rd.relay_prefixlen > 32 ||
1009 ip6rd.prefixlen + (32 - ip6rd.relay_prefixlen) > 64)
1010 goto done;
1011
1012 ipv6_addr_prefix(&prefix, &ip6rd.prefix,
1013 ip6rd.prefixlen);
1014 if (!ipv6_addr_equal(&prefix, &ip6rd.prefix))
1015 goto done;
1016 relay_prefix = ip6rd.relay_prefix &
1017 htonl(0xffffffffUL <<
1018 (32 - ip6rd.relay_prefixlen));
1019 if (relay_prefix != ip6rd.relay_prefix)
1020 goto done;
1021
1022 ipv6_addr_copy(&t->ip6rd.prefix, &prefix);
1023 t->ip6rd.relay_prefix = relay_prefix;
1024 t->ip6rd.prefixlen = ip6rd.prefixlen;
1025 t->ip6rd.relay_prefixlen = ip6rd.relay_prefixlen;
1026 } else
1027 ipip6_tunnel_clone_6rd(t, sitn);
1028
1029 err = 0;
1030 break;
1031#endif
1032
924 default:
925 err = -EINVAL;
926 }
927
928done:
929 return err;
930}
931

--- 173 unchanged lines hidden ---
1033 default:
1034 err = -EINVAL;
1035 }
1036
1037done:
1038 return err;
1039}
1040

--- 173 unchanged lines hidden ---