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 --- |