aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig16
-rw-r--r--net/ipv6/Makefile1
-rw-r--r--net/ipv6/addrconf.c73
-rw-r--r--net/ipv6/addrlabel.c24
-rw-r--r--net/ipv6/ip6_flowlabel.c47
-rw-r--r--net/ipv6/ip6_gre.c1792
-rw-r--r--net/ipv6/ip6_output.c20
-rw-r--r--net/ipv6/ip6_tunnel.c91
-rw-r--r--net/ipv6/ip6mr.c10
-rw-r--r--net/ipv6/netfilter.c8
-rw-r--r--net/ipv6/netfilter/Kconfig54
-rw-r--r--net/ipv6/netfilter/Makefile8
-rw-r--r--net/ipv6/netfilter/ip6t_MASQUERADE.c135
-rw-r--r--net/ipv6/netfilter/ip6t_NETMAP.c94
-rw-r--r--net/ipv6/netfilter/ip6t_NPT.c165
-rw-r--r--net/ipv6/netfilter/ip6t_REDIRECT.c98
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c4
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c4
-rw-r--r--net/ipv6/netfilter/ip6table_nat.c321
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c4
-rw-r--r--net/ipv6/netfilter/ip6table_security.c5
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c137
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c19
-rw-r--r--net/ipv6/netfilter/nf_nat_l3proto_ipv6.c288
-rw-r--r--net/ipv6/netfilter/nf_nat_proto_icmpv6.c90
-rw-r--r--net/ipv6/raw.c3
-rw-r--r--net/ipv6/route.c90
-rw-r--r--net/ipv6/syncookies.c1
-rw-r--r--net/ipv6/tcp_ipv6.c20
-rw-r--r--net/ipv6/udp.c3
30 files changed, 3397 insertions, 228 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 5728695b5449..4f7fe7270e37 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -201,6 +201,22 @@ config IPV6_TUNNEL
201 201
202 If unsure, say N. 202 If unsure, say N.
203 203
204config IPV6_GRE
205 tristate "IPv6: GRE tunnel"
206 select IPV6_TUNNEL
207 ---help---
208 Tunneling means encapsulating data of one protocol type within
209 another protocol and sending it over a channel that understands the
210 encapsulating protocol. This particular tunneling driver implements
211 GRE (Generic Routing Encapsulation) and at this time allows
212 encapsulating of IPv4 or IPv6 over existing IPv6 infrastructure.
213 This driver is useful if the other endpoint is a Cisco router: Cisco
214 likes GRE much better than the other Linux tunneling driver ("IP
215 tunneling" above). In addition, GRE allows multicast redistribution
216 through the tunnel.
217
218 Saying M here will produce a module called ip6_gre. If unsure, say N.
219
204config IPV6_MULTIPLE_TABLES 220config IPV6_MULTIPLE_TABLES
205 bool "IPv6: Multiple Routing Tables" 221 bool "IPv6: Multiple Routing Tables"
206 depends on EXPERIMENTAL 222 depends on EXPERIMENTAL
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 686934acfac1..b6d3f79151e2 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_NETFILTER) += netfilter/
36 36
37obj-$(CONFIG_IPV6_SIT) += sit.o 37obj-$(CONFIG_IPV6_SIT) += sit.o
38obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 38obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
39obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
39 40
40obj-y += addrconf_core.o exthdrs_core.o 41obj-y += addrconf_core.o exthdrs_core.o
41 42
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6bc85f7c31e3..719a828fb67f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -127,8 +127,8 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
127#endif 127#endif
128 128
129#ifdef CONFIG_IPV6_PRIVACY 129#ifdef CONFIG_IPV6_PRIVACY
130static int __ipv6_regen_rndid(struct inet6_dev *idev); 130static void __ipv6_regen_rndid(struct inet6_dev *idev);
131static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 131static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
132static void ipv6_regen_rndid(unsigned long data); 132static void ipv6_regen_rndid(unsigned long data);
133#endif 133#endif
134 134
@@ -852,16 +852,7 @@ retry:
852 } 852 }
853 in6_ifa_hold(ifp); 853 in6_ifa_hold(ifp);
854 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); 854 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
855 if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { 855 __ipv6_try_regen_rndid(idev, tmpaddr);
856 spin_unlock_bh(&ifp->lock);
857 write_unlock(&idev->lock);
858 pr_warn("%s: regeneration of randomized interface id failed\n",
859 __func__);
860 in6_ifa_put(ifp);
861 in6_dev_put(idev);
862 ret = -1;
863 goto out;
864 }
865 memcpy(&addr.s6_addr[8], idev->rndid, 8); 856 memcpy(&addr.s6_addr[8], idev->rndid, 8);
866 age = (now - ifp->tstamp) / HZ; 857 age = (now - ifp->tstamp) / HZ;
867 tmp_valid_lft = min_t(__u32, 858 tmp_valid_lft = min_t(__u32,
@@ -1079,8 +1070,10 @@ static int ipv6_get_saddr_eval(struct net *net,
1079 break; 1070 break;
1080 case IPV6_SADDR_RULE_PREFIX: 1071 case IPV6_SADDR_RULE_PREFIX:
1081 /* Rule 8: Use longest matching prefix */ 1072 /* Rule 8: Use longest matching prefix */
1082 score->matchlen = ret = ipv6_addr_diff(&score->ifa->addr, 1073 ret = ipv6_addr_diff(&score->ifa->addr, dst->addr);
1083 dst->addr); 1074 if (ret > score->ifa->prefix_len)
1075 ret = score->ifa->prefix_len;
1076 score->matchlen = ret;
1084 break; 1077 break;
1085 default: 1078 default:
1086 ret = 0; 1079 ret = 0;
@@ -1093,7 +1086,7 @@ out:
1093 return ret; 1086 return ret;
1094} 1087}
1095 1088
1096int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, 1089int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
1097 const struct in6_addr *daddr, unsigned int prefs, 1090 const struct in6_addr *daddr, unsigned int prefs,
1098 struct in6_addr *saddr) 1091 struct in6_addr *saddr)
1099{ 1092{
@@ -1600,7 +1593,7 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1600 1593
1601#ifdef CONFIG_IPV6_PRIVACY 1594#ifdef CONFIG_IPV6_PRIVACY
1602/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */ 1595/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
1603static int __ipv6_regen_rndid(struct inet6_dev *idev) 1596static void __ipv6_regen_rndid(struct inet6_dev *idev)
1604{ 1597{
1605regen: 1598regen:
1606 get_random_bytes(idev->rndid, sizeof(idev->rndid)); 1599 get_random_bytes(idev->rndid, sizeof(idev->rndid));
@@ -1627,8 +1620,6 @@ regen:
1627 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00) 1620 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
1628 goto regen; 1621 goto regen;
1629 } 1622 }
1630
1631 return 0;
1632} 1623}
1633 1624
1634static void ipv6_regen_rndid(unsigned long data) 1625static void ipv6_regen_rndid(unsigned long data)
@@ -1642,8 +1633,7 @@ static void ipv6_regen_rndid(unsigned long data)
1642 if (idev->dead) 1633 if (idev->dead)
1643 goto out; 1634 goto out;
1644 1635
1645 if (__ipv6_regen_rndid(idev) < 0) 1636 __ipv6_regen_rndid(idev);
1646 goto out;
1647 1637
1648 expires = jiffies + 1638 expires = jiffies +
1649 idev->cnf.temp_prefered_lft * HZ - 1639 idev->cnf.temp_prefered_lft * HZ -
@@ -1664,13 +1654,10 @@ out:
1664 in6_dev_put(idev); 1654 in6_dev_put(idev);
1665} 1655}
1666 1656
1667static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) 1657static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
1668{ 1658{
1669 int ret = 0;
1670
1671 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0) 1659 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
1672 ret = __ipv6_regen_rndid(idev); 1660 __ipv6_regen_rndid(idev);
1673 return ret;
1674} 1661}
1675#endif 1662#endif
1676 1663
@@ -1721,7 +1708,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1721 if (table == NULL) 1708 if (table == NULL)
1722 return NULL; 1709 return NULL;
1723 1710
1724 write_lock_bh(&table->tb6_lock); 1711 read_lock_bh(&table->tb6_lock);
1725 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0); 1712 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
1726 if (!fn) 1713 if (!fn)
1727 goto out; 1714 goto out;
@@ -1736,7 +1723,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1736 break; 1723 break;
1737 } 1724 }
1738out: 1725out:
1739 write_unlock_bh(&table->tb6_lock); 1726 read_unlock_bh(&table->tb6_lock);
1740 return rt; 1727 return rt;
1741} 1728}
1742 1729
@@ -3549,12 +3536,12 @@ static inline int inet6_ifaddr_msgsize(void)
3549} 3536}
3550 3537
3551static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3538static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3552 u32 pid, u32 seq, int event, unsigned int flags) 3539 u32 portid, u32 seq, int event, unsigned int flags)
3553{ 3540{
3554 struct nlmsghdr *nlh; 3541 struct nlmsghdr *nlh;
3555 u32 preferred, valid; 3542 u32 preferred, valid;
3556 3543
3557 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3544 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3558 if (nlh == NULL) 3545 if (nlh == NULL)
3559 return -EMSGSIZE; 3546 return -EMSGSIZE;
3560 3547
@@ -3592,7 +3579,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3592} 3579}
3593 3580
3594static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3581static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3595 u32 pid, u32 seq, int event, u16 flags) 3582 u32 portid, u32 seq, int event, u16 flags)
3596{ 3583{
3597 struct nlmsghdr *nlh; 3584 struct nlmsghdr *nlh;
3598 u8 scope = RT_SCOPE_UNIVERSE; 3585 u8 scope = RT_SCOPE_UNIVERSE;
@@ -3601,7 +3588,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3601 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE) 3588 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
3602 scope = RT_SCOPE_SITE; 3589 scope = RT_SCOPE_SITE;
3603 3590
3604 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3591 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3605 if (nlh == NULL) 3592 if (nlh == NULL)
3606 return -EMSGSIZE; 3593 return -EMSGSIZE;
3607 3594
@@ -3617,7 +3604,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3617} 3604}
3618 3605
3619static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, 3606static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3620 u32 pid, u32 seq, int event, unsigned int flags) 3607 u32 portid, u32 seq, int event, unsigned int flags)
3621{ 3608{
3622 struct nlmsghdr *nlh; 3609 struct nlmsghdr *nlh;
3623 u8 scope = RT_SCOPE_UNIVERSE; 3610 u8 scope = RT_SCOPE_UNIVERSE;
@@ -3626,7 +3613,7 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3626 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE) 3613 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
3627 scope = RT_SCOPE_SITE; 3614 scope = RT_SCOPE_SITE;
3628 3615
3629 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3616 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3630 if (nlh == NULL) 3617 if (nlh == NULL)
3631 return -EMSGSIZE; 3618 return -EMSGSIZE;
3632 3619
@@ -3667,7 +3654,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3667 if (++ip_idx < s_ip_idx) 3654 if (++ip_idx < s_ip_idx)
3668 continue; 3655 continue;
3669 err = inet6_fill_ifaddr(skb, ifa, 3656 err = inet6_fill_ifaddr(skb, ifa,
3670 NETLINK_CB(cb->skb).pid, 3657 NETLINK_CB(cb->skb).portid,
3671 cb->nlh->nlmsg_seq, 3658 cb->nlh->nlmsg_seq,
3672 RTM_NEWADDR, 3659 RTM_NEWADDR,
3673 NLM_F_MULTI); 3660 NLM_F_MULTI);
@@ -3683,7 +3670,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3683 if (ip_idx < s_ip_idx) 3670 if (ip_idx < s_ip_idx)
3684 continue; 3671 continue;
3685 err = inet6_fill_ifmcaddr(skb, ifmca, 3672 err = inet6_fill_ifmcaddr(skb, ifmca,
3686 NETLINK_CB(cb->skb).pid, 3673 NETLINK_CB(cb->skb).portid,
3687 cb->nlh->nlmsg_seq, 3674 cb->nlh->nlmsg_seq,
3688 RTM_GETMULTICAST, 3675 RTM_GETMULTICAST,
3689 NLM_F_MULTI); 3676 NLM_F_MULTI);
@@ -3698,7 +3685,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3698 if (ip_idx < s_ip_idx) 3685 if (ip_idx < s_ip_idx)
3699 continue; 3686 continue;
3700 err = inet6_fill_ifacaddr(skb, ifaca, 3687 err = inet6_fill_ifacaddr(skb, ifaca,
3701 NETLINK_CB(cb->skb).pid, 3688 NETLINK_CB(cb->skb).portid,
3702 cb->nlh->nlmsg_seq, 3689 cb->nlh->nlmsg_seq,
3703 RTM_GETANYCAST, 3690 RTM_GETANYCAST,
3704 NLM_F_MULTI); 3691 NLM_F_MULTI);
@@ -3820,7 +3807,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3820 goto errout_ifa; 3807 goto errout_ifa;
3821 } 3808 }
3822 3809
3823 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3810 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
3824 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3811 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3825 if (err < 0) { 3812 if (err < 0) {
3826 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ 3813 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
@@ -3828,7 +3815,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3828 kfree_skb(skb); 3815 kfree_skb(skb);
3829 goto errout_ifa; 3816 goto errout_ifa;
3830 } 3817 }
3831 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 3818 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
3832errout_ifa: 3819errout_ifa:
3833 in6_ifa_put(ifa); 3820 in6_ifa_put(ifa);
3834errout: 3821errout:
@@ -4030,14 +4017,14 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
4030} 4017}
4031 4018
4032static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 4019static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
4033 u32 pid, u32 seq, int event, unsigned int flags) 4020 u32 portid, u32 seq, int event, unsigned int flags)
4034{ 4021{
4035 struct net_device *dev = idev->dev; 4022 struct net_device *dev = idev->dev;
4036 struct ifinfomsg *hdr; 4023 struct ifinfomsg *hdr;
4037 struct nlmsghdr *nlh; 4024 struct nlmsghdr *nlh;
4038 void *protoinfo; 4025 void *protoinfo;
4039 4026
4040 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 4027 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*hdr), flags);
4041 if (nlh == NULL) 4028 if (nlh == NULL)
4042 return -EMSGSIZE; 4029 return -EMSGSIZE;
4043 4030
@@ -4095,7 +4082,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
4095 if (!idev) 4082 if (!idev)
4096 goto cont; 4083 goto cont;
4097 if (inet6_fill_ifinfo(skb, idev, 4084 if (inet6_fill_ifinfo(skb, idev,
4098 NETLINK_CB(cb->skb).pid, 4085 NETLINK_CB(cb->skb).portid,
4099 cb->nlh->nlmsg_seq, 4086 cb->nlh->nlmsg_seq,
4100 RTM_NEWLINK, NLM_F_MULTI) <= 0) 4087 RTM_NEWLINK, NLM_F_MULTI) <= 0)
4101 goto out; 4088 goto out;
@@ -4143,14 +4130,14 @@ static inline size_t inet6_prefix_nlmsg_size(void)
4143} 4130}
4144 4131
4145static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 4132static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
4146 struct prefix_info *pinfo, u32 pid, u32 seq, 4133 struct prefix_info *pinfo, u32 portid, u32 seq,
4147 int event, unsigned int flags) 4134 int event, unsigned int flags)
4148{ 4135{
4149 struct prefixmsg *pmsg; 4136 struct prefixmsg *pmsg;
4150 struct nlmsghdr *nlh; 4137 struct nlmsghdr *nlh;
4151 struct prefix_cacheinfo ci; 4138 struct prefix_cacheinfo ci;
4152 4139
4153 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags); 4140 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*pmsg), flags);
4154 if (nlh == NULL) 4141 if (nlh == NULL)
4155 return -EMSGSIZE; 4142 return -EMSGSIZE;
4156 4143
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index eb6a63632d3c..4be23da32b89 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -57,7 +57,7 @@ struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
57} 57}
58 58
59/* 59/*
60 * Default policy table (RFC3484 + extensions) 60 * Default policy table (RFC6724 + extensions)
61 * 61 *
62 * prefix addr_type label 62 * prefix addr_type label
63 * ------------------------------------------------------------------------- 63 * -------------------------------------------------------------------------
@@ -69,8 +69,12 @@ struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
69 * fc00::/7 N/A 5 ULA (RFC 4193) 69 * fc00::/7 N/A 5 ULA (RFC 4193)
70 * 2001::/32 N/A 6 Teredo (RFC 4380) 70 * 2001::/32 N/A 6 Teredo (RFC 4380)
71 * 2001:10::/28 N/A 7 ORCHID (RFC 4843) 71 * 2001:10::/28 N/A 7 ORCHID (RFC 4843)
72 * fec0::/10 N/A 11 Site-local
73 * (deprecated by RFC3879)
74 * 3ffe::/16 N/A 12 6bone
72 * 75 *
73 * Note: 0xffffffff is used if we do not have any policies. 76 * Note: 0xffffffff is used if we do not have any policies.
77 * Note: Labels for ULA and 6to4 are different from labels listed in RFC6724.
74 */ 78 */
75 79
76#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 80#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL
@@ -88,10 +92,18 @@ static const __net_initdata struct ip6addrlbl_init_table
88 .prefix = &(struct in6_addr){{{ 0xfc }}}, 92 .prefix = &(struct in6_addr){{{ 0xfc }}},
89 .prefixlen = 7, 93 .prefixlen = 7,
90 .label = 5, 94 .label = 5,
95 },{ /* fec0::/10 */
96 .prefix = &(struct in6_addr){{{ 0xfe, 0xc0 }}},
97 .prefixlen = 10,
98 .label = 11,
91 },{ /* 2002::/16 */ 99 },{ /* 2002::/16 */
92 .prefix = &(struct in6_addr){{{ 0x20, 0x02 }}}, 100 .prefix = &(struct in6_addr){{{ 0x20, 0x02 }}},
93 .prefixlen = 16, 101 .prefixlen = 16,
94 .label = 2, 102 .label = 2,
103 },{ /* 3ffe::/16 */
104 .prefix = &(struct in6_addr){{{ 0x3f, 0xfe }}},
105 .prefixlen = 16,
106 .label = 12,
95 },{ /* 2001::/32 */ 107 },{ /* 2001::/32 */
96 .prefix = &(struct in6_addr){{{ 0x20, 0x01 }}}, 108 .prefix = &(struct in6_addr){{{ 0x20, 0x01 }}},
97 .prefixlen = 32, 109 .prefixlen = 32,
@@ -470,10 +482,10 @@ static void ip6addrlbl_putmsg(struct nlmsghdr *nlh,
470static int ip6addrlbl_fill(struct sk_buff *skb, 482static int ip6addrlbl_fill(struct sk_buff *skb,
471 struct ip6addrlbl_entry *p, 483 struct ip6addrlbl_entry *p,
472 u32 lseq, 484 u32 lseq,
473 u32 pid, u32 seq, int event, 485 u32 portid, u32 seq, int event,
474 unsigned int flags) 486 unsigned int flags)
475{ 487{
476 struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, event, 488 struct nlmsghdr *nlh = nlmsg_put(skb, portid, seq, event,
477 sizeof(struct ifaddrlblmsg), flags); 489 sizeof(struct ifaddrlblmsg), flags);
478 if (!nlh) 490 if (!nlh)
479 return -EMSGSIZE; 491 return -EMSGSIZE;
@@ -503,7 +515,7 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
503 net_eq(ip6addrlbl_net(p), net)) { 515 net_eq(ip6addrlbl_net(p), net)) {
504 if ((err = ip6addrlbl_fill(skb, p, 516 if ((err = ip6addrlbl_fill(skb, p,
505 ip6addrlbl_table.seq, 517 ip6addrlbl_table.seq,
506 NETLINK_CB(cb->skb).pid, 518 NETLINK_CB(cb->skb).portid,
507 cb->nlh->nlmsg_seq, 519 cb->nlh->nlmsg_seq,
508 RTM_NEWADDRLABEL, 520 RTM_NEWADDRLABEL,
509 NLM_F_MULTI)) <= 0) 521 NLM_F_MULTI)) <= 0)
@@ -574,7 +586,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
574 } 586 }
575 587
576 err = ip6addrlbl_fill(skb, p, lseq, 588 err = ip6addrlbl_fill(skb, p, lseq,
577 NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 589 NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
578 RTM_NEWADDRLABEL, 0); 590 RTM_NEWADDRLABEL, 0);
579 591
580 ip6addrlbl_put(p); 592 ip6addrlbl_put(p);
@@ -585,7 +597,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
585 goto out; 597 goto out;
586 } 598 }
587 599
588 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 600 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
589out: 601out:
590 return err; 602 return err;
591} 603}
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 9772fbd8a3f5..90bbefb57943 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/pid_namespace.h>
25 26
26#include <net/net_namespace.h> 27#include <net/net_namespace.h>
27#include <net/sock.h> 28#include <net/sock.h>
@@ -91,6 +92,8 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label)
91static void fl_free(struct ip6_flowlabel *fl) 92static void fl_free(struct ip6_flowlabel *fl)
92{ 93{
93 if (fl) { 94 if (fl) {
95 if (fl->share == IPV6_FL_S_PROCESS)
96 put_pid(fl->owner.pid);
94 release_net(fl->fl_net); 97 release_net(fl->fl_net);
95 kfree(fl->opt); 98 kfree(fl->opt);
96 } 99 }
@@ -394,10 +397,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
394 case IPV6_FL_S_ANY: 397 case IPV6_FL_S_ANY:
395 break; 398 break;
396 case IPV6_FL_S_PROCESS: 399 case IPV6_FL_S_PROCESS:
397 fl->owner = current->pid; 400 fl->owner.pid = get_task_pid(current, PIDTYPE_PID);
398 break; 401 break;
399 case IPV6_FL_S_USER: 402 case IPV6_FL_S_USER:
400 fl->owner = current_euid(); 403 fl->owner.uid = current_euid();
401 break; 404 break;
402 default: 405 default:
403 err = -EINVAL; 406 err = -EINVAL;
@@ -561,7 +564,10 @@ recheck:
561 err = -EPERM; 564 err = -EPERM;
562 if (fl1->share == IPV6_FL_S_EXCL || 565 if (fl1->share == IPV6_FL_S_EXCL ||
563 fl1->share != fl->share || 566 fl1->share != fl->share ||
564 fl1->owner != fl->owner) 567 ((fl1->share == IPV6_FL_S_PROCESS) &&
568 (fl1->owner.pid == fl->owner.pid)) ||
569 ((fl1->share == IPV6_FL_S_USER) &&
570 uid_eq(fl1->owner.uid, fl->owner.uid)))
565 goto release; 571 goto release;
566 572
567 err = -EINVAL; 573 err = -EINVAL;
@@ -621,6 +627,7 @@ done:
621 627
622struct ip6fl_iter_state { 628struct ip6fl_iter_state {
623 struct seq_net_private p; 629 struct seq_net_private p;
630 struct pid_namespace *pid_ns;
624 int bucket; 631 int bucket;
625}; 632};
626 633
@@ -699,6 +706,7 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v)
699 706
700static int ip6fl_seq_show(struct seq_file *seq, void *v) 707static int ip6fl_seq_show(struct seq_file *seq, void *v)
701{ 708{
709 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
702 if (v == SEQ_START_TOKEN) 710 if (v == SEQ_START_TOKEN)
703 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", 711 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
704 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); 712 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
@@ -708,7 +716,11 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
708 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", 716 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
709 (unsigned int)ntohl(fl->label), 717 (unsigned int)ntohl(fl->label),
710 fl->share, 718 fl->share,
711 (int)fl->owner, 719 ((fl->share == IPV6_FL_S_PROCESS) ?
720 pid_nr_ns(fl->owner.pid, state->pid_ns) :
721 ((fl->share == IPV6_FL_S_USER) ?
722 from_kuid_munged(seq_user_ns(seq), fl->owner.uid) :
723 0)),
712 atomic_read(&fl->users), 724 atomic_read(&fl->users),
713 fl->linger/HZ, 725 fl->linger/HZ,
714 (long)(fl->expires - jiffies)/HZ, 726 (long)(fl->expires - jiffies)/HZ,
@@ -727,8 +739,29 @@ static const struct seq_operations ip6fl_seq_ops = {
727 739
728static int ip6fl_seq_open(struct inode *inode, struct file *file) 740static int ip6fl_seq_open(struct inode *inode, struct file *file)
729{ 741{
730 return seq_open_net(inode, file, &ip6fl_seq_ops, 742 struct seq_file *seq;
731 sizeof(struct ip6fl_iter_state)); 743 struct ip6fl_iter_state *state;
744 int err;
745
746 err = seq_open_net(inode, file, &ip6fl_seq_ops,
747 sizeof(struct ip6fl_iter_state));
748
749 if (!err) {
750 seq = file->private_data;
751 state = ip6fl_seq_private(seq);
752 rcu_read_lock();
753 state->pid_ns = get_pid_ns(task_active_pid_ns(current));
754 rcu_read_unlock();
755 }
756 return err;
757}
758
759static int ip6fl_seq_release(struct inode *inode, struct file *file)
760{
761 struct seq_file *seq = file->private_data;
762 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
763 put_pid_ns(state->pid_ns);
764 return seq_release_net(inode, file);
732} 765}
733 766
734static const struct file_operations ip6fl_seq_fops = { 767static const struct file_operations ip6fl_seq_fops = {
@@ -736,7 +769,7 @@ static const struct file_operations ip6fl_seq_fops = {
736 .open = ip6fl_seq_open, 769 .open = ip6fl_seq_open,
737 .read = seq_read, 770 .read = seq_read,
738 .llseek = seq_lseek, 771 .llseek = seq_lseek,
739 .release = seq_release_net, 772 .release = ip6fl_seq_release,
740}; 773};
741 774
742static int __net_init ip6_flowlabel_proc_init(struct net *net) 775static int __net_init ip6_flowlabel_proc_init(struct net *net)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
new file mode 100644
index 000000000000..424d11a4e7ff
--- /dev/null
+++ b/net/ipv6/ip6_gre.c
@@ -0,0 +1,1792 @@
1/*
2 * GRE over IPv6 protocol decoder.
3 *
4 * Authors: Dmitry Kozlov (xeb@mail.ru)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/capability.h>
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <linux/uaccess.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/in.h>
24#include <linux/tcp.h>
25#include <linux/udp.h>
26#include <linux/if_arp.h>
27#include <linux/mroute.h>
28#include <linux/init.h>
29#include <linux/in6.h>
30#include <linux/inetdevice.h>
31#include <linux/igmp.h>
32#include <linux/netfilter_ipv4.h>
33#include <linux/etherdevice.h>
34#include <linux/if_ether.h>
35#include <linux/hash.h>
36#include <linux/if_tunnel.h>
37#include <linux/ip6_tunnel.h>
38
39#include <net/sock.h>
40#include <net/ip.h>
41#include <net/icmp.h>
42#include <net/protocol.h>
43#include <net/addrconf.h>
44#include <net/arp.h>
45#include <net/checksum.h>
46#include <net/dsfield.h>
47#include <net/inet_ecn.h>
48#include <net/xfrm.h>
49#include <net/net_namespace.h>
50#include <net/netns/generic.h>
51#include <net/rtnetlink.h>
52
53#include <net/ipv6.h>
54#include <net/ip6_fib.h>
55#include <net/ip6_route.h>
56#include <net/ip6_tunnel.h>
57
58
59#define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK)
60#define IPV6_TCLASS_SHIFT 20
61
62#define HASH_SIZE_SHIFT 5
63#define HASH_SIZE (1 << HASH_SIZE_SHIFT)
64
65static int ip6gre_net_id __read_mostly;
66struct ip6gre_net {
67 struct ip6_tnl __rcu *tunnels[4][HASH_SIZE];
68
69 struct net_device *fb_tunnel_dev;
70};
71
72static struct rtnl_link_ops ip6gre_link_ops __read_mostly;
73static int ip6gre_tunnel_init(struct net_device *dev);
74static void ip6gre_tunnel_setup(struct net_device *dev);
75static void ip6gre_tunnel_link(struct ip6gre_net *ign, struct ip6_tnl *t);
76static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu);
77
78/* Tunnel hash table */
79
80/*
81 4 hash tables:
82
83 3: (remote,local)
84 2: (remote,*)
85 1: (*,local)
86 0: (*,*)
87
88 We require exact key match i.e. if a key is present in packet
89 it will match only tunnel with the same key; if it is not present,
90 it will match only keyless tunnel.
91
92 All keysless packets, if not matched configured keyless tunnels
93 will match fallback tunnel.
94 */
95
96#define HASH_KEY(key) (((__force u32)key^((__force u32)key>>4))&(HASH_SIZE - 1))
97static u32 HASH_ADDR(const struct in6_addr *addr)
98{
99 u32 hash = ipv6_addr_hash(addr);
100
101 return hash_32(hash, HASH_SIZE_SHIFT);
102}
103
104#define tunnels_r_l tunnels[3]
105#define tunnels_r tunnels[2]
106#define tunnels_l tunnels[1]
107#define tunnels_wc tunnels[0]
108/*
109 * Locking : hash tables are protected by RCU and RTNL
110 */
111
112#define for_each_ip_tunnel_rcu(start) \
113 for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
114
115/* often modified stats are per cpu, other are shared (netdev->stats) */
116struct pcpu_tstats {
117 u64 rx_packets;
118 u64 rx_bytes;
119 u64 tx_packets;
120 u64 tx_bytes;
121 struct u64_stats_sync syncp;
122};
123
124static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev,
125 struct rtnl_link_stats64 *tot)
126{
127 int i;
128
129 for_each_possible_cpu(i) {
130 const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
131 u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
132 unsigned int start;
133
134 do {
135 start = u64_stats_fetch_begin_bh(&tstats->syncp);
136 rx_packets = tstats->rx_packets;
137 tx_packets = tstats->tx_packets;
138 rx_bytes = tstats->rx_bytes;
139 tx_bytes = tstats->tx_bytes;
140 } while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
141
142 tot->rx_packets += rx_packets;
143 tot->tx_packets += tx_packets;
144 tot->rx_bytes += rx_bytes;
145 tot->tx_bytes += tx_bytes;
146 }
147
148 tot->multicast = dev->stats.multicast;
149 tot->rx_crc_errors = dev->stats.rx_crc_errors;
150 tot->rx_fifo_errors = dev->stats.rx_fifo_errors;
151 tot->rx_length_errors = dev->stats.rx_length_errors;
152 tot->rx_errors = dev->stats.rx_errors;
153 tot->tx_fifo_errors = dev->stats.tx_fifo_errors;
154 tot->tx_carrier_errors = dev->stats.tx_carrier_errors;
155 tot->tx_dropped = dev->stats.tx_dropped;
156 tot->tx_aborted_errors = dev->stats.tx_aborted_errors;
157 tot->tx_errors = dev->stats.tx_errors;
158
159 return tot;
160}
161
162/* Given src, dst and key, find appropriate for input tunnel. */
163
164static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
165 const struct in6_addr *remote, const struct in6_addr *local,
166 __be32 key, __be16 gre_proto)
167{
168 struct net *net = dev_net(dev);
169 int link = dev->ifindex;
170 unsigned int h0 = HASH_ADDR(remote);
171 unsigned int h1 = HASH_KEY(key);
172 struct ip6_tnl *t, *cand = NULL;
173 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
174 int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
175 ARPHRD_ETHER : ARPHRD_IP6GRE;
176 int score, cand_score = 4;
177
178 for_each_ip_tunnel_rcu(ign->tunnels_r_l[h0 ^ h1]) {
179 if (!ipv6_addr_equal(local, &t->parms.laddr) ||
180 !ipv6_addr_equal(remote, &t->parms.raddr) ||
181 key != t->parms.i_key ||
182 !(t->dev->flags & IFF_UP))
183 continue;
184
185 if (t->dev->type != ARPHRD_IP6GRE &&
186 t->dev->type != dev_type)
187 continue;
188
189 score = 0;
190 if (t->parms.link != link)
191 score |= 1;
192 if (t->dev->type != dev_type)
193 score |= 2;
194 if (score == 0)
195 return t;
196
197 if (score < cand_score) {
198 cand = t;
199 cand_score = score;
200 }
201 }
202
203 for_each_ip_tunnel_rcu(ign->tunnels_r[h0 ^ h1]) {
204 if (!ipv6_addr_equal(remote, &t->parms.raddr) ||
205 key != t->parms.i_key ||
206 !(t->dev->flags & IFF_UP))
207 continue;
208
209 if (t->dev->type != ARPHRD_IP6GRE &&
210 t->dev->type != dev_type)
211 continue;
212
213 score = 0;
214 if (t->parms.link != link)
215 score |= 1;
216 if (t->dev->type != dev_type)
217 score |= 2;
218 if (score == 0)
219 return t;
220
221 if (score < cand_score) {
222 cand = t;
223 cand_score = score;
224 }
225 }
226
227 for_each_ip_tunnel_rcu(ign->tunnels_l[h1]) {
228 if ((!ipv6_addr_equal(local, &t->parms.laddr) &&
229 (!ipv6_addr_equal(local, &t->parms.raddr) ||
230 !ipv6_addr_is_multicast(local))) ||
231 key != t->parms.i_key ||
232 !(t->dev->flags & IFF_UP))
233 continue;
234
235 if (t->dev->type != ARPHRD_IP6GRE &&
236 t->dev->type != dev_type)
237 continue;
238
239 score = 0;
240 if (t->parms.link != link)
241 score |= 1;
242 if (t->dev->type != dev_type)
243 score |= 2;
244 if (score == 0)
245 return t;
246
247 if (score < cand_score) {
248 cand = t;
249 cand_score = score;
250 }
251 }
252
253 for_each_ip_tunnel_rcu(ign->tunnels_wc[h1]) {
254 if (t->parms.i_key != key ||
255 !(t->dev->flags & IFF_UP))
256 continue;
257
258 if (t->dev->type != ARPHRD_IP6GRE &&
259 t->dev->type != dev_type)
260 continue;
261
262 score = 0;
263 if (t->parms.link != link)
264 score |= 1;
265 if (t->dev->type != dev_type)
266 score |= 2;
267 if (score == 0)
268 return t;
269
270 if (score < cand_score) {
271 cand = t;
272 cand_score = score;
273 }
274 }
275
276 if (cand != NULL)
277 return cand;
278
279 dev = ign->fb_tunnel_dev;
280 if (dev->flags & IFF_UP)
281 return netdev_priv(dev);
282
283 return NULL;
284}
285
286static struct ip6_tnl __rcu **__ip6gre_bucket(struct ip6gre_net *ign,
287 const struct __ip6_tnl_parm *p)
288{
289 const struct in6_addr *remote = &p->raddr;
290 const struct in6_addr *local = &p->laddr;
291 unsigned int h = HASH_KEY(p->i_key);
292 int prio = 0;
293
294 if (!ipv6_addr_any(local))
295 prio |= 1;
296 if (!ipv6_addr_any(remote) && !ipv6_addr_is_multicast(remote)) {
297 prio |= 2;
298 h ^= HASH_ADDR(remote);
299 }
300
301 return &ign->tunnels[prio][h];
302}
303
304static inline struct ip6_tnl __rcu **ip6gre_bucket(struct ip6gre_net *ign,
305 const struct ip6_tnl *t)
306{
307 return __ip6gre_bucket(ign, &t->parms);
308}
309
310static void ip6gre_tunnel_link(struct ip6gre_net *ign, struct ip6_tnl *t)
311{
312 struct ip6_tnl __rcu **tp = ip6gre_bucket(ign, t);
313
314 rcu_assign_pointer(t->next, rtnl_dereference(*tp));
315 rcu_assign_pointer(*tp, t);
316}
317
318static void ip6gre_tunnel_unlink(struct ip6gre_net *ign, struct ip6_tnl *t)
319{
320 struct ip6_tnl __rcu **tp;
321 struct ip6_tnl *iter;
322
323 for (tp = ip6gre_bucket(ign, t);
324 (iter = rtnl_dereference(*tp)) != NULL;
325 tp = &iter->next) {
326 if (t == iter) {
327 rcu_assign_pointer(*tp, t->next);
328 break;
329 }
330 }
331}
332
333static struct ip6_tnl *ip6gre_tunnel_find(struct net *net,
334 const struct __ip6_tnl_parm *parms,
335 int type)
336{
337 const struct in6_addr *remote = &parms->raddr;
338 const struct in6_addr *local = &parms->laddr;
339 __be32 key = parms->i_key;
340 int link = parms->link;
341 struct ip6_tnl *t;
342 struct ip6_tnl __rcu **tp;
343 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
344
345 for (tp = __ip6gre_bucket(ign, parms);
346 (t = rtnl_dereference(*tp)) != NULL;
347 tp = &t->next)
348 if (ipv6_addr_equal(local, &t->parms.laddr) &&
349 ipv6_addr_equal(remote, &t->parms.raddr) &&
350 key == t->parms.i_key &&
351 link == t->parms.link &&
352 type == t->dev->type)
353 break;
354
355 return t;
356}
357
358static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
359 const struct __ip6_tnl_parm *parms, int create)
360{
361 struct ip6_tnl *t, *nt;
362 struct net_device *dev;
363 char name[IFNAMSIZ];
364 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
365
366 t = ip6gre_tunnel_find(net, parms, ARPHRD_IP6GRE);
367 if (t || !create)
368 return t;
369
370 if (parms->name[0])
371 strlcpy(name, parms->name, IFNAMSIZ);
372 else
373 strcpy(name, "ip6gre%d");
374
375 dev = alloc_netdev(sizeof(*t), name, ip6gre_tunnel_setup);
376 if (!dev)
377 return NULL;
378
379 dev_net_set(dev, net);
380
381 nt = netdev_priv(dev);
382 nt->parms = *parms;
383 dev->rtnl_link_ops = &ip6gre_link_ops;
384
385 nt->dev = dev;
386 ip6gre_tnl_link_config(nt, 1);
387
388 if (register_netdevice(dev) < 0)
389 goto failed_free;
390
391 /* Can use a lockless transmit, unless we generate output sequences */
392 if (!(nt->parms.o_flags & GRE_SEQ))
393 dev->features |= NETIF_F_LLTX;
394
395 dev_hold(dev);
396 ip6gre_tunnel_link(ign, nt);
397 return nt;
398
399failed_free:
400 free_netdev(dev);
401 return NULL;
402}
403
404static void ip6gre_tunnel_uninit(struct net_device *dev)
405{
406 struct net *net = dev_net(dev);
407 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
408
409 ip6gre_tunnel_unlink(ign, netdev_priv(dev));
410 dev_put(dev);
411}
412
413
414static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
415 u8 type, u8 code, int offset, __be32 info)
416{
417 const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
418 __be16 *p = (__be16 *)(skb->data + offset);
419 int grehlen = offset + 4;
420 struct ip6_tnl *t;
421 __be16 flags;
422
423 flags = p[0];
424 if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
425 if (flags&(GRE_VERSION|GRE_ROUTING))
426 return;
427 if (flags&GRE_KEY) {
428 grehlen += 4;
429 if (flags&GRE_CSUM)
430 grehlen += 4;
431 }
432 }
433
434 /* If only 8 bytes returned, keyed message will be dropped here */
435 if (!pskb_may_pull(skb, grehlen))
436 return;
437 ipv6h = (const struct ipv6hdr *)skb->data;
438 p = (__be16 *)(skb->data + offset);
439
440 rcu_read_lock();
441
442 t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
443 flags & GRE_KEY ?
444 *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
445 p[1]);
446 if (t == NULL)
447 goto out;
448
449 switch (type) {
450 __u32 teli;
451 struct ipv6_tlv_tnl_enc_lim *tel;
452 __u32 mtu;
453 case ICMPV6_DEST_UNREACH:
454 net_warn_ratelimited("%s: Path to destination invalid or inactive!\n",
455 t->parms.name);
456 break;
457 case ICMPV6_TIME_EXCEED:
458 if (code == ICMPV6_EXC_HOPLIMIT) {
459 net_warn_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
460 t->parms.name);
461 }
462 break;
463 case ICMPV6_PARAMPROB:
464 teli = 0;
465 if (code == ICMPV6_HDR_FIELD)
466 teli = ip6_tnl_parse_tlv_enc_lim(skb, skb->data);
467
468 if (teli && teli == info - 2) {
469 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
470 if (tel->encap_limit == 0) {
471 net_warn_ratelimited("%s: Too small encapsulation limit or routing loop in tunnel!\n",
472 t->parms.name);
473 }
474 } else {
475 net_warn_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
476 t->parms.name);
477 }
478 break;
479 case ICMPV6_PKT_TOOBIG:
480 mtu = info - offset;
481 if (mtu < IPV6_MIN_MTU)
482 mtu = IPV6_MIN_MTU;
483 t->dev->mtu = mtu;
484 break;
485 }
486
487 if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
488 t->err_count++;
489 else
490 t->err_count = 1;
491 t->err_time = jiffies;
492out:
493 rcu_read_unlock();
494}
495
496static inline void ip6gre_ecn_decapsulate_ipv4(const struct ip6_tnl *t,
497 const struct ipv6hdr *ipv6h, struct sk_buff *skb)
498{
499 __u8 dsfield = ipv6_get_dsfield(ipv6h) & ~INET_ECN_MASK;
500
501 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
502 ipv4_change_dsfield(ip_hdr(skb), INET_ECN_MASK, dsfield);
503
504 if (INET_ECN_is_ce(dsfield))
505 IP_ECN_set_ce(ip_hdr(skb));
506}
507
508static inline void ip6gre_ecn_decapsulate_ipv6(const struct ip6_tnl *t,
509 const struct ipv6hdr *ipv6h, struct sk_buff *skb)
510{
511 if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
512 ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb));
513
514 if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h)))
515 IP6_ECN_set_ce(ipv6_hdr(skb));
516}
517
518static int ip6gre_rcv(struct sk_buff *skb)
519{
520 const struct ipv6hdr *ipv6h;
521 u8 *h;
522 __be16 flags;
523 __sum16 csum = 0;
524 __be32 key = 0;
525 u32 seqno = 0;
526 struct ip6_tnl *tunnel;
527 int offset = 4;
528 __be16 gre_proto;
529
530 if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
531 goto drop_nolock;
532
533 ipv6h = ipv6_hdr(skb);
534 h = skb->data;
535 flags = *(__be16 *)h;
536
537 if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
538 /* - Version must be 0.
539 - We do not support routing headers.
540 */
541 if (flags&(GRE_VERSION|GRE_ROUTING))
542 goto drop_nolock;
543
544 if (flags&GRE_CSUM) {
545 switch (skb->ip_summed) {
546 case CHECKSUM_COMPLETE:
547 csum = csum_fold(skb->csum);
548 if (!csum)
549 break;
550 /* fall through */
551 case CHECKSUM_NONE:
552 skb->csum = 0;
553 csum = __skb_checksum_complete(skb);
554 skb->ip_summed = CHECKSUM_COMPLETE;
555 }
556 offset += 4;
557 }
558 if (flags&GRE_KEY) {
559 key = *(__be32 *)(h + offset);
560 offset += 4;
561 }
562 if (flags&GRE_SEQ) {
563 seqno = ntohl(*(__be32 *)(h + offset));
564 offset += 4;
565 }
566 }
567
568 gre_proto = *(__be16 *)(h + 2);
569
570 rcu_read_lock();
571 tunnel = ip6gre_tunnel_lookup(skb->dev,
572 &ipv6h->saddr, &ipv6h->daddr, key,
573 gre_proto);
574 if (tunnel) {
575 struct pcpu_tstats *tstats;
576
577 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
578 goto drop;
579
580 if (!ip6_tnl_rcv_ctl(tunnel, &ipv6h->daddr, &ipv6h->saddr)) {
581 tunnel->dev->stats.rx_dropped++;
582 goto drop;
583 }
584
585 secpath_reset(skb);
586
587 skb->protocol = gre_proto;
588 /* WCCP version 1 and 2 protocol decoding.
589 * - Change protocol to IP
590 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
591 */
592 if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) {
593 skb->protocol = htons(ETH_P_IP);
594 if ((*(h + offset) & 0xF0) != 0x40)
595 offset += 4;
596 }
597
598 skb->mac_header = skb->network_header;
599 __pskb_pull(skb, offset);
600 skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
601 skb->pkt_type = PACKET_HOST;
602
603 if (((flags&GRE_CSUM) && csum) ||
604 (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
605 tunnel->dev->stats.rx_crc_errors++;
606 tunnel->dev->stats.rx_errors++;
607 goto drop;
608 }
609 if (tunnel->parms.i_flags&GRE_SEQ) {
610 if (!(flags&GRE_SEQ) ||
611 (tunnel->i_seqno &&
612 (s32)(seqno - tunnel->i_seqno) < 0)) {
613 tunnel->dev->stats.rx_fifo_errors++;
614 tunnel->dev->stats.rx_errors++;
615 goto drop;
616 }
617 tunnel->i_seqno = seqno + 1;
618 }
619
620 /* Warning: All skb pointers will be invalidated! */
621 if (tunnel->dev->type == ARPHRD_ETHER) {
622 if (!pskb_may_pull(skb, ETH_HLEN)) {
623 tunnel->dev->stats.rx_length_errors++;
624 tunnel->dev->stats.rx_errors++;
625 goto drop;
626 }
627
628 ipv6h = ipv6_hdr(skb);
629 skb->protocol = eth_type_trans(skb, tunnel->dev);
630 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
631 }
632
633 tstats = this_cpu_ptr(tunnel->dev->tstats);
634 u64_stats_update_begin(&tstats->syncp);
635 tstats->rx_packets++;
636 tstats->rx_bytes += skb->len;
637 u64_stats_update_end(&tstats->syncp);
638
639 __skb_tunnel_rx(skb, tunnel->dev);
640
641 skb_reset_network_header(skb);
642 if (skb->protocol == htons(ETH_P_IP))
643 ip6gre_ecn_decapsulate_ipv4(tunnel, ipv6h, skb);
644 else if (skb->protocol == htons(ETH_P_IPV6))
645 ip6gre_ecn_decapsulate_ipv6(tunnel, ipv6h, skb);
646
647 netif_rx(skb);
648
649 rcu_read_unlock();
650 return 0;
651 }
652 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
653
654drop:
655 rcu_read_unlock();
656drop_nolock:
657 kfree_skb(skb);
658 return 0;
659}
660
661struct ipv6_tel_txoption {
662 struct ipv6_txoptions ops;
663 __u8 dst_opt[8];
664};
665
666static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
667{
668 memset(opt, 0, sizeof(struct ipv6_tel_txoption));
669
670 opt->dst_opt[2] = IPV6_TLV_TNL_ENCAP_LIMIT;
671 opt->dst_opt[3] = 1;
672 opt->dst_opt[4] = encap_limit;
673 opt->dst_opt[5] = IPV6_TLV_PADN;
674 opt->dst_opt[6] = 1;
675
676 opt->ops.dst0opt = (struct ipv6_opt_hdr *) opt->dst_opt;
677 opt->ops.opt_nflen = 8;
678}
679
680static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
681 struct net_device *dev,
682 __u8 dsfield,
683 struct flowi6 *fl6,
684 int encap_limit,
685 __u32 *pmtu)
686{
687 struct net *net = dev_net(dev);
688 struct ip6_tnl *tunnel = netdev_priv(dev);
689 struct net_device *tdev; /* Device to other host */
690 struct ipv6hdr *ipv6h; /* Our new IP header */
691 unsigned int max_headroom; /* The extra header space needed */
692 int gre_hlen;
693 struct ipv6_tel_txoption opt;
694 int mtu;
695 struct dst_entry *dst = NULL, *ndst = NULL;
696 struct net_device_stats *stats = &tunnel->dev->stats;
697 int err = -1;
698 u8 proto;
699 int pkt_len;
700 struct sk_buff *new_skb;
701
702 if (dev->type == ARPHRD_ETHER)
703 IPCB(skb)->flags = 0;
704
705 if (dev->header_ops && dev->type == ARPHRD_IP6GRE) {
706 gre_hlen = 0;
707 ipv6h = (struct ipv6hdr *)skb->data;
708 fl6->daddr = ipv6h->daddr;
709 } else {
710 gre_hlen = tunnel->hlen;
711 fl6->daddr = tunnel->parms.raddr;
712 }
713
714 if (!fl6->flowi6_mark)
715 dst = ip6_tnl_dst_check(tunnel);
716
717 if (!dst) {
718 ndst = ip6_route_output(net, NULL, fl6);
719
720 if (ndst->error)
721 goto tx_err_link_failure;
722 ndst = xfrm_lookup(net, ndst, flowi6_to_flowi(fl6), NULL, 0);
723 if (IS_ERR(ndst)) {
724 err = PTR_ERR(ndst);
725 ndst = NULL;
726 goto tx_err_link_failure;
727 }
728 dst = ndst;
729 }
730
731 tdev = dst->dev;
732
733 if (tdev == dev) {
734 stats->collisions++;
735 net_warn_ratelimited("%s: Local routing loop detected!\n",
736 tunnel->parms.name);
737 goto tx_err_dst_release;
738 }
739
740 mtu = dst_mtu(dst) - sizeof(*ipv6h);
741 if (encap_limit >= 0) {
742 max_headroom += 8;
743 mtu -= 8;
744 }
745 if (mtu < IPV6_MIN_MTU)
746 mtu = IPV6_MIN_MTU;
747 if (skb_dst(skb))
748 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
749 if (skb->len > mtu) {
750 *pmtu = mtu;
751 err = -EMSGSIZE;
752 goto tx_err_dst_release;
753 }
754
755 if (tunnel->err_count > 0) {
756 if (time_before(jiffies,
757 tunnel->err_time + IP6TUNNEL_ERR_TIMEO)) {
758 tunnel->err_count--;
759
760 dst_link_failure(skb);
761 } else
762 tunnel->err_count = 0;
763 }
764
765 max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len;
766
767 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
768 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
769 new_skb = skb_realloc_headroom(skb, max_headroom);
770 if (max_headroom > dev->needed_headroom)
771 dev->needed_headroom = max_headroom;
772 if (!new_skb)
773 goto tx_err_dst_release;
774
775 if (skb->sk)
776 skb_set_owner_w(new_skb, skb->sk);
777 consume_skb(skb);
778 skb = new_skb;
779 }
780
781 skb_dst_drop(skb);
782
783 if (fl6->flowi6_mark) {
784 skb_dst_set(skb, dst);
785 ndst = NULL;
786 } else {
787 skb_dst_set_noref(skb, dst);
788 }
789
790 skb->transport_header = skb->network_header;
791
792 proto = NEXTHDR_GRE;
793 if (encap_limit >= 0) {
794 init_tel_txopt(&opt, encap_limit);
795 ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
796 }
797
798 skb_push(skb, gre_hlen);
799 skb_reset_network_header(skb);
800
801 /*
802 * Push down and install the IP header.
803 */
804 ipv6h = ipv6_hdr(skb);
805 *(__be32 *)ipv6h = fl6->flowlabel | htonl(0x60000000);
806 dsfield = INET_ECN_encapsulate(0, dsfield);
807 ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
808 ipv6h->hop_limit = tunnel->parms.hop_limit;
809 ipv6h->nexthdr = proto;
810 ipv6h->saddr = fl6->saddr;
811 ipv6h->daddr = fl6->daddr;
812
813 ((__be16 *)(ipv6h + 1))[0] = tunnel->parms.o_flags;
814 ((__be16 *)(ipv6h + 1))[1] = (dev->type == ARPHRD_ETHER) ?
815 htons(ETH_P_TEB) : skb->protocol;
816
817 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
818 __be32 *ptr = (__be32 *)(((u8 *)ipv6h) + tunnel->hlen - 4);
819
820 if (tunnel->parms.o_flags&GRE_SEQ) {
821 ++tunnel->o_seqno;
822 *ptr = htonl(tunnel->o_seqno);
823 ptr--;
824 }
825 if (tunnel->parms.o_flags&GRE_KEY) {
826 *ptr = tunnel->parms.o_key;
827 ptr--;
828 }
829 if (tunnel->parms.o_flags&GRE_CSUM) {
830 *ptr = 0;
831 *(__sum16 *)ptr = ip_compute_csum((void *)(ipv6h+1),
832 skb->len - sizeof(struct ipv6hdr));
833 }
834 }
835
836 nf_reset(skb);
837 pkt_len = skb->len;
838 err = ip6_local_out(skb);
839
840 if (net_xmit_eval(err) == 0) {
841 struct pcpu_tstats *tstats = this_cpu_ptr(tunnel->dev->tstats);
842
843 tstats->tx_bytes += pkt_len;
844 tstats->tx_packets++;
845 } else {
846 stats->tx_errors++;
847 stats->tx_aborted_errors++;
848 }
849
850 if (ndst)
851 ip6_tnl_dst_store(tunnel, ndst);
852
853 return 0;
854tx_err_link_failure:
855 stats->tx_carrier_errors++;
856 dst_link_failure(skb);
857tx_err_dst_release:
858 dst_release(ndst);
859 return err;
860}
861
862static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
863{
864 struct ip6_tnl *t = netdev_priv(dev);
865 const struct iphdr *iph = ip_hdr(skb);
866 int encap_limit = -1;
867 struct flowi6 fl6;
868 __u8 dsfield;
869 __u32 mtu;
870 int err;
871
872 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
873 encap_limit = t->parms.encap_limit;
874
875 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
876 fl6.flowi6_proto = IPPROTO_IPIP;
877
878 dsfield = ipv4_get_dsfield(iph);
879
880 if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
881 fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
882 & IPV6_TCLASS_MASK;
883 if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
884 fl6.flowi6_mark = skb->mark;
885
886 err = ip6gre_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
887 if (err != 0) {
888 /* XXX: send ICMP error even if DF is not set. */
889 if (err == -EMSGSIZE)
890 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
891 htonl(mtu));
892 return -1;
893 }
894
895 return 0;
896}
897
898static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
899{
900 struct ip6_tnl *t = netdev_priv(dev);
901 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
902 int encap_limit = -1;
903 __u16 offset;
904 struct flowi6 fl6;
905 __u8 dsfield;
906 __u32 mtu;
907 int err;
908
909 if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr))
910 return -1;
911
912 offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
913 if (offset > 0) {
914 struct ipv6_tlv_tnl_enc_lim *tel;
915 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
916 if (tel->encap_limit == 0) {
917 icmpv6_send(skb, ICMPV6_PARAMPROB,
918 ICMPV6_HDR_FIELD, offset + 2);
919 return -1;
920 }
921 encap_limit = tel->encap_limit - 1;
922 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
923 encap_limit = t->parms.encap_limit;
924
925 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
926 fl6.flowi6_proto = IPPROTO_IPV6;
927
928 dsfield = ipv6_get_dsfield(ipv6h);
929 if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
930 fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
931 if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
932 fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
933 if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
934 fl6.flowi6_mark = skb->mark;
935
936 err = ip6gre_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
937 if (err != 0) {
938 if (err == -EMSGSIZE)
939 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
940 return -1;
941 }
942
943 return 0;
944}
945
946/**
947 * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
948 * @t: the outgoing tunnel device
949 * @hdr: IPv6 header from the incoming packet
950 *
951 * Description:
952 * Avoid trivial tunneling loop by checking that tunnel exit-point
953 * doesn't match source of incoming packet.
954 *
955 * Return:
956 * 1 if conflict,
957 * 0 else
958 **/
959
960static inline bool ip6gre_tnl_addr_conflict(const struct ip6_tnl *t,
961 const struct ipv6hdr *hdr)
962{
963 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
964}
965
966static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev)
967{
968 struct ip6_tnl *t = netdev_priv(dev);
969 int encap_limit = -1;
970 struct flowi6 fl6;
971 __u32 mtu;
972 int err;
973
974 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
975 encap_limit = t->parms.encap_limit;
976
977 memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
978 fl6.flowi6_proto = skb->protocol;
979
980 err = ip6gre_xmit2(skb, dev, 0, &fl6, encap_limit, &mtu);
981
982 return err;
983}
984
985static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
986 struct net_device *dev)
987{
988 struct ip6_tnl *t = netdev_priv(dev);
989 struct net_device_stats *stats = &t->dev->stats;
990 int ret;
991
992 if (!ip6_tnl_xmit_ctl(t))
993 return -1;
994
995 switch (skb->protocol) {
996 case htons(ETH_P_IP):
997 ret = ip6gre_xmit_ipv4(skb, dev);
998 break;
999 case htons(ETH_P_IPV6):
1000 ret = ip6gre_xmit_ipv6(skb, dev);
1001 break;
1002 default:
1003 ret = ip6gre_xmit_other(skb, dev);
1004 break;
1005 }
1006
1007 if (ret < 0)
1008 goto tx_err;
1009
1010 return NETDEV_TX_OK;
1011
1012tx_err:
1013 stats->tx_errors++;
1014 stats->tx_dropped++;
1015 kfree_skb(skb);
1016 return NETDEV_TX_OK;
1017}
1018
1019static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
1020{
1021 struct net_device *dev = t->dev;
1022 struct __ip6_tnl_parm *p = &t->parms;
1023 struct flowi6 *fl6 = &t->fl.u.ip6;
1024 int addend = sizeof(struct ipv6hdr) + 4;
1025
1026 if (dev->type != ARPHRD_ETHER) {
1027 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
1028 memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
1029 }
1030
1031 /* Set up flowi template */
1032 fl6->saddr = p->laddr;
1033 fl6->daddr = p->raddr;
1034 fl6->flowi6_oif = p->link;
1035 fl6->flowlabel = 0;
1036
1037 if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
1038 fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
1039 if (!(p->flags&IP6_TNL_F_USE_ORIG_FLOWLABEL))
1040 fl6->flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo;
1041
1042 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV|IP6_TNL_F_CAP_PER_PACKET);
1043 p->flags |= ip6_tnl_get_cap(t, &p->laddr, &p->raddr);
1044
1045 if (p->flags&IP6_TNL_F_CAP_XMIT &&
1046 p->flags&IP6_TNL_F_CAP_RCV && dev->type != ARPHRD_ETHER)
1047 dev->flags |= IFF_POINTOPOINT;
1048 else
1049 dev->flags &= ~IFF_POINTOPOINT;
1050
1051 dev->iflink = p->link;
1052
1053 /* Precalculate GRE options length */
1054 if (t->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
1055 if (t->parms.o_flags&GRE_CSUM)
1056 addend += 4;
1057 if (t->parms.o_flags&GRE_KEY)
1058 addend += 4;
1059 if (t->parms.o_flags&GRE_SEQ)
1060 addend += 4;
1061 }
1062
1063 if (p->flags & IP6_TNL_F_CAP_XMIT) {
1064 int strict = (ipv6_addr_type(&p->raddr) &
1065 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
1066
1067 struct rt6_info *rt = rt6_lookup(dev_net(dev),
1068 &p->raddr, &p->laddr,
1069 p->link, strict);
1070
1071 if (rt == NULL)
1072 return;
1073
1074 if (rt->dst.dev) {
1075 dev->hard_header_len = rt->dst.dev->hard_header_len + addend;
1076
1077 if (set_mtu) {
1078 dev->mtu = rt->dst.dev->mtu - addend;
1079 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1080 dev->mtu -= 8;
1081
1082 if (dev->mtu < IPV6_MIN_MTU)
1083 dev->mtu = IPV6_MIN_MTU;
1084 }
1085 }
1086 dst_release(&rt->dst);
1087 }
1088
1089 t->hlen = addend;
1090}
1091
1092static int ip6gre_tnl_change(struct ip6_tnl *t,
1093 const struct __ip6_tnl_parm *p, int set_mtu)
1094{
1095 t->parms.laddr = p->laddr;
1096 t->parms.raddr = p->raddr;
1097 t->parms.flags = p->flags;
1098 t->parms.hop_limit = p->hop_limit;
1099 t->parms.encap_limit = p->encap_limit;
1100 t->parms.flowinfo = p->flowinfo;
1101 t->parms.link = p->link;
1102 t->parms.proto = p->proto;
1103 t->parms.i_key = p->i_key;
1104 t->parms.o_key = p->o_key;
1105 t->parms.i_flags = p->i_flags;
1106 t->parms.o_flags = p->o_flags;
1107 ip6_tnl_dst_reset(t);
1108 ip6gre_tnl_link_config(t, set_mtu);
1109 return 0;
1110}
1111
1112static void ip6gre_tnl_parm_from_user(struct __ip6_tnl_parm *p,
1113 const struct ip6_tnl_parm2 *u)
1114{
1115 p->laddr = u->laddr;
1116 p->raddr = u->raddr;
1117 p->flags = u->flags;
1118 p->hop_limit = u->hop_limit;
1119 p->encap_limit = u->encap_limit;
1120 p->flowinfo = u->flowinfo;
1121 p->link = u->link;
1122 p->i_key = u->i_key;
1123 p->o_key = u->o_key;
1124 p->i_flags = u->i_flags;
1125 p->o_flags = u->o_flags;
1126 memcpy(p->name, u->name, sizeof(u->name));
1127}
1128
1129static void ip6gre_tnl_parm_to_user(struct ip6_tnl_parm2 *u,
1130 const struct __ip6_tnl_parm *p)
1131{
1132 u->proto = IPPROTO_GRE;
1133 u->laddr = p->laddr;
1134 u->raddr = p->raddr;
1135 u->flags = p->flags;
1136 u->hop_limit = p->hop_limit;
1137 u->encap_limit = p->encap_limit;
1138 u->flowinfo = p->flowinfo;
1139 u->link = p->link;
1140 u->i_key = p->i_key;
1141 u->o_key = p->o_key;
1142 u->i_flags = p->i_flags;
1143 u->o_flags = p->o_flags;
1144 memcpy(u->name, p->name, sizeof(u->name));
1145}
1146
1147static int ip6gre_tunnel_ioctl(struct net_device *dev,
1148 struct ifreq *ifr, int cmd)
1149{
1150 int err = 0;
1151 struct ip6_tnl_parm2 p;
1152 struct __ip6_tnl_parm p1;
1153 struct ip6_tnl *t;
1154 struct net *net = dev_net(dev);
1155 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
1156
1157 switch (cmd) {
1158 case SIOCGETTUNNEL:
1159 t = NULL;
1160 if (dev == ign->fb_tunnel_dev) {
1161 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
1162 err = -EFAULT;
1163 break;
1164 }
1165 ip6gre_tnl_parm_from_user(&p1, &p);
1166 t = ip6gre_tunnel_locate(net, &p1, 0);
1167 }
1168 if (t == NULL)
1169 t = netdev_priv(dev);
1170 ip6gre_tnl_parm_to_user(&p, &t->parms);
1171 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
1172 err = -EFAULT;
1173 break;
1174
1175 case SIOCADDTUNNEL:
1176 case SIOCCHGTUNNEL:
1177 err = -EPERM;
1178 if (!capable(CAP_NET_ADMIN))
1179 goto done;
1180
1181 err = -EFAULT;
1182 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1183 goto done;
1184
1185 err = -EINVAL;
1186 if ((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING))
1187 goto done;
1188
1189 if (!(p.i_flags&GRE_KEY))
1190 p.i_key = 0;
1191 if (!(p.o_flags&GRE_KEY))
1192 p.o_key = 0;
1193
1194 ip6gre_tnl_parm_from_user(&p1, &p);
1195 t = ip6gre_tunnel_locate(net, &p1, cmd == SIOCADDTUNNEL);
1196
1197 if (dev != ign->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
1198 if (t != NULL) {
1199 if (t->dev != dev) {
1200 err = -EEXIST;
1201 break;
1202 }
1203 } else {
1204 t = netdev_priv(dev);
1205
1206 ip6gre_tunnel_unlink(ign, t);
1207 synchronize_net();
1208 ip6gre_tnl_change(t, &p1, 1);
1209 ip6gre_tunnel_link(ign, t);
1210 netdev_state_change(dev);
1211 }
1212 }
1213
1214 if (t) {
1215 err = 0;
1216
1217 ip6gre_tnl_parm_to_user(&p, &t->parms);
1218 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
1219 err = -EFAULT;
1220 } else
1221 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
1222 break;
1223
1224 case SIOCDELTUNNEL:
1225 err = -EPERM;
1226 if (!capable(CAP_NET_ADMIN))
1227 goto done;
1228
1229 if (dev == ign->fb_tunnel_dev) {
1230 err = -EFAULT;
1231 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
1232 goto done;
1233 err = -ENOENT;
1234 ip6gre_tnl_parm_from_user(&p1, &p);
1235 t = ip6gre_tunnel_locate(net, &p1, 0);
1236 if (t == NULL)
1237 goto done;
1238 err = -EPERM;
1239 if (t == netdev_priv(ign->fb_tunnel_dev))
1240 goto done;
1241 dev = t->dev;
1242 }
1243 unregister_netdevice(dev);
1244 err = 0;
1245 break;
1246
1247 default:
1248 err = -EINVAL;
1249 }
1250
1251done:
1252 return err;
1253}
1254
1255static int ip6gre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
1256{
1257 struct ip6_tnl *tunnel = netdev_priv(dev);
1258 if (new_mtu < 68 ||
1259 new_mtu > 0xFFF8 - dev->hard_header_len - tunnel->hlen)
1260 return -EINVAL;
1261 dev->mtu = new_mtu;
1262 return 0;
1263}
1264
1265static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
1266 unsigned short type,
1267 const void *daddr, const void *saddr, unsigned int len)
1268{
1269 struct ip6_tnl *t = netdev_priv(dev);
1270 struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
1271 __be16 *p = (__be16 *)(ipv6h+1);
1272
1273 *(__be32 *)ipv6h = t->fl.u.ip6.flowlabel | htonl(0x60000000);
1274 ipv6h->hop_limit = t->parms.hop_limit;
1275 ipv6h->nexthdr = NEXTHDR_GRE;
1276 ipv6h->saddr = t->parms.laddr;
1277 ipv6h->daddr = t->parms.raddr;
1278
1279 p[0] = t->parms.o_flags;
1280 p[1] = htons(type);
1281
1282 /*
1283 * Set the source hardware address.
1284 */
1285
1286 if (saddr)
1287 memcpy(&ipv6h->saddr, saddr, sizeof(struct in6_addr));
1288 if (daddr)
1289 memcpy(&ipv6h->daddr, daddr, sizeof(struct in6_addr));
1290 if (!ipv6_addr_any(&ipv6h->daddr))
1291 return t->hlen;
1292
1293 return -t->hlen;
1294}
1295
1296static int ip6gre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
1297{
1298 const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb_mac_header(skb);
1299 memcpy(haddr, &ipv6h->saddr, sizeof(struct in6_addr));
1300 return sizeof(struct in6_addr);
1301}
1302
1303static const struct header_ops ip6gre_header_ops = {
1304 .create = ip6gre_header,
1305 .parse = ip6gre_header_parse,
1306};
1307
1308static const struct net_device_ops ip6gre_netdev_ops = {
1309 .ndo_init = ip6gre_tunnel_init,
1310 .ndo_uninit = ip6gre_tunnel_uninit,
1311 .ndo_start_xmit = ip6gre_tunnel_xmit,
1312 .ndo_do_ioctl = ip6gre_tunnel_ioctl,
1313 .ndo_change_mtu = ip6gre_tunnel_change_mtu,
1314 .ndo_get_stats64 = ip6gre_get_stats64,
1315};
1316
1317static void ip6gre_dev_free(struct net_device *dev)
1318{
1319 free_percpu(dev->tstats);
1320 free_netdev(dev);
1321}
1322
1323static void ip6gre_tunnel_setup(struct net_device *dev)
1324{
1325 struct ip6_tnl *t;
1326
1327 dev->netdev_ops = &ip6gre_netdev_ops;
1328 dev->destructor = ip6gre_dev_free;
1329
1330 dev->type = ARPHRD_IP6GRE;
1331 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr) + 4;
1332 dev->mtu = ETH_DATA_LEN - sizeof(struct ipv6hdr) - 4;
1333 t = netdev_priv(dev);
1334 if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1335 dev->mtu -= 8;
1336 dev->flags |= IFF_NOARP;
1337 dev->iflink = 0;
1338 dev->addr_len = sizeof(struct in6_addr);
1339 dev->features |= NETIF_F_NETNS_LOCAL;
1340 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
1341}
1342
1343static int ip6gre_tunnel_init(struct net_device *dev)
1344{
1345 struct ip6_tnl *tunnel;
1346
1347 tunnel = netdev_priv(dev);
1348
1349 tunnel->dev = dev;
1350 strcpy(tunnel->parms.name, dev->name);
1351
1352 memcpy(dev->dev_addr, &tunnel->parms.laddr, sizeof(struct in6_addr));
1353 memcpy(dev->broadcast, &tunnel->parms.raddr, sizeof(struct in6_addr));
1354
1355 if (ipv6_addr_any(&tunnel->parms.raddr))
1356 dev->header_ops = &ip6gre_header_ops;
1357
1358 dev->tstats = alloc_percpu(struct pcpu_tstats);
1359 if (!dev->tstats)
1360 return -ENOMEM;
1361
1362 return 0;
1363}
1364
1365static void ip6gre_fb_tunnel_init(struct net_device *dev)
1366{
1367 struct ip6_tnl *tunnel = netdev_priv(dev);
1368
1369 tunnel->dev = dev;
1370 strcpy(tunnel->parms.name, dev->name);
1371
1372 tunnel->hlen = sizeof(struct ipv6hdr) + 4;
1373
1374 dev_hold(dev);
1375}
1376
1377
1378static struct inet6_protocol ip6gre_protocol __read_mostly = {
1379 .handler = ip6gre_rcv,
1380 .err_handler = ip6gre_err,
1381 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1382};
1383
1384static void ip6gre_destroy_tunnels(struct ip6gre_net *ign,
1385 struct list_head *head)
1386{
1387 int prio;
1388
1389 for (prio = 0; prio < 4; prio++) {
1390 int h;
1391 for (h = 0; h < HASH_SIZE; h++) {
1392 struct ip6_tnl *t;
1393
1394 t = rtnl_dereference(ign->tunnels[prio][h]);
1395
1396 while (t != NULL) {
1397 unregister_netdevice_queue(t->dev, head);
1398 t = rtnl_dereference(t->next);
1399 }
1400 }
1401 }
1402}
1403
1404static int __net_init ip6gre_init_net(struct net *net)
1405{
1406 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
1407 int err;
1408
1409 ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
1410 ip6gre_tunnel_setup);
1411 if (!ign->fb_tunnel_dev) {
1412 err = -ENOMEM;
1413 goto err_alloc_dev;
1414 }
1415 dev_net_set(ign->fb_tunnel_dev, net);
1416
1417 ip6gre_fb_tunnel_init(ign->fb_tunnel_dev);
1418 ign->fb_tunnel_dev->rtnl_link_ops = &ip6gre_link_ops;
1419
1420 err = register_netdev(ign->fb_tunnel_dev);
1421 if (err)
1422 goto err_reg_dev;
1423
1424 rcu_assign_pointer(ign->tunnels_wc[0],
1425 netdev_priv(ign->fb_tunnel_dev));
1426 return 0;
1427
1428err_reg_dev:
1429 ip6gre_dev_free(ign->fb_tunnel_dev);
1430err_alloc_dev:
1431 return err;
1432}
1433
1434static void __net_exit ip6gre_exit_net(struct net *net)
1435{
1436 struct ip6gre_net *ign;
1437 LIST_HEAD(list);
1438
1439 ign = net_generic(net, ip6gre_net_id);
1440 rtnl_lock();
1441 ip6gre_destroy_tunnels(ign, &list);
1442 unregister_netdevice_many(&list);
1443 rtnl_unlock();
1444}
1445
1446static struct pernet_operations ip6gre_net_ops = {
1447 .init = ip6gre_init_net,
1448 .exit = ip6gre_exit_net,
1449 .id = &ip6gre_net_id,
1450 .size = sizeof(struct ip6gre_net),
1451};
1452
1453static int ip6gre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
1454{
1455 __be16 flags;
1456
1457 if (!data)
1458 return 0;
1459
1460 flags = 0;
1461 if (data[IFLA_GRE_IFLAGS])
1462 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
1463 if (data[IFLA_GRE_OFLAGS])
1464 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
1465 if (flags & (GRE_VERSION|GRE_ROUTING))
1466 return -EINVAL;
1467
1468 return 0;
1469}
1470
1471static int ip6gre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
1472{
1473 struct in6_addr daddr;
1474
1475 if (tb[IFLA_ADDRESS]) {
1476 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
1477 return -EINVAL;
1478 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
1479 return -EADDRNOTAVAIL;
1480 }
1481
1482 if (!data)
1483 goto out;
1484
1485 if (data[IFLA_GRE_REMOTE]) {
1486 nla_memcpy(&daddr, data[IFLA_GRE_REMOTE], sizeof(struct in6_addr));
1487 if (ipv6_addr_any(&daddr))
1488 return -EINVAL;
1489 }
1490
1491out:
1492 return ip6gre_tunnel_validate(tb, data);
1493}
1494
1495
1496static void ip6gre_netlink_parms(struct nlattr *data[],
1497 struct __ip6_tnl_parm *parms)
1498{
1499 memset(parms, 0, sizeof(*parms));
1500
1501 if (!data)
1502 return;
1503
1504 if (data[IFLA_GRE_LINK])
1505 parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
1506
1507 if (data[IFLA_GRE_IFLAGS])
1508 parms->i_flags = nla_get_be16(data[IFLA_GRE_IFLAGS]);
1509
1510 if (data[IFLA_GRE_OFLAGS])
1511 parms->o_flags = nla_get_be16(data[IFLA_GRE_OFLAGS]);
1512
1513 if (data[IFLA_GRE_IKEY])
1514 parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
1515
1516 if (data[IFLA_GRE_OKEY])
1517 parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
1518
1519 if (data[IFLA_GRE_LOCAL])
1520 nla_memcpy(&parms->laddr, data[IFLA_GRE_LOCAL], sizeof(struct in6_addr));
1521
1522 if (data[IFLA_GRE_REMOTE])
1523 nla_memcpy(&parms->raddr, data[IFLA_GRE_REMOTE], sizeof(struct in6_addr));
1524
1525 if (data[IFLA_GRE_TTL])
1526 parms->hop_limit = nla_get_u8(data[IFLA_GRE_TTL]);
1527
1528 if (data[IFLA_GRE_ENCAP_LIMIT])
1529 parms->encap_limit = nla_get_u8(data[IFLA_GRE_ENCAP_LIMIT]);
1530
1531 if (data[IFLA_GRE_FLOWINFO])
1532 parms->flowinfo = nla_get_u32(data[IFLA_GRE_FLOWINFO]);
1533
1534 if (data[IFLA_GRE_FLAGS])
1535 parms->flags = nla_get_u32(data[IFLA_GRE_FLAGS]);
1536}
1537
1538static int ip6gre_tap_init(struct net_device *dev)
1539{
1540 struct ip6_tnl *tunnel;
1541
1542 tunnel = netdev_priv(dev);
1543
1544 tunnel->dev = dev;
1545 strcpy(tunnel->parms.name, dev->name);
1546
1547 ip6gre_tnl_link_config(tunnel, 1);
1548
1549 dev->tstats = alloc_percpu(struct pcpu_tstats);
1550 if (!dev->tstats)
1551 return -ENOMEM;
1552
1553 return 0;
1554}
1555
1556static const struct net_device_ops ip6gre_tap_netdev_ops = {
1557 .ndo_init = ip6gre_tap_init,
1558 .ndo_uninit = ip6gre_tunnel_uninit,
1559 .ndo_start_xmit = ip6gre_tunnel_xmit,
1560 .ndo_set_mac_address = eth_mac_addr,
1561 .ndo_validate_addr = eth_validate_addr,
1562 .ndo_change_mtu = ip6gre_tunnel_change_mtu,
1563 .ndo_get_stats64 = ip6gre_get_stats64,
1564};
1565
1566static void ip6gre_tap_setup(struct net_device *dev)
1567{
1568
1569 ether_setup(dev);
1570
1571 dev->netdev_ops = &ip6gre_tap_netdev_ops;
1572 dev->destructor = ip6gre_dev_free;
1573
1574 dev->iflink = 0;
1575 dev->features |= NETIF_F_NETNS_LOCAL;
1576}
1577
1578static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
1579 struct nlattr *tb[], struct nlattr *data[])
1580{
1581 struct ip6_tnl *nt;
1582 struct net *net = dev_net(dev);
1583 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
1584 int err;
1585
1586 nt = netdev_priv(dev);
1587 ip6gre_netlink_parms(data, &nt->parms);
1588
1589 if (ip6gre_tunnel_find(net, &nt->parms, dev->type))
1590 return -EEXIST;
1591
1592 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1593 eth_hw_addr_random(dev);
1594
1595 nt->dev = dev;
1596 ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
1597
1598 /* Can use a lockless transmit, unless we generate output sequences */
1599 if (!(nt->parms.o_flags & GRE_SEQ))
1600 dev->features |= NETIF_F_LLTX;
1601
1602 err = register_netdevice(dev);
1603 if (err)
1604 goto out;
1605
1606 dev_hold(dev);
1607 ip6gre_tunnel_link(ign, nt);
1608
1609out:
1610 return err;
1611}
1612
1613static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
1614 struct nlattr *data[])
1615{
1616 struct ip6_tnl *t, *nt;
1617 struct net *net = dev_net(dev);
1618 struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
1619 struct __ip6_tnl_parm p;
1620
1621 if (dev == ign->fb_tunnel_dev)
1622 return -EINVAL;
1623
1624 nt = netdev_priv(dev);
1625 ip6gre_netlink_parms(data, &p);
1626
1627 t = ip6gre_tunnel_locate(net, &p, 0);
1628
1629 if (t) {
1630 if (t->dev != dev)
1631 return -EEXIST;
1632 } else {
1633 t = nt;
1634
1635 ip6gre_tunnel_unlink(ign, t);
1636 ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
1637 ip6gre_tunnel_link(ign, t);
1638 netdev_state_change(dev);
1639 }
1640
1641 return 0;
1642}
1643
1644static size_t ip6gre_get_size(const struct net_device *dev)
1645{
1646 return
1647 /* IFLA_GRE_LINK */
1648 nla_total_size(4) +
1649 /* IFLA_GRE_IFLAGS */
1650 nla_total_size(2) +
1651 /* IFLA_GRE_OFLAGS */
1652 nla_total_size(2) +
1653 /* IFLA_GRE_IKEY */
1654 nla_total_size(4) +
1655 /* IFLA_GRE_OKEY */
1656 nla_total_size(4) +
1657 /* IFLA_GRE_LOCAL */
1658 nla_total_size(4) +
1659 /* IFLA_GRE_REMOTE */
1660 nla_total_size(4) +
1661 /* IFLA_GRE_TTL */
1662 nla_total_size(1) +
1663 /* IFLA_GRE_TOS */
1664 nla_total_size(1) +
1665 /* IFLA_GRE_ENCAP_LIMIT */
1666 nla_total_size(1) +
1667 /* IFLA_GRE_FLOWINFO */
1668 nla_total_size(4) +
1669 /* IFLA_GRE_FLAGS */
1670 nla_total_size(4) +
1671 0;
1672}
1673
1674static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1675{
1676 struct ip6_tnl *t = netdev_priv(dev);
1677 struct __ip6_tnl_parm *p = &t->parms;
1678
1679 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
1680 nla_put_be16(skb, IFLA_GRE_IFLAGS, p->i_flags) ||
1681 nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) ||
1682 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
1683 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
1684 nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) ||
1685 nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) ||
1686 nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) ||
1687 /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/
1688 nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) ||
1689 nla_put_be32(skb, IFLA_GRE_FLOWINFO, p->flowinfo) ||
1690 nla_put_u32(skb, IFLA_GRE_FLAGS, p->flags))
1691 goto nla_put_failure;
1692 return 0;
1693
1694nla_put_failure:
1695 return -EMSGSIZE;
1696}
1697
1698static const struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = {
1699 [IFLA_GRE_LINK] = { .type = NLA_U32 },
1700 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
1701 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
1702 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
1703 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
1704 [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct ipv6hdr, saddr) },
1705 [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct ipv6hdr, daddr) },
1706 [IFLA_GRE_TTL] = { .type = NLA_U8 },
1707 [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
1708 [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 },
1709 [IFLA_GRE_FLAGS] = { .type = NLA_U32 },
1710};
1711
1712static struct rtnl_link_ops ip6gre_link_ops __read_mostly = {
1713 .kind = "ip6gre",
1714 .maxtype = IFLA_GRE_MAX,
1715 .policy = ip6gre_policy,
1716 .priv_size = sizeof(struct ip6_tnl),
1717 .setup = ip6gre_tunnel_setup,
1718 .validate = ip6gre_tunnel_validate,
1719 .newlink = ip6gre_newlink,
1720 .changelink = ip6gre_changelink,
1721 .get_size = ip6gre_get_size,
1722 .fill_info = ip6gre_fill_info,
1723};
1724
1725static struct rtnl_link_ops ip6gre_tap_ops __read_mostly = {
1726 .kind = "ip6gretap",
1727 .maxtype = IFLA_GRE_MAX,
1728 .policy = ip6gre_policy,
1729 .priv_size = sizeof(struct ip6_tnl),
1730 .setup = ip6gre_tap_setup,
1731 .validate = ip6gre_tap_validate,
1732 .newlink = ip6gre_newlink,
1733 .changelink = ip6gre_changelink,
1734 .get_size = ip6gre_get_size,
1735 .fill_info = ip6gre_fill_info,
1736};
1737
1738/*
1739 * And now the modules code and kernel interface.
1740 */
1741
1742static int __init ip6gre_init(void)
1743{
1744 int err;
1745
1746 pr_info("GRE over IPv6 tunneling driver\n");
1747
1748 err = register_pernet_device(&ip6gre_net_ops);
1749 if (err < 0)
1750 return err;
1751
1752 err = inet6_add_protocol(&ip6gre_protocol, IPPROTO_GRE);
1753 if (err < 0) {
1754 pr_info("%s: can't add protocol\n", __func__);
1755 goto add_proto_failed;
1756 }
1757
1758 err = rtnl_link_register(&ip6gre_link_ops);
1759 if (err < 0)
1760 goto rtnl_link_failed;
1761
1762 err = rtnl_link_register(&ip6gre_tap_ops);
1763 if (err < 0)
1764 goto tap_ops_failed;
1765
1766out:
1767 return err;
1768
1769tap_ops_failed:
1770 rtnl_link_unregister(&ip6gre_link_ops);
1771rtnl_link_failed:
1772 inet6_del_protocol(&ip6gre_protocol, IPPROTO_GRE);
1773add_proto_failed:
1774 unregister_pernet_device(&ip6gre_net_ops);
1775 goto out;
1776}
1777
1778static void __exit ip6gre_fini(void)
1779{
1780 rtnl_link_unregister(&ip6gre_tap_ops);
1781 rtnl_link_unregister(&ip6gre_link_ops);
1782 inet6_del_protocol(&ip6gre_protocol, IPPROTO_GRE);
1783 unregister_pernet_device(&ip6gre_net_ops);
1784}
1785
1786module_init(ip6gre_init);
1787module_exit(ip6gre_fini);
1788MODULE_LICENSE("GPL");
1789MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
1790MODULE_DESCRIPTION("GRE over IPv6 tunneling device");
1791MODULE_ALIAS_RTNL_LINK("ip6gre");
1792MODULE_ALIAS_NETDEV("ip6gre0");
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5b2d63ed793e..3dd4a37488d5 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -123,16 +123,11 @@ static int ip6_finish_output2(struct sk_buff *skb)
123 skb->len); 123 skb->len);
124 } 124 }
125 125
126 rcu_read_lock();
127 rt = (struct rt6_info *) dst; 126 rt = (struct rt6_info *) dst;
128 neigh = rt->n; 127 neigh = rt->n;
129 if (neigh) { 128 if (neigh)
130 int res = dst_neigh_output(dst, neigh, skb); 129 return dst_neigh_output(dst, neigh, skb);
131 130
132 rcu_read_unlock();
133 return res;
134 }
135 rcu_read_unlock();
136 IP6_INC_STATS_BH(dev_net(dst->dev), 131 IP6_INC_STATS_BH(dev_net(dst->dev),
137 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 132 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
138 kfree_skb(skb); 133 kfree_skb(skb);
@@ -493,7 +488,8 @@ int ip6_forward(struct sk_buff *skb)
493 if (mtu < IPV6_MIN_MTU) 488 if (mtu < IPV6_MIN_MTU)
494 mtu = IPV6_MIN_MTU; 489 mtu = IPV6_MIN_MTU;
495 490
496 if (skb->len > mtu && !skb_is_gso(skb)) { 491 if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
492 (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {
497 /* Again, force OUTPUT device used as source address */ 493 /* Again, force OUTPUT device used as source address */
498 skb->dev = dst->dev; 494 skb->dev = dst->dev;
499 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 495 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
@@ -636,7 +632,9 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
636 /* We must not fragment if the socket is set to force MTU discovery 632 /* We must not fragment if the socket is set to force MTU discovery
637 * or if the skb it not generated by a local socket. 633 * or if the skb it not generated by a local socket.
638 */ 634 */
639 if (unlikely(!skb->local_df && skb->len > mtu)) { 635 if (unlikely(!skb->local_df && skb->len > mtu) ||
636 (IP6CB(skb)->frag_max_size &&
637 IP6CB(skb)->frag_max_size > mtu)) {
640 if (skb->sk && dst_allfrag(skb_dst(skb))) 638 if (skb->sk && dst_allfrag(skb_dst(skb)))
641 sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK); 639 sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
642 640
@@ -980,7 +978,6 @@ static int ip6_dst_lookup_tail(struct sock *sk,
980 * dst entry and replace it instead with the 978 * dst entry and replace it instead with the
981 * dst entry of the nexthop router 979 * dst entry of the nexthop router
982 */ 980 */
983 rcu_read_lock();
984 rt = (struct rt6_info *) *dst; 981 rt = (struct rt6_info *) *dst;
985 n = rt->n; 982 n = rt->n;
986 if (n && !(n->nud_state & NUD_VALID)) { 983 if (n && !(n->nud_state & NUD_VALID)) {
@@ -988,7 +985,6 @@ static int ip6_dst_lookup_tail(struct sock *sk,
988 struct flowi6 fl_gw6; 985 struct flowi6 fl_gw6;
989 int redirect; 986 int redirect;
990 987
991 rcu_read_unlock();
992 ifp = ipv6_get_ifaddr(net, &fl6->saddr, 988 ifp = ipv6_get_ifaddr(net, &fl6->saddr,
993 (*dst)->dev, 1); 989 (*dst)->dev, 1);
994 990
@@ -1008,8 +1004,6 @@ static int ip6_dst_lookup_tail(struct sock *sk,
1008 if ((err = (*dst)->error)) 1004 if ((err = (*dst)->error))
1009 goto out_err_release; 1005 goto out_err_release;
1010 } 1006 }
1011 } else {
1012 rcu_read_unlock();
1013 } 1007 }
1014#endif 1008#endif
1015 1009
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9a1d5fe6aef8..cb7e2ded6f08 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -126,7 +126,7 @@ static struct net_device_stats *ip6_get_stats(struct net_device *dev)
126 * Locking : hash tables are protected by RCU and RTNL 126 * Locking : hash tables are protected by RCU and RTNL
127 */ 127 */
128 128
129static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t) 129struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
130{ 130{
131 struct dst_entry *dst = t->dst_cache; 131 struct dst_entry *dst = t->dst_cache;
132 132
@@ -139,20 +139,23 @@ static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
139 139
140 return dst; 140 return dst;
141} 141}
142EXPORT_SYMBOL_GPL(ip6_tnl_dst_check);
142 143
143static inline void ip6_tnl_dst_reset(struct ip6_tnl *t) 144void ip6_tnl_dst_reset(struct ip6_tnl *t)
144{ 145{
145 dst_release(t->dst_cache); 146 dst_release(t->dst_cache);
146 t->dst_cache = NULL; 147 t->dst_cache = NULL;
147} 148}
149EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset);
148 150
149static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst) 151void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
150{ 152{
151 struct rt6_info *rt = (struct rt6_info *) dst; 153 struct rt6_info *rt = (struct rt6_info *) dst;
152 t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; 154 t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
153 dst_release(t->dst_cache); 155 dst_release(t->dst_cache);
154 t->dst_cache = dst; 156 t->dst_cache = dst;
155} 157}
158EXPORT_SYMBOL_GPL(ip6_tnl_dst_store);
156 159
157/** 160/**
158 * ip6_tnl_lookup - fetch tunnel matching the end-point addresses 161 * ip6_tnl_lookup - fetch tunnel matching the end-point addresses
@@ -200,7 +203,7 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
200 **/ 203 **/
201 204
202static struct ip6_tnl __rcu ** 205static struct ip6_tnl __rcu **
203ip6_tnl_bucket(struct ip6_tnl_net *ip6n, const struct ip6_tnl_parm *p) 206ip6_tnl_bucket(struct ip6_tnl_net *ip6n, const struct __ip6_tnl_parm *p)
204{ 207{
205 const struct in6_addr *remote = &p->raddr; 208 const struct in6_addr *remote = &p->raddr;
206 const struct in6_addr *local = &p->laddr; 209 const struct in6_addr *local = &p->laddr;
@@ -267,7 +270,7 @@ static void ip6_dev_free(struct net_device *dev)
267 * created tunnel or NULL 270 * created tunnel or NULL
268 **/ 271 **/
269 272
270static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) 273static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
271{ 274{
272 struct net_device *dev; 275 struct net_device *dev;
273 struct ip6_tnl *t; 276 struct ip6_tnl *t;
@@ -322,7 +325,7 @@ failed:
322 **/ 325 **/
323 326
324static struct ip6_tnl *ip6_tnl_locate(struct net *net, 327static struct ip6_tnl *ip6_tnl_locate(struct net *net,
325 struct ip6_tnl_parm *p, int create) 328 struct __ip6_tnl_parm *p, int create)
326{ 329{
327 const struct in6_addr *remote = &p->raddr; 330 const struct in6_addr *remote = &p->raddr;
328 const struct in6_addr *local = &p->laddr; 331 const struct in6_addr *local = &p->laddr;
@@ -374,8 +377,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
374 * else index to encapsulation limit 377 * else index to encapsulation limit
375 **/ 378 **/
376 379
377static __u16 380__u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __u8 *raw)
378parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
379{ 381{
380 const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw; 382 const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) raw;
381 __u8 nexthdr = ipv6h->nexthdr; 383 __u8 nexthdr = ipv6h->nexthdr;
@@ -425,6 +427,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
425 } 427 }
426 return 0; 428 return 0;
427} 429}
430EXPORT_SYMBOL(ip6_tnl_parse_tlv_enc_lim);
428 431
429/** 432/**
430 * ip6_tnl_err - tunnel error handler 433 * ip6_tnl_err - tunnel error handler
@@ -480,7 +483,7 @@ ip6_tnl_err(struct sk_buff *skb, __u8 ipproto, struct inet6_skb_parm *opt,
480 case ICMPV6_PARAMPROB: 483 case ICMPV6_PARAMPROB:
481 teli = 0; 484 teli = 0;
482 if ((*code) == ICMPV6_HDR_FIELD) 485 if ((*code) == ICMPV6_HDR_FIELD)
483 teli = parse_tlv_tnl_enc_lim(skb, skb->data); 486 teli = ip6_tnl_parse_tlv_enc_lim(skb, skb->data);
484 487
485 if (teli && teli == *info - 2) { 488 if (teli && teli == *info - 2) {
486 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; 489 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
@@ -693,11 +696,11 @@ static void ip6ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t,
693 IP6_ECN_set_ce(ipv6_hdr(skb)); 696 IP6_ECN_set_ce(ipv6_hdr(skb));
694} 697}
695 698
696static __u32 ip6_tnl_get_cap(struct ip6_tnl *t, 699__u32 ip6_tnl_get_cap(struct ip6_tnl *t,
697 const struct in6_addr *laddr, 700 const struct in6_addr *laddr,
698 const struct in6_addr *raddr) 701 const struct in6_addr *raddr)
699{ 702{
700 struct ip6_tnl_parm *p = &t->parms; 703 struct __ip6_tnl_parm *p = &t->parms;
701 int ltype = ipv6_addr_type(laddr); 704 int ltype = ipv6_addr_type(laddr);
702 int rtype = ipv6_addr_type(raddr); 705 int rtype = ipv6_addr_type(raddr);
703 __u32 flags = 0; 706 __u32 flags = 0;
@@ -715,13 +718,14 @@ static __u32 ip6_tnl_get_cap(struct ip6_tnl *t,
715 } 718 }
716 return flags; 719 return flags;
717} 720}
721EXPORT_SYMBOL(ip6_tnl_get_cap);
718 722
719/* called with rcu_read_lock() */ 723/* called with rcu_read_lock() */
720static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t, 724int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
721 const struct in6_addr *laddr, 725 const struct in6_addr *laddr,
722 const struct in6_addr *raddr) 726 const struct in6_addr *raddr)
723{ 727{
724 struct ip6_tnl_parm *p = &t->parms; 728 struct __ip6_tnl_parm *p = &t->parms;
725 int ret = 0; 729 int ret = 0;
726 struct net *net = dev_net(t->dev); 730 struct net *net = dev_net(t->dev);
727 731
@@ -740,6 +744,7 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
740 } 744 }
741 return ret; 745 return ret;
742} 746}
747EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl);
743 748
744/** 749/**
745 * ip6_tnl_rcv - decapsulate IPv6 packet and retransmit it locally 750 * ip6_tnl_rcv - decapsulate IPv6 packet and retransmit it locally
@@ -859,9 +864,9 @@ ip6_tnl_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
859 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); 864 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
860} 865}
861 866
862static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t) 867int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
863{ 868{
864 struct ip6_tnl_parm *p = &t->parms; 869 struct __ip6_tnl_parm *p = &t->parms;
865 int ret = 0; 870 int ret = 0;
866 struct net *net = dev_net(t->dev); 871 struct net *net = dev_net(t->dev);
867 872
@@ -885,6 +890,8 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
885 } 890 }
886 return ret; 891 return ret;
887} 892}
893EXPORT_SYMBOL_GPL(ip6_tnl_xmit_ctl);
894
888/** 895/**
889 * ip6_tnl_xmit2 - encapsulate packet and send 896 * ip6_tnl_xmit2 - encapsulate packet and send
890 * @skb: the outgoing socket buffer 897 * @skb: the outgoing socket buffer
@@ -1085,7 +1092,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1085 !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h)) 1092 !ip6_tnl_xmit_ctl(t) || ip6_tnl_addr_conflict(t, ipv6h))
1086 return -1; 1093 return -1;
1087 1094
1088 offset = parse_tlv_tnl_enc_lim(skb, skb_network_header(skb)); 1095 offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
1089 if (offset > 0) { 1096 if (offset > 0) {
1090 struct ipv6_tlv_tnl_enc_lim *tel; 1097 struct ipv6_tlv_tnl_enc_lim *tel;
1091 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; 1098 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
@@ -1152,7 +1159,7 @@ tx_err:
1152static void ip6_tnl_link_config(struct ip6_tnl *t) 1159static void ip6_tnl_link_config(struct ip6_tnl *t)
1153{ 1160{
1154 struct net_device *dev = t->dev; 1161 struct net_device *dev = t->dev;
1155 struct ip6_tnl_parm *p = &t->parms; 1162 struct __ip6_tnl_parm *p = &t->parms;
1156 struct flowi6 *fl6 = &t->fl.u.ip6; 1163 struct flowi6 *fl6 = &t->fl.u.ip6;
1157 1164
1158 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr)); 1165 memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
@@ -1215,7 +1222,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
1215 **/ 1222 **/
1216 1223
1217static int 1224static int
1218ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p) 1225ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
1219{ 1226{
1220 t->parms.laddr = p->laddr; 1227 t->parms.laddr = p->laddr;
1221 t->parms.raddr = p->raddr; 1228 t->parms.raddr = p->raddr;
@@ -1230,6 +1237,34 @@ ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p)
1230 return 0; 1237 return 0;
1231} 1238}
1232 1239
1240static void
1241ip6_tnl_parm_from_user(struct __ip6_tnl_parm *p, const struct ip6_tnl_parm *u)
1242{
1243 p->laddr = u->laddr;
1244 p->raddr = u->raddr;
1245 p->flags = u->flags;
1246 p->hop_limit = u->hop_limit;
1247 p->encap_limit = u->encap_limit;
1248 p->flowinfo = u->flowinfo;
1249 p->link = u->link;
1250 p->proto = u->proto;
1251 memcpy(p->name, u->name, sizeof(u->name));
1252}
1253
1254static void
1255ip6_tnl_parm_to_user(struct ip6_tnl_parm *u, const struct __ip6_tnl_parm *p)
1256{
1257 u->laddr = p->laddr;
1258 u->raddr = p->raddr;
1259 u->flags = p->flags;
1260 u->hop_limit = p->hop_limit;
1261 u->encap_limit = p->encap_limit;
1262 u->flowinfo = p->flowinfo;
1263 u->link = p->link;
1264 u->proto = p->proto;
1265 memcpy(u->name, p->name, sizeof(u->name));
1266}
1267
1233/** 1268/**
1234 * ip6_tnl_ioctl - configure ipv6 tunnels from userspace 1269 * ip6_tnl_ioctl - configure ipv6 tunnels from userspace
1235 * @dev: virtual device associated with tunnel 1270 * @dev: virtual device associated with tunnel
@@ -1263,6 +1298,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1263{ 1298{
1264 int err = 0; 1299 int err = 0;
1265 struct ip6_tnl_parm p; 1300 struct ip6_tnl_parm p;
1301 struct __ip6_tnl_parm p1;
1266 struct ip6_tnl *t = NULL; 1302 struct ip6_tnl *t = NULL;
1267 struct net *net = dev_net(dev); 1303 struct net *net = dev_net(dev);
1268 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1304 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
@@ -1274,11 +1310,14 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1274 err = -EFAULT; 1310 err = -EFAULT;
1275 break; 1311 break;
1276 } 1312 }
1277 t = ip6_tnl_locate(net, &p, 0); 1313 ip6_tnl_parm_from_user(&p1, &p);
1314 t = ip6_tnl_locate(net, &p1, 0);
1315 } else {
1316 memset(&p, 0, sizeof(p));
1278 } 1317 }
1279 if (t == NULL) 1318 if (t == NULL)
1280 t = netdev_priv(dev); 1319 t = netdev_priv(dev);
1281 memcpy(&p, &t->parms, sizeof (p)); 1320 ip6_tnl_parm_to_user(&p, &t->parms);
1282 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { 1321 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
1283 err = -EFAULT; 1322 err = -EFAULT;
1284 } 1323 }
@@ -1295,7 +1334,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1295 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP && 1334 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP &&
1296 p.proto != 0) 1335 p.proto != 0)
1297 break; 1336 break;
1298 t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL); 1337 ip6_tnl_parm_from_user(&p1, &p);
1338 t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL);
1299 if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) { 1339 if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
1300 if (t != NULL) { 1340 if (t != NULL) {
1301 if (t->dev != dev) { 1341 if (t->dev != dev) {
@@ -1307,13 +1347,14 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1307 1347
1308 ip6_tnl_unlink(ip6n, t); 1348 ip6_tnl_unlink(ip6n, t);
1309 synchronize_net(); 1349 synchronize_net();
1310 err = ip6_tnl_change(t, &p); 1350 err = ip6_tnl_change(t, &p1);
1311 ip6_tnl_link(ip6n, t); 1351 ip6_tnl_link(ip6n, t);
1312 netdev_state_change(dev); 1352 netdev_state_change(dev);
1313 } 1353 }
1314 if (t) { 1354 if (t) {
1315 err = 0; 1355 err = 0;
1316 if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof (p))) 1356 ip6_tnl_parm_to_user(&p, &t->parms);
1357 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
1317 err = -EFAULT; 1358 err = -EFAULT;
1318 1359
1319 } else 1360 } else
@@ -1329,7 +1370,9 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1329 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) 1370 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
1330 break; 1371 break;
1331 err = -ENOENT; 1372 err = -ENOENT;
1332 if ((t = ip6_tnl_locate(net, &p, 0)) == NULL) 1373 ip6_tnl_parm_from_user(&p1, &p);
1374 t = ip6_tnl_locate(net, &p1, 0);
1375 if (t == NULL)
1333 break; 1376 break;
1334 err = -EPERM; 1377 err = -EPERM;
1335 if (t->dev == ip6n->fb_tnl_dev) 1378 if (t->dev == ip6n->fb_tnl_dev)
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 4532973f0dd4..08ea3f0b6e55 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -838,7 +838,7 @@ static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c)
838 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 838 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
839 skb_trim(skb, nlh->nlmsg_len); 839 skb_trim(skb, nlh->nlmsg_len);
840 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT; 840 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
841 rtnl_unicast(skb, net, NETLINK_CB(skb).pid); 841 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
842 } else 842 } else
843 kfree_skb(skb); 843 kfree_skb(skb);
844 } 844 }
@@ -1052,7 +1052,7 @@ static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
1052 skb_trim(skb, nlh->nlmsg_len); 1052 skb_trim(skb, nlh->nlmsg_len);
1053 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE; 1053 ((struct nlmsgerr *)NLMSG_DATA(nlh))->error = -EMSGSIZE;
1054 } 1054 }
1055 rtnl_unicast(skb, net, NETLINK_CB(skb).pid); 1055 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
1056 } else 1056 } else
1057 ip6_mr_forward(net, mrt, skb, c); 1057 ip6_mr_forward(net, mrt, skb, c);
1058 } 1058 }
@@ -2202,12 +2202,12 @@ int ip6mr_get_route(struct net *net,
2202} 2202}
2203 2203
2204static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, 2204static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2205 u32 pid, u32 seq, struct mfc6_cache *c) 2205 u32 portid, u32 seq, struct mfc6_cache *c)
2206{ 2206{
2207 struct nlmsghdr *nlh; 2207 struct nlmsghdr *nlh;
2208 struct rtmsg *rtm; 2208 struct rtmsg *rtm;
2209 2209
2210 nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI); 2210 nlh = nlmsg_put(skb, portid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
2211 if (nlh == NULL) 2211 if (nlh == NULL)
2212 return -EMSGSIZE; 2212 return -EMSGSIZE;
2213 2213
@@ -2260,7 +2260,7 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
2260 if (e < s_e) 2260 if (e < s_e)
2261 goto next_entry; 2261 goto next_entry;
2262 if (ip6mr_fill_mroute(mrt, skb, 2262 if (ip6mr_fill_mroute(mrt, skb,
2263 NETLINK_CB(cb->skb).pid, 2263 NETLINK_CB(cb->skb).portid,
2264 cb->nlh->nlmsg_seq, 2264 cb->nlh->nlmsg_seq,
2265 mfc) < 0) 2265 mfc) < 0)
2266 goto done; 2266 goto done;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index db31561cc8df..429089cb073d 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -15,6 +15,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
15{ 15{
16 struct net *net = dev_net(skb_dst(skb)->dev); 16 struct net *net = dev_net(skb_dst(skb)->dev);
17 const struct ipv6hdr *iph = ipv6_hdr(skb); 17 const struct ipv6hdr *iph = ipv6_hdr(skb);
18 unsigned int hh_len;
18 struct dst_entry *dst; 19 struct dst_entry *dst;
19 struct flowi6 fl6 = { 20 struct flowi6 fl6 = {
20 .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, 21 .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
@@ -47,6 +48,13 @@ int ip6_route_me_harder(struct sk_buff *skb)
47 } 48 }
48#endif 49#endif
49 50
51 /* Change in oif may mean change in hh_len. */
52 hh_len = skb_dst(skb)->dev->hard_header_len;
53 if (skb_headroom(skb) < hh_len &&
54 pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)),
55 0, GFP_ATOMIC))
56 return -1;
57
50 return 0; 58 return 0;
51} 59}
52EXPORT_SYMBOL(ip6_route_me_harder); 60EXPORT_SYMBOL(ip6_route_me_harder);
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 10135342799e..3b73254d7bf1 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -25,6 +25,18 @@ config NF_CONNTRACK_IPV6
25 25
26 To compile it as a module, choose M here. If unsure, say N. 26 To compile it as a module, choose M here. If unsure, say N.
27 27
28config NF_NAT_IPV6
29 tristate "IPv6 NAT"
30 depends on NF_CONNTRACK_IPV6
31 depends on NETFILTER_ADVANCED
32 select NF_NAT
33 help
34 The IPv6 NAT option allows masquerading, port forwarding and other
35 forms of full Network Address Port Translation. It is controlled by
36 the `nat' table in ip6tables, see the man page for ip6tables(8).
37
38 To compile it as a module, choose M here. If unsure, say N.
39
28config IP6_NF_IPTABLES 40config IP6_NF_IPTABLES
29 tristate "IP6 tables support (required for filtering)" 41 tristate "IP6 tables support (required for filtering)"
30 depends on INET && IPV6 42 depends on INET && IPV6
@@ -132,6 +144,48 @@ config IP6_NF_TARGET_HL
132 (e.g. when running oldconfig). It selects 144 (e.g. when running oldconfig). It selects
133 CONFIG_NETFILTER_XT_TARGET_HL. 145 CONFIG_NETFILTER_XT_TARGET_HL.
134 146
147config IP6_NF_TARGET_MASQUERADE
148 tristate "MASQUERADE target support"
149 depends on NF_NAT_IPV6
150 help
151 Masquerading is a special case of NAT: all outgoing connections are
152 changed to seem to come from a particular interface's address, and
153 if the interface goes down, those connections are lost. This is
154 only useful for dialup accounts with dynamic IP address (ie. your IP
155 address will be different on next dialup).
156
157 To compile it as a module, choose M here. If unsure, say N.
158
159config IP6_NF_TARGET_NETMAP
160 tristate "NETMAP target support"
161 depends on NF_NAT_IPV6
162 help
163 NETMAP is an implementation of static 1:1 NAT mapping of network
164 addresses. It maps the network address part, while keeping the host
165 address part intact.
166
167 To compile it as a module, choose M here. If unsure, say N.
168
169config IP6_NF_TARGET_REDIRECT
170 tristate "REDIRECT target support"
171 depends on NF_NAT_IPV6
172 help
173 REDIRECT is a special case of NAT: all incoming connections are
174 mapped onto the incoming interface's address, causing the packets to
175 come to the local machine instead of passing through. This is
176 useful for transparent proxies.
177
178 To compile it as a module, choose M here. If unsure, say N.
179
180config IP6_NF_TARGET_NPT
181 tristate "NPT (Network Prefix translation) target support"
182 depends on NETFILTER_ADVANCED
183 help
184 This option adds the `SNPT' and `DNPT' target, which perform
185 stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
186
187 To compile it as a module, choose M here. If unsure, say N.
188
135config IP6_NF_FILTER 189config IP6_NF_FILTER
136 tristate "Packet filtering" 190 tristate "Packet filtering"
137 default m if NETFILTER_ADVANCED=n 191 default m if NETFILTER_ADVANCED=n
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 534d3f216f7b..5752132ca159 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
8obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 8obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
9obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 9obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
10obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o 10obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
11obj-$(CONFIG_NF_NAT_IPV6) += ip6table_nat.o
11 12
12# objects for l3 independent conntrack 13# objects for l3 independent conntrack
13nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o 14nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
@@ -15,6 +16,9 @@ nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
15# l3 independent conntrack 16# l3 independent conntrack
16obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o 17obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o
17 18
19nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o
20obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o
21
18# defrag 22# defrag
19nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o 23nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
20obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o 24obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
@@ -30,4 +34,8 @@ obj-$(CONFIG_IP6_NF_MATCH_RPFILTER) += ip6t_rpfilter.o
30obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o 34obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
31 35
32# targets 36# targets
37obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o
38obj-$(CONFIG_IP6_NF_TARGET_NETMAP) += ip6t_NETMAP.o
39obj-$(CONFIG_IP6_NF_TARGET_NPT) += ip6t_NPT.o
40obj-$(CONFIG_IP6_NF_TARGET_REDIRECT) += ip6t_REDIRECT.o
33obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o 41obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
new file mode 100644
index 000000000000..60e9053bab05
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
@@ -0,0 +1,135 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on Rusty Russell's IPv6 MASQUERADE target. Development of IPv6
9 * NAT funded by Astaro.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/netdevice.h>
15#include <linux/ipv6.h>
16#include <linux/netfilter.h>
17#include <linux/netfilter_ipv6.h>
18#include <linux/netfilter/x_tables.h>
19#include <net/netfilter/nf_nat.h>
20#include <net/addrconf.h>
21#include <net/ipv6.h>
22
23static unsigned int
24masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par)
25{
26 const struct nf_nat_range *range = par->targinfo;
27 enum ip_conntrack_info ctinfo;
28 struct in6_addr src;
29 struct nf_conn *ct;
30 struct nf_nat_range newrange;
31
32 ct = nf_ct_get(skb, &ctinfo);
33 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
34 ctinfo == IP_CT_RELATED_REPLY));
35
36 if (ipv6_dev_get_saddr(dev_net(par->out), par->out,
37 &ipv6_hdr(skb)->daddr, 0, &src) < 0)
38 return NF_DROP;
39
40 nfct_nat(ct)->masq_index = par->out->ifindex;
41
42 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
43 newrange.min_addr.in6 = src;
44 newrange.max_addr.in6 = src;
45 newrange.min_proto = range->min_proto;
46 newrange.max_proto = range->max_proto;
47
48 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
49}
50
51static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
52{
53 const struct nf_nat_range *range = par->targinfo;
54
55 if (range->flags & NF_NAT_RANGE_MAP_IPS)
56 return -EINVAL;
57 return 0;
58}
59
60static int device_cmp(struct nf_conn *ct, void *ifindex)
61{
62 const struct nf_conn_nat *nat = nfct_nat(ct);
63
64 if (!nat)
65 return 0;
66 if (nf_ct_l3num(ct) != NFPROTO_IPV6)
67 return 0;
68 return nat->masq_index == (int)(long)ifindex;
69}
70
71static int masq_device_event(struct notifier_block *this,
72 unsigned long event, void *ptr)
73{
74 const struct net_device *dev = ptr;
75 struct net *net = dev_net(dev);
76
77 if (event == NETDEV_DOWN)
78 nf_ct_iterate_cleanup(net, device_cmp,
79 (void *)(long)dev->ifindex);
80
81 return NOTIFY_DONE;
82}
83
84static struct notifier_block masq_dev_notifier = {
85 .notifier_call = masq_device_event,
86};
87
88static int masq_inet_event(struct notifier_block *this,
89 unsigned long event, void *ptr)
90{
91 struct inet6_ifaddr *ifa = ptr;
92
93 return masq_device_event(this, event, ifa->idev->dev);
94}
95
96static struct notifier_block masq_inet_notifier = {
97 .notifier_call = masq_inet_event,
98};
99
100static struct xt_target masquerade_tg6_reg __read_mostly = {
101 .name = "MASQUERADE",
102 .family = NFPROTO_IPV6,
103 .checkentry = masquerade_tg6_checkentry,
104 .target = masquerade_tg6,
105 .targetsize = sizeof(struct nf_nat_range),
106 .table = "nat",
107 .hooks = 1 << NF_INET_POST_ROUTING,
108 .me = THIS_MODULE,
109};
110
111static int __init masquerade_tg6_init(void)
112{
113 int err;
114
115 err = xt_register_target(&masquerade_tg6_reg);
116 if (err == 0) {
117 register_netdevice_notifier(&masq_dev_notifier);
118 register_inet6addr_notifier(&masq_inet_notifier);
119 }
120
121 return err;
122}
123static void __exit masquerade_tg6_exit(void)
124{
125 unregister_inet6addr_notifier(&masq_inet_notifier);
126 unregister_netdevice_notifier(&masq_dev_notifier);
127 xt_unregister_target(&masquerade_tg6_reg);
128}
129
130module_init(masquerade_tg6_init);
131module_exit(masquerade_tg6_exit);
132
133MODULE_LICENSE("GPL");
134MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
135MODULE_DESCRIPTION("Xtables: automatic address SNAT");
diff --git a/net/ipv6/netfilter/ip6t_NETMAP.c b/net/ipv6/netfilter/ip6t_NETMAP.c
new file mode 100644
index 000000000000..4f3bf360e50f
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_NETMAP.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on Svenning Soerensen's IPv4 NETMAP target. Development of IPv6
9 * NAT funded by Astaro.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/ipv6.h>
15#include <linux/netfilter.h>
16#include <linux/netfilter_ipv6.h>
17#include <linux/netfilter/x_tables.h>
18#include <net/netfilter/nf_nat.h>
19
20static unsigned int
21netmap_tg6(struct sk_buff *skb, const struct xt_action_param *par)
22{
23 const struct nf_nat_range *range = par->targinfo;
24 struct nf_nat_range newrange;
25 struct nf_conn *ct;
26 enum ip_conntrack_info ctinfo;
27 union nf_inet_addr new_addr, netmask;
28 unsigned int i;
29
30 ct = nf_ct_get(skb, &ctinfo);
31 for (i = 0; i < ARRAY_SIZE(range->min_addr.ip6); i++)
32 netmask.ip6[i] = ~(range->min_addr.ip6[i] ^
33 range->max_addr.ip6[i]);
34
35 if (par->hooknum == NF_INET_PRE_ROUTING ||
36 par->hooknum == NF_INET_LOCAL_OUT)
37 new_addr.in6 = ipv6_hdr(skb)->daddr;
38 else
39 new_addr.in6 = ipv6_hdr(skb)->saddr;
40
41 for (i = 0; i < ARRAY_SIZE(new_addr.ip6); i++) {
42 new_addr.ip6[i] &= ~netmask.ip6[i];
43 new_addr.ip6[i] |= range->min_addr.ip6[i] &
44 netmask.ip6[i];
45 }
46
47 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
48 newrange.min_addr = new_addr;
49 newrange.max_addr = new_addr;
50 newrange.min_proto = range->min_proto;
51 newrange.max_proto = range->max_proto;
52
53 return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum));
54}
55
56static int netmap_tg6_checkentry(const struct xt_tgchk_param *par)
57{
58 const struct nf_nat_range *range = par->targinfo;
59
60 if (!(range->flags & NF_NAT_RANGE_MAP_IPS))
61 return -EINVAL;
62 return 0;
63}
64
65static struct xt_target netmap_tg6_reg __read_mostly = {
66 .name = "NETMAP",
67 .family = NFPROTO_IPV6,
68 .target = netmap_tg6,
69 .targetsize = sizeof(struct nf_nat_range),
70 .table = "nat",
71 .hooks = (1 << NF_INET_PRE_ROUTING) |
72 (1 << NF_INET_POST_ROUTING) |
73 (1 << NF_INET_LOCAL_OUT) |
74 (1 << NF_INET_LOCAL_IN),
75 .checkentry = netmap_tg6_checkentry,
76 .me = THIS_MODULE,
77};
78
79static int __init netmap_tg6_init(void)
80{
81 return xt_register_target(&netmap_tg6_reg);
82}
83
84static void netmap_tg6_exit(void)
85{
86 xt_unregister_target(&netmap_tg6_reg);
87}
88
89module_init(netmap_tg6_init);
90module_exit(netmap_tg6_exit);
91
92MODULE_LICENSE("GPL");
93MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv6 subnets");
94MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c
new file mode 100644
index 000000000000..e9486915eff6
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_NPT.c
@@ -0,0 +1,165 @@
1/*
2 * Copyright (c) 2011, 2012 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/ipv6.h>
12#include <linux/netfilter.h>
13#include <linux/netfilter_ipv6.h>
14#include <linux/netfilter_ipv6/ip6t_NPT.h>
15#include <linux/netfilter/x_tables.h>
16
17static __sum16 csum16_complement(__sum16 a)
18{
19 return (__force __sum16)(0xffff - (__force u16)a);
20}
21
22static __sum16 csum16_add(__sum16 a, __sum16 b)
23{
24 u16 sum;
25
26 sum = (__force u16)a + (__force u16)b;
27 sum += (__force u16)a < (__force u16)b;
28 return (__force __sum16)sum;
29}
30
31static __sum16 csum16_sub(__sum16 a, __sum16 b)
32{
33 return csum16_add(a, csum16_complement(b));
34}
35
36static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
37{
38 struct ip6t_npt_tginfo *npt = par->targinfo;
39 __sum16 src_sum = 0, dst_sum = 0;
40 unsigned int i;
41
42 if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64)
43 return -EINVAL;
44
45 for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) {
46 src_sum = csum16_add(src_sum,
47 (__force __sum16)npt->src_pfx.in6.s6_addr16[i]);
48 dst_sum = csum16_add(dst_sum,
49 (__force __sum16)npt->dst_pfx.in6.s6_addr16[i]);
50 }
51
52 npt->adjustment = csum16_sub(src_sum, dst_sum);
53 return 0;
54}
55
56static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,
57 struct in6_addr *addr)
58{
59 unsigned int pfx_len;
60 unsigned int i, idx;
61 __be32 mask;
62 __sum16 sum;
63
64 pfx_len = max(npt->src_pfx_len, npt->dst_pfx_len);
65 for (i = 0; i < pfx_len; i += 32) {
66 if (pfx_len - i >= 32)
67 mask = 0;
68 else
69 mask = htonl(~((1 << (pfx_len - i)) - 1));
70
71 idx = i / 32;
72 addr->s6_addr32[idx] &= mask;
73 addr->s6_addr32[idx] |= npt->dst_pfx.in6.s6_addr32[idx];
74 }
75
76 if (pfx_len <= 48)
77 idx = 3;
78 else {
79 for (idx = 4; idx < ARRAY_SIZE(addr->s6_addr16); idx++) {
80 if ((__force __sum16)addr->s6_addr16[idx] !=
81 CSUM_MANGLED_0)
82 break;
83 }
84 if (idx == ARRAY_SIZE(addr->s6_addr16))
85 return false;
86 }
87
88 sum = csum16_add((__force __sum16)addr->s6_addr16[idx],
89 npt->adjustment);
90 if (sum == CSUM_MANGLED_0)
91 sum = 0;
92 *(__force __sum16 *)&addr->s6_addr16[idx] = sum;
93
94 return true;
95}
96
97static unsigned int
98ip6t_snpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
99{
100 const struct ip6t_npt_tginfo *npt = par->targinfo;
101
102 if (!ip6t_npt_map_pfx(npt, &ipv6_hdr(skb)->saddr)) {
103 icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD,
104 offsetof(struct ipv6hdr, saddr));
105 return NF_DROP;
106 }
107 return XT_CONTINUE;
108}
109
110static unsigned int
111ip6t_dnpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
112{
113 const struct ip6t_npt_tginfo *npt = par->targinfo;
114
115 if (!ip6t_npt_map_pfx(npt, &ipv6_hdr(skb)->daddr)) {
116 icmpv6_send(skb, ICMPV6_PARAMPROB, ICMPV6_HDR_FIELD,
117 offsetof(struct ipv6hdr, daddr));
118 return NF_DROP;
119 }
120 return XT_CONTINUE;
121}
122
123static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
124 {
125 .name = "SNPT",
126 .target = ip6t_snpt_tg,
127 .targetsize = sizeof(struct ip6t_npt_tginfo),
128 .checkentry = ip6t_npt_checkentry,
129 .family = NFPROTO_IPV6,
130 .hooks = (1 << NF_INET_LOCAL_IN) |
131 (1 << NF_INET_POST_ROUTING),
132 .me = THIS_MODULE,
133 },
134 {
135 .name = "DNPT",
136 .target = ip6t_dnpt_tg,
137 .targetsize = sizeof(struct ip6t_npt_tginfo),
138 .checkentry = ip6t_npt_checkentry,
139 .family = NFPROTO_IPV6,
140 .hooks = (1 << NF_INET_PRE_ROUTING) |
141 (1 << NF_INET_LOCAL_OUT),
142 .me = THIS_MODULE,
143 },
144};
145
146static int __init ip6t_npt_init(void)
147{
148 return xt_register_targets(ip6t_npt_target_reg,
149 ARRAY_SIZE(ip6t_npt_target_reg));
150}
151
152static void __exit ip6t_npt_exit(void)
153{
154 xt_unregister_targets(ip6t_npt_target_reg,
155 ARRAY_SIZE(ip6t_npt_target_reg));
156}
157
158module_init(ip6t_npt_init);
159module_exit(ip6t_npt_exit);
160
161MODULE_LICENSE("GPL");
162MODULE_DESCRIPTION("IPv6-to-IPv6 Network Prefix Translation (RFC 6296)");
163MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
164MODULE_ALIAS("ip6t_SNPT");
165MODULE_ALIAS("ip6t_DNPT");
diff --git a/net/ipv6/netfilter/ip6t_REDIRECT.c b/net/ipv6/netfilter/ip6t_REDIRECT.c
new file mode 100644
index 000000000000..60497a3c6004
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_REDIRECT.c
@@ -0,0 +1,98 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6
9 * NAT funded by Astaro.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter_ipv6.h>
16#include <linux/netfilter/x_tables.h>
17#include <net/addrconf.h>
18#include <net/netfilter/nf_nat.h>
19
20static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
21
22static unsigned int
23redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par)
24{
25 const struct nf_nat_range *range = par->targinfo;
26 struct nf_nat_range newrange;
27 struct in6_addr newdst;
28 enum ip_conntrack_info ctinfo;
29 struct nf_conn *ct;
30
31 ct = nf_ct_get(skb, &ctinfo);
32 if (par->hooknum == NF_INET_LOCAL_OUT)
33 newdst = loopback_addr;
34 else {
35 struct inet6_dev *idev;
36 struct inet6_ifaddr *ifa;
37 bool addr = false;
38
39 rcu_read_lock();
40 idev = __in6_dev_get(skb->dev);
41 if (idev != NULL) {
42 list_for_each_entry(ifa, &idev->addr_list, if_list) {
43 newdst = ifa->addr;
44 addr = true;
45 break;
46 }
47 }
48 rcu_read_unlock();
49
50 if (!addr)
51 return NF_DROP;
52 }
53
54 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
55 newrange.min_addr.in6 = newdst;
56 newrange.max_addr.in6 = newdst;
57 newrange.min_proto = range->min_proto;
58 newrange.max_proto = range->max_proto;
59
60 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
61}
62
63static int redirect_tg6_checkentry(const struct xt_tgchk_param *par)
64{
65 const struct nf_nat_range *range = par->targinfo;
66
67 if (range->flags & NF_NAT_RANGE_MAP_IPS)
68 return -EINVAL;
69 return 0;
70}
71
72static struct xt_target redirect_tg6_reg __read_mostly = {
73 .name = "REDIRECT",
74 .family = NFPROTO_IPV6,
75 .checkentry = redirect_tg6_checkentry,
76 .target = redirect_tg6,
77 .targetsize = sizeof(struct nf_nat_range),
78 .table = "nat",
79 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
80 .me = THIS_MODULE,
81};
82
83static int __init redirect_tg6_init(void)
84{
85 return xt_register_target(&redirect_tg6_reg);
86}
87
88static void __exit redirect_tg6_exit(void)
89{
90 xt_unregister_target(&redirect_tg6_reg);
91}
92
93module_init(redirect_tg6_init);
94module_exit(redirect_tg6_exit);
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
98MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 325e59a0224f..beb5777d2043 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -61,9 +61,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
61 net->ipv6.ip6table_filter = 61 net->ipv6.ip6table_filter =
62 ip6t_register_table(net, &packet_filter, repl); 62 ip6t_register_table(net, &packet_filter, repl);
63 kfree(repl); 63 kfree(repl);
64 if (IS_ERR(net->ipv6.ip6table_filter)) 64 return PTR_RET(net->ipv6.ip6table_filter);
65 return PTR_ERR(net->ipv6.ip6table_filter);
66 return 0;
67} 65}
68 66
69static void __net_exit ip6table_filter_net_exit(struct net *net) 67static void __net_exit ip6table_filter_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 4d782405f125..7431121b87de 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -97,9 +97,7 @@ static int __net_init ip6table_mangle_net_init(struct net *net)
97 net->ipv6.ip6table_mangle = 97 net->ipv6.ip6table_mangle =
98 ip6t_register_table(net, &packet_mangler, repl); 98 ip6t_register_table(net, &packet_mangler, repl);
99 kfree(repl); 99 kfree(repl);
100 if (IS_ERR(net->ipv6.ip6table_mangle)) 100 return PTR_RET(net->ipv6.ip6table_mangle);
101 return PTR_ERR(net->ipv6.ip6table_mangle);
102 return 0;
103} 101}
104 102
105static void __net_exit ip6table_mangle_net_exit(struct net *net) 103static void __net_exit ip6table_mangle_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
new file mode 100644
index 000000000000..e418bd6350a4
--- /dev/null
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -0,0 +1,321 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on Rusty Russell's IPv4 NAT code. Development of IPv6 NAT
9 * funded by Astaro.
10 */
11
12#include <linux/module.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter_ipv6.h>
15#include <linux/netfilter_ipv6/ip6_tables.h>
16#include <linux/ipv6.h>
17#include <net/ipv6.h>
18
19#include <net/netfilter/nf_nat.h>
20#include <net/netfilter/nf_nat_core.h>
21#include <net/netfilter/nf_nat_l3proto.h>
22
23static const struct xt_table nf_nat_ipv6_table = {
24 .name = "nat",
25 .valid_hooks = (1 << NF_INET_PRE_ROUTING) |
26 (1 << NF_INET_POST_ROUTING) |
27 (1 << NF_INET_LOCAL_OUT) |
28 (1 << NF_INET_LOCAL_IN),
29 .me = THIS_MODULE,
30 .af = NFPROTO_IPV6,
31};
32
33static unsigned int alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
34{
35 /* Force range to this IP; let proto decide mapping for
36 * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
37 */
38 struct nf_nat_range range;
39
40 range.flags = 0;
41 pr_debug("Allocating NULL binding for %p (%pI6)\n", ct,
42 HOOK2MANIP(hooknum) == NF_NAT_MANIP_SRC ?
43 &ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6 :
44 &ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6);
45
46 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
47}
48
49static unsigned int nf_nat_rule_find(struct sk_buff *skb, unsigned int hooknum,
50 const struct net_device *in,
51 const struct net_device *out,
52 struct nf_conn *ct)
53{
54 struct net *net = nf_ct_net(ct);
55 unsigned int ret;
56
57 ret = ip6t_do_table(skb, hooknum, in, out, net->ipv6.ip6table_nat);
58 if (ret == NF_ACCEPT) {
59 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
60 ret = alloc_null_binding(ct, hooknum);
61 }
62 return ret;
63}
64
65static unsigned int
66nf_nat_ipv6_fn(unsigned int hooknum,
67 struct sk_buff *skb,
68 const struct net_device *in,
69 const struct net_device *out,
70 int (*okfn)(struct sk_buff *))
71{
72 struct nf_conn *ct;
73 enum ip_conntrack_info ctinfo;
74 struct nf_conn_nat *nat;
75 enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
76 __be16 frag_off;
77 int hdrlen;
78 u8 nexthdr;
79
80 ct = nf_ct_get(skb, &ctinfo);
81 /* Can't track? It's not due to stress, or conntrack would
82 * have dropped it. Hence it's the user's responsibilty to
83 * packet filter it out, or implement conntrack/NAT for that
84 * protocol. 8) --RR
85 */
86 if (!ct)
87 return NF_ACCEPT;
88
89 /* Don't try to NAT if this packet is not conntracked */
90 if (nf_ct_is_untracked(ct))
91 return NF_ACCEPT;
92
93 nat = nfct_nat(ct);
94 if (!nat) {
95 /* NAT module was loaded late. */
96 if (nf_ct_is_confirmed(ct))
97 return NF_ACCEPT;
98 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
99 if (nat == NULL) {
100 pr_debug("failed to add NAT extension\n");
101 return NF_ACCEPT;
102 }
103 }
104
105 switch (ctinfo) {
106 case IP_CT_RELATED:
107 case IP_CT_RELATED_REPLY:
108 nexthdr = ipv6_hdr(skb)->nexthdr;
109 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
110 &nexthdr, &frag_off);
111
112 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
113 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
114 hooknum, hdrlen))
115 return NF_DROP;
116 else
117 return NF_ACCEPT;
118 }
119 /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
120 case IP_CT_NEW:
121 /* Seen it before? This can happen for loopback, retrans,
122 * or local packets.
123 */
124 if (!nf_nat_initialized(ct, maniptype)) {
125 unsigned int ret;
126
127 ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
128 if (ret != NF_ACCEPT)
129 return ret;
130 } else
131 pr_debug("Already setup manip %s for ct %p\n",
132 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
133 ct);
134 break;
135
136 default:
137 /* ESTABLISHED */
138 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
139 ctinfo == IP_CT_ESTABLISHED_REPLY);
140 }
141
142 return nf_nat_packet(ct, ctinfo, hooknum, skb);
143}
144
145static unsigned int
146nf_nat_ipv6_in(unsigned int hooknum,
147 struct sk_buff *skb,
148 const struct net_device *in,
149 const struct net_device *out,
150 int (*okfn)(struct sk_buff *))
151{
152 unsigned int ret;
153 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
154
155 ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
156 if (ret != NF_DROP && ret != NF_STOLEN &&
157 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
158 skb_dst_drop(skb);
159
160 return ret;
161}
162
163static unsigned int
164nf_nat_ipv6_out(unsigned int hooknum,
165 struct sk_buff *skb,
166 const struct net_device *in,
167 const struct net_device *out,
168 int (*okfn)(struct sk_buff *))
169{
170#ifdef CONFIG_XFRM
171 const struct nf_conn *ct;
172 enum ip_conntrack_info ctinfo;
173#endif
174 unsigned int ret;
175
176 /* root is playing with raw sockets. */
177 if (skb->len < sizeof(struct ipv6hdr))
178 return NF_ACCEPT;
179
180 ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
181#ifdef CONFIG_XFRM
182 if (ret != NF_DROP && ret != NF_STOLEN &&
183 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
184 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
185 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
186
187 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
188 &ct->tuplehash[!dir].tuple.dst.u3) ||
189 (ct->tuplehash[dir].tuple.src.u.all !=
190 ct->tuplehash[!dir].tuple.dst.u.all))
191 if (nf_xfrm_me_harder(skb, AF_INET6) < 0)
192 ret = NF_DROP;
193 }
194#endif
195 return ret;
196}
197
198static unsigned int
199nf_nat_ipv6_local_fn(unsigned int hooknum,
200 struct sk_buff *skb,
201 const struct net_device *in,
202 const struct net_device *out,
203 int (*okfn)(struct sk_buff *))
204{
205 const struct nf_conn *ct;
206 enum ip_conntrack_info ctinfo;
207 unsigned int ret;
208
209 /* root is playing with raw sockets. */
210 if (skb->len < sizeof(struct ipv6hdr))
211 return NF_ACCEPT;
212
213 ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
214 if (ret != NF_DROP && ret != NF_STOLEN &&
215 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
216 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
217
218 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
219 &ct->tuplehash[!dir].tuple.src.u3)) {
220 if (ip6_route_me_harder(skb))
221 ret = NF_DROP;
222 }
223#ifdef CONFIG_XFRM
224 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
225 ct->tuplehash[dir].tuple.dst.u.all !=
226 ct->tuplehash[!dir].tuple.src.u.all)
227 if (nf_xfrm_me_harder(skb, AF_INET6))
228 ret = NF_DROP;
229#endif
230 }
231 return ret;
232}
233
234static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
235 /* Before packet filtering, change destination */
236 {
237 .hook = nf_nat_ipv6_in,
238 .owner = THIS_MODULE,
239 .pf = NFPROTO_IPV6,
240 .hooknum = NF_INET_PRE_ROUTING,
241 .priority = NF_IP6_PRI_NAT_DST,
242 },
243 /* After packet filtering, change source */
244 {
245 .hook = nf_nat_ipv6_out,
246 .owner = THIS_MODULE,
247 .pf = NFPROTO_IPV6,
248 .hooknum = NF_INET_POST_ROUTING,
249 .priority = NF_IP6_PRI_NAT_SRC,
250 },
251 /* Before packet filtering, change destination */
252 {
253 .hook = nf_nat_ipv6_local_fn,
254 .owner = THIS_MODULE,
255 .pf = NFPROTO_IPV6,
256 .hooknum = NF_INET_LOCAL_OUT,
257 .priority = NF_IP6_PRI_NAT_DST,
258 },
259 /* After packet filtering, change source */
260 {
261 .hook = nf_nat_ipv6_fn,
262 .owner = THIS_MODULE,
263 .pf = NFPROTO_IPV6,
264 .hooknum = NF_INET_LOCAL_IN,
265 .priority = NF_IP6_PRI_NAT_SRC,
266 },
267};
268
269static int __net_init ip6table_nat_net_init(struct net *net)
270{
271 struct ip6t_replace *repl;
272
273 repl = ip6t_alloc_initial_table(&nf_nat_ipv6_table);
274 if (repl == NULL)
275 return -ENOMEM;
276 net->ipv6.ip6table_nat = ip6t_register_table(net, &nf_nat_ipv6_table, repl);
277 kfree(repl);
278 if (IS_ERR(net->ipv6.ip6table_nat))
279 return PTR_ERR(net->ipv6.ip6table_nat);
280 return 0;
281}
282
283static void __net_exit ip6table_nat_net_exit(struct net *net)
284{
285 ip6t_unregister_table(net, net->ipv6.ip6table_nat);
286}
287
288static struct pernet_operations ip6table_nat_net_ops = {
289 .init = ip6table_nat_net_init,
290 .exit = ip6table_nat_net_exit,
291};
292
293static int __init ip6table_nat_init(void)
294{
295 int err;
296
297 err = register_pernet_subsys(&ip6table_nat_net_ops);
298 if (err < 0)
299 goto err1;
300
301 err = nf_register_hooks(nf_nat_ipv6_ops, ARRAY_SIZE(nf_nat_ipv6_ops));
302 if (err < 0)
303 goto err2;
304 return 0;
305
306err2:
307 unregister_pernet_subsys(&ip6table_nat_net_ops);
308err1:
309 return err;
310}
311
312static void __exit ip6table_nat_exit(void)
313{
314 nf_unregister_hooks(nf_nat_ipv6_ops, ARRAY_SIZE(nf_nat_ipv6_ops));
315 unregister_pernet_subsys(&ip6table_nat_net_ops);
316}
317
318module_init(ip6table_nat_init);
319module_exit(ip6table_nat_exit);
320
321MODULE_LICENSE("GPL");
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 5b9926a011bd..60d1bddff7a0 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -40,9 +40,7 @@ static int __net_init ip6table_raw_net_init(struct net *net)
40 net->ipv6.ip6table_raw = 40 net->ipv6.ip6table_raw =
41 ip6t_register_table(net, &packet_raw, repl); 41 ip6t_register_table(net, &packet_raw, repl);
42 kfree(repl); 42 kfree(repl);
43 if (IS_ERR(net->ipv6.ip6table_raw)) 43 return PTR_RET(net->ipv6.ip6table_raw);
44 return PTR_ERR(net->ipv6.ip6table_raw);
45 return 0;
46} 44}
47 45
48static void __net_exit ip6table_raw_net_exit(struct net *net) 46static void __net_exit ip6table_raw_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 91aa2b4d83c9..db155351339c 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -58,10 +58,7 @@ static int __net_init ip6table_security_net_init(struct net *net)
58 net->ipv6.ip6table_security = 58 net->ipv6.ip6table_security =
59 ip6t_register_table(net, &security_table, repl); 59 ip6t_register_table(net, &security_table, repl);
60 kfree(repl); 60 kfree(repl);
61 if (IS_ERR(net->ipv6.ip6table_security)) 61 return PTR_RET(net->ipv6.ip6table_security);
62 return PTR_ERR(net->ipv6.ip6table_security);
63
64 return 0;
65} 62}
66 63
67static void __net_exit ip6table_security_net_exit(struct net *net) 64static void __net_exit ip6table_security_net_exit(struct net *net)
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 4794f96cf2e0..8860d23e61cf 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -28,6 +28,7 @@
28#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
29#include <net/netfilter/nf_conntrack_zones.h> 29#include <net/netfilter/nf_conntrack_zones.h>
30#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 30#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
31#include <net/netfilter/nf_nat_helper.h>
31#include <net/netfilter/ipv6/nf_defrag_ipv6.h> 32#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
32#include <net/netfilter/nf_log.h> 33#include <net/netfilter/nf_log.h>
33 34
@@ -64,82 +65,31 @@ static int ipv6_print_tuple(struct seq_file *s,
64 tuple->src.u3.ip6, tuple->dst.u3.ip6); 65 tuple->src.u3.ip6, tuple->dst.u3.ip6);
65} 66}
66 67
67/*
68 * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
69 *
70 * This function parses (probably truncated) exthdr set "hdr"
71 * of length "len". "nexthdrp" initially points to some place,
72 * where type of the first header can be found.
73 *
74 * It skips all well-known exthdrs, and returns pointer to the start
75 * of unparsable area i.e. the first header with unknown type.
76 * if success, *nexthdr is updated by type/protocol of this header.
77 *
78 * NOTES: - it may return pointer pointing beyond end of packet,
79 * if the last recognized header is truncated in the middle.
80 * - if packet is truncated, so that all parsed headers are skipped,
81 * it returns -1.
82 * - if packet is fragmented, return pointer of the fragment header.
83 * - ESP is unparsable for now and considered like
84 * normal payload protocol.
85 * - Note also special handling of AUTH header. Thanks to IPsec wizards.
86 */
87
88static int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
89 u8 *nexthdrp, int len)
90{
91 u8 nexthdr = *nexthdrp;
92
93 while (ipv6_ext_hdr(nexthdr)) {
94 struct ipv6_opt_hdr hdr;
95 int hdrlen;
96
97 if (len < (int)sizeof(struct ipv6_opt_hdr))
98 return -1;
99 if (nexthdr == NEXTHDR_NONE)
100 break;
101 if (nexthdr == NEXTHDR_FRAGMENT)
102 break;
103 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
104 BUG();
105 if (nexthdr == NEXTHDR_AUTH)
106 hdrlen = (hdr.hdrlen+2)<<2;
107 else
108 hdrlen = ipv6_optlen(&hdr);
109
110 nexthdr = hdr.nexthdr;
111 len -= hdrlen;
112 start += hdrlen;
113 }
114
115 *nexthdrp = nexthdr;
116 return start;
117}
118
119static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 68static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
120 unsigned int *dataoff, u_int8_t *protonum) 69 unsigned int *dataoff, u_int8_t *protonum)
121{ 70{
122 unsigned int extoff = nhoff + sizeof(struct ipv6hdr); 71 unsigned int extoff = nhoff + sizeof(struct ipv6hdr);
123 unsigned char pnum; 72 __be16 frag_off;
124 int protoff; 73 int protoff;
74 u8 nexthdr;
125 75
126 if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr), 76 if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr),
127 &pnum, sizeof(pnum)) != 0) { 77 &nexthdr, sizeof(nexthdr)) != 0) {
128 pr_debug("ip6_conntrack_core: can't get nexthdr\n"); 78 pr_debug("ip6_conntrack_core: can't get nexthdr\n");
129 return -NF_ACCEPT; 79 return -NF_ACCEPT;
130 } 80 }
131 protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff); 81 protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off);
132 /* 82 /*
133 * (protoff == skb->len) mean that the packet doesn't have no data 83 * (protoff == skb->len) mean that the packet doesn't have no data
134 * except of IPv6 & ext headers. but it's tracked anyway. - YK 84 * except of IPv6 & ext headers. but it's tracked anyway. - YK
135 */ 85 */
136 if ((protoff < 0) || (protoff > skb->len)) { 86 if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
137 pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); 87 pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
138 return -NF_ACCEPT; 88 return -NF_ACCEPT;
139 } 89 }
140 90
141 *dataoff = protoff; 91 *dataoff = protoff;
142 *protonum = pnum; 92 *protonum = nexthdr;
143 return NF_ACCEPT; 93 return NF_ACCEPT;
144} 94}
145 95
@@ -153,10 +103,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,
153 const struct nf_conn_help *help; 103 const struct nf_conn_help *help;
154 const struct nf_conntrack_helper *helper; 104 const struct nf_conntrack_helper *helper;
155 enum ip_conntrack_info ctinfo; 105 enum ip_conntrack_info ctinfo;
156 unsigned int ret, protoff; 106 unsigned int ret;
157 unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data; 107 __be16 frag_off;
158 unsigned char pnum = ipv6_hdr(skb)->nexthdr; 108 int protoff;
159 109 u8 nexthdr;
160 110
161 /* This is where we call the helper: as the packet goes out. */ 111 /* This is where we call the helper: as the packet goes out. */
162 ct = nf_ct_get(skb, &ctinfo); 112 ct = nf_ct_get(skb, &ctinfo);
@@ -171,9 +121,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,
171 if (!helper) 121 if (!helper)
172 return NF_ACCEPT; 122 return NF_ACCEPT;
173 123
174 protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, 124 nexthdr = ipv6_hdr(skb)->nexthdr;
175 skb->len - extoff); 125 protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
176 if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) { 126 &frag_off);
127 if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
177 pr_debug("proto header not found\n"); 128 pr_debug("proto header not found\n");
178 return NF_ACCEPT; 129 return NF_ACCEPT;
179 } 130 }
@@ -192,6 +143,36 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
192 const struct net_device *out, 143 const struct net_device *out,
193 int (*okfn)(struct sk_buff *)) 144 int (*okfn)(struct sk_buff *))
194{ 145{
146 struct nf_conn *ct;
147 enum ip_conntrack_info ctinfo;
148 unsigned char pnum = ipv6_hdr(skb)->nexthdr;
149 int protoff;
150 __be16 frag_off;
151
152 ct = nf_ct_get(skb, &ctinfo);
153 if (!ct || ctinfo == IP_CT_RELATED_REPLY)
154 goto out;
155
156 protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,
157 &frag_off);
158 if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
159 pr_debug("proto header not found\n");
160 goto out;
161 }
162
163 /* adjust seqs for loopback traffic only in outgoing direction */
164 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
165 !nf_is_loopback_packet(skb)) {
166 typeof(nf_nat_seq_adjust_hook) seq_adjust;
167
168 seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook);
169 if (!seq_adjust ||
170 !seq_adjust(skb, ct, ctinfo, protoff)) {
171 NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
172 return NF_DROP;
173 }
174 }
175out:
195 /* We've seen it coming out the other side: confirm it */ 176 /* We've seen it coming out the other side: confirm it */
196 return nf_conntrack_confirm(skb); 177 return nf_conntrack_confirm(skb);
197} 178}
@@ -199,9 +180,14 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
199static unsigned int __ipv6_conntrack_in(struct net *net, 180static unsigned int __ipv6_conntrack_in(struct net *net,
200 unsigned int hooknum, 181 unsigned int hooknum,
201 struct sk_buff *skb, 182 struct sk_buff *skb,
183 const struct net_device *in,
184 const struct net_device *out,
202 int (*okfn)(struct sk_buff *)) 185 int (*okfn)(struct sk_buff *))
203{ 186{
204 struct sk_buff *reasm = skb->nfct_reasm; 187 struct sk_buff *reasm = skb->nfct_reasm;
188 const struct nf_conn_help *help;
189 struct nf_conn *ct;
190 enum ip_conntrack_info ctinfo;
205 191
206 /* This packet is fragmented and has reassembled packet. */ 192 /* This packet is fragmented and has reassembled packet. */
207 if (reasm) { 193 if (reasm) {
@@ -213,6 +199,25 @@ static unsigned int __ipv6_conntrack_in(struct net *net,
213 if (ret != NF_ACCEPT) 199 if (ret != NF_ACCEPT)
214 return ret; 200 return ret;
215 } 201 }
202
203 /* Conntrack helpers need the entire reassembled packet in the
204 * POST_ROUTING hook. In case of unconfirmed connections NAT
205 * might reassign a helper, so the entire packet is also
206 * required.
207 */
208 ct = nf_ct_get(reasm, &ctinfo);
209 if (ct != NULL && !nf_ct_is_untracked(ct)) {
210 help = nfct_help(ct);
211 if ((help && help->helper) || !nf_ct_is_confirmed(ct)) {
212 nf_conntrack_get_reasm(skb);
213 NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
214 (struct net_device *)in,
215 (struct net_device *)out,
216 okfn, NF_IP6_PRI_CONNTRACK + 1);
217 return NF_DROP_ERR(-ECANCELED);
218 }
219 }
220
216 nf_conntrack_get(reasm->nfct); 221 nf_conntrack_get(reasm->nfct);
217 skb->nfct = reasm->nfct; 222 skb->nfct = reasm->nfct;
218 skb->nfctinfo = reasm->nfctinfo; 223 skb->nfctinfo = reasm->nfctinfo;
@@ -228,7 +233,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
228 const struct net_device *out, 233 const struct net_device *out,
229 int (*okfn)(struct sk_buff *)) 234 int (*okfn)(struct sk_buff *))
230{ 235{
231 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn); 236 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
232} 237}
233 238
234static unsigned int ipv6_conntrack_local(unsigned int hooknum, 239static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -242,7 +247,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
242 net_notice_ratelimited("ipv6_conntrack_local: packet too short\n"); 247 net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
243 return NF_ACCEPT; 248 return NF_ACCEPT;
244 } 249 }
245 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn); 250 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
246} 251}
247 252
248static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { 253static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c9c78c2e666b..f94fb3ac2a79 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -190,6 +190,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
190 const struct frag_hdr *fhdr, int nhoff) 190 const struct frag_hdr *fhdr, int nhoff)
191{ 191{
192 struct sk_buff *prev, *next; 192 struct sk_buff *prev, *next;
193 unsigned int payload_len;
193 int offset, end; 194 int offset, end;
194 195
195 if (fq->q.last_in & INET_FRAG_COMPLETE) { 196 if (fq->q.last_in & INET_FRAG_COMPLETE) {
@@ -197,8 +198,10 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
197 goto err; 198 goto err;
198 } 199 }
199 200
201 payload_len = ntohs(ipv6_hdr(skb)->payload_len);
202
200 offset = ntohs(fhdr->frag_off) & ~0x7; 203 offset = ntohs(fhdr->frag_off) & ~0x7;
201 end = offset + (ntohs(ipv6_hdr(skb)->payload_len) - 204 end = offset + (payload_len -
202 ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); 205 ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
203 206
204 if ((unsigned int)end > IPV6_MAXPLEN) { 207 if ((unsigned int)end > IPV6_MAXPLEN) {
@@ -307,6 +310,8 @@ found:
307 skb->dev = NULL; 310 skb->dev = NULL;
308 fq->q.stamp = skb->tstamp; 311 fq->q.stamp = skb->tstamp;
309 fq->q.meat += skb->len; 312 fq->q.meat += skb->len;
313 if (payload_len > fq->q.max_size)
314 fq->q.max_size = payload_len;
310 atomic_add(skb->truesize, &nf_init_frags.mem); 315 atomic_add(skb->truesize, &nf_init_frags.mem);
311 316
312 /* The first fragment. 317 /* The first fragment.
@@ -412,10 +417,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
412 } 417 }
413 atomic_sub(head->truesize, &nf_init_frags.mem); 418 atomic_sub(head->truesize, &nf_init_frags.mem);
414 419
420 head->local_df = 1;
415 head->next = NULL; 421 head->next = NULL;
416 head->dev = dev; 422 head->dev = dev;
417 head->tstamp = fq->q.stamp; 423 head->tstamp = fq->q.stamp;
418 ipv6_hdr(head)->payload_len = htons(payload_len); 424 ipv6_hdr(head)->payload_len = htons(payload_len);
425 IP6CB(head)->frag_max_size = sizeof(struct ipv6hdr) + fq->q.max_size;
419 426
420 /* Yes, and fold redundant checksum back. 8) */ 427 /* Yes, and fold redundant checksum back. 8) */
421 if (head->ip_summed == CHECKSUM_COMPLETE) 428 if (head->ip_summed == CHECKSUM_COMPLETE)
@@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
592 int (*okfn)(struct sk_buff *)) 599 int (*okfn)(struct sk_buff *))
593{ 600{
594 struct sk_buff *s, *s2; 601 struct sk_buff *s, *s2;
602 unsigned int ret = 0;
595 603
596 for (s = NFCT_FRAG6_CB(skb)->orig; s;) { 604 for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
597 nf_conntrack_put_reasm(s->nfct_reasm); 605 nf_conntrack_put_reasm(s->nfct_reasm);
@@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
601 s2 = s->next; 609 s2 = s->next;
602 s->next = NULL; 610 s->next = NULL;
603 611
604 NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s, in, out, okfn, 612 if (ret != -ECANCELED)
605 NF_IP6_PRI_CONNTRACK_DEFRAG + 1); 613 ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
614 in, out, okfn,
615 NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
616 else
617 kfree_skb(s);
618
606 s = s2; 619 s = s2;
607 } 620 }
608 nf_conntrack_put_reasm(skb); 621 nf_conntrack_put_reasm(skb);
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
new file mode 100644
index 000000000000..abfe75a2e316
--- /dev/null
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -0,0 +1,288 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Development of IPv6 NAT funded by Astaro.
9 */
10#include <linux/types.h>
11#include <linux/module.h>
12#include <linux/skbuff.h>
13#include <linux/ipv6.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter_ipv6.h>
16#include <net/secure_seq.h>
17#include <net/checksum.h>
18#include <net/ip6_checksum.h>
19#include <net/ip6_route.h>
20#include <net/ipv6.h>
21
22#include <net/netfilter/nf_conntrack_core.h>
23#include <net/netfilter/nf_conntrack.h>
24#include <net/netfilter/nf_nat_core.h>
25#include <net/netfilter/nf_nat_l3proto.h>
26#include <net/netfilter/nf_nat_l4proto.h>
27
28static const struct nf_nat_l3proto nf_nat_l3proto_ipv6;
29
30#ifdef CONFIG_XFRM
31static void nf_nat_ipv6_decode_session(struct sk_buff *skb,
32 const struct nf_conn *ct,
33 enum ip_conntrack_dir dir,
34 unsigned long statusbit,
35 struct flowi *fl)
36{
37 const struct nf_conntrack_tuple *t = &ct->tuplehash[dir].tuple;
38 struct flowi6 *fl6 = &fl->u.ip6;
39
40 if (ct->status & statusbit) {
41 fl6->daddr = t->dst.u3.in6;
42 if (t->dst.protonum == IPPROTO_TCP ||
43 t->dst.protonum == IPPROTO_UDP ||
44 t->dst.protonum == IPPROTO_UDPLITE ||
45 t->dst.protonum == IPPROTO_DCCP ||
46 t->dst.protonum == IPPROTO_SCTP)
47 fl6->fl6_dport = t->dst.u.all;
48 }
49
50 statusbit ^= IPS_NAT_MASK;
51
52 if (ct->status & statusbit) {
53 fl6->saddr = t->src.u3.in6;
54 if (t->dst.protonum == IPPROTO_TCP ||
55 t->dst.protonum == IPPROTO_UDP ||
56 t->dst.protonum == IPPROTO_UDPLITE ||
57 t->dst.protonum == IPPROTO_DCCP ||
58 t->dst.protonum == IPPROTO_SCTP)
59 fl6->fl6_sport = t->src.u.all;
60 }
61}
62#endif
63
64static bool nf_nat_ipv6_in_range(const struct nf_conntrack_tuple *t,
65 const struct nf_nat_range *range)
66{
67 return ipv6_addr_cmp(&t->src.u3.in6, &range->min_addr.in6) >= 0 &&
68 ipv6_addr_cmp(&t->src.u3.in6, &range->max_addr.in6) <= 0;
69}
70
71static u32 nf_nat_ipv6_secure_port(const struct nf_conntrack_tuple *t,
72 __be16 dport)
73{
74 return secure_ipv6_port_ephemeral(t->src.u3.ip6, t->dst.u3.ip6, dport);
75}
76
77static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
78 unsigned int iphdroff,
79 const struct nf_nat_l4proto *l4proto,
80 const struct nf_conntrack_tuple *target,
81 enum nf_nat_manip_type maniptype)
82{
83 struct ipv6hdr *ipv6h;
84 __be16 frag_off;
85 int hdroff;
86 u8 nexthdr;
87
88 if (!skb_make_writable(skb, iphdroff + sizeof(*ipv6h)))
89 return false;
90
91 ipv6h = (void *)skb->data + iphdroff;
92 nexthdr = ipv6h->nexthdr;
93 hdroff = ipv6_skip_exthdr(skb, iphdroff + sizeof(*ipv6h),
94 &nexthdr, &frag_off);
95 if (hdroff < 0)
96 goto manip_addr;
97
98 if ((frag_off & htons(~0x7)) == 0 &&
99 !l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff,
100 target, maniptype))
101 return false;
102manip_addr:
103 if (maniptype == NF_NAT_MANIP_SRC)
104 ipv6h->saddr = target->src.u3.in6;
105 else
106 ipv6h->daddr = target->dst.u3.in6;
107
108 return true;
109}
110
111static void nf_nat_ipv6_csum_update(struct sk_buff *skb,
112 unsigned int iphdroff, __sum16 *check,
113 const struct nf_conntrack_tuple *t,
114 enum nf_nat_manip_type maniptype)
115{
116 const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + iphdroff);
117 const struct in6_addr *oldip, *newip;
118
119 if (maniptype == NF_NAT_MANIP_SRC) {
120 oldip = &ipv6h->saddr;
121 newip = &t->src.u3.in6;
122 } else {
123 oldip = &ipv6h->daddr;
124 newip = &t->dst.u3.in6;
125 }
126 inet_proto_csum_replace16(check, skb, oldip->s6_addr32,
127 newip->s6_addr32, 1);
128}
129
130static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
131 u8 proto, void *data, __sum16 *check,
132 int datalen, int oldlen)
133{
134 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
135 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
136
137 if (skb->ip_summed != CHECKSUM_PARTIAL) {
138 if (!(rt->rt6i_flags & RTF_LOCAL) &&
139 (!skb->dev || skb->dev->features & NETIF_F_V6_CSUM)) {
140 skb->ip_summed = CHECKSUM_PARTIAL;
141 skb->csum_start = skb_headroom(skb) +
142 skb_network_offset(skb) +
143 (data - (void *)skb->data);
144 skb->csum_offset = (void *)check - data;
145 *check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
146 datalen, proto, 0);
147 } else {
148 *check = 0;
149 *check = csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
150 datalen, proto,
151 csum_partial(data, datalen,
152 0));
153 if (proto == IPPROTO_UDP && !*check)
154 *check = CSUM_MANGLED_0;
155 }
156 } else
157 inet_proto_csum_replace2(check, skb,
158 htons(oldlen), htons(datalen), 1);
159}
160
161static int nf_nat_ipv6_nlattr_to_range(struct nlattr *tb[],
162 struct nf_nat_range *range)
163{
164 if (tb[CTA_NAT_V6_MINIP]) {
165 nla_memcpy(&range->min_addr.ip6, tb[CTA_NAT_V6_MINIP],
166 sizeof(struct in6_addr));
167 range->flags |= NF_NAT_RANGE_MAP_IPS;
168 }
169
170 if (tb[CTA_NAT_V6_MAXIP])
171 nla_memcpy(&range->max_addr.ip6, tb[CTA_NAT_V6_MAXIP],
172 sizeof(struct in6_addr));
173 else
174 range->max_addr = range->min_addr;
175
176 return 0;
177}
178
179static const struct nf_nat_l3proto nf_nat_l3proto_ipv6 = {
180 .l3proto = NFPROTO_IPV6,
181 .secure_port = nf_nat_ipv6_secure_port,
182 .in_range = nf_nat_ipv6_in_range,
183 .manip_pkt = nf_nat_ipv6_manip_pkt,
184 .csum_update = nf_nat_ipv6_csum_update,
185 .csum_recalc = nf_nat_ipv6_csum_recalc,
186 .nlattr_to_range = nf_nat_ipv6_nlattr_to_range,
187#ifdef CONFIG_XFRM
188 .decode_session = nf_nat_ipv6_decode_session,
189#endif
190};
191
192int nf_nat_icmpv6_reply_translation(struct sk_buff *skb,
193 struct nf_conn *ct,
194 enum ip_conntrack_info ctinfo,
195 unsigned int hooknum,
196 unsigned int hdrlen)
197{
198 struct {
199 struct icmp6hdr icmp6;
200 struct ipv6hdr ip6;
201 } *inside;
202 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
203 enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
204 const struct nf_nat_l4proto *l4proto;
205 struct nf_conntrack_tuple target;
206 unsigned long statusbit;
207
208 NF_CT_ASSERT(ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY);
209
210 if (!skb_make_writable(skb, hdrlen + sizeof(*inside)))
211 return 0;
212 if (nf_ip6_checksum(skb, hooknum, hdrlen, IPPROTO_ICMPV6))
213 return 0;
214
215 inside = (void *)skb->data + hdrlen;
216 if (inside->icmp6.icmp6_type == NDISC_REDIRECT) {
217 if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
218 return 0;
219 if (ct->status & IPS_NAT_MASK)
220 return 0;
221 }
222
223 if (manip == NF_NAT_MANIP_SRC)
224 statusbit = IPS_SRC_NAT;
225 else
226 statusbit = IPS_DST_NAT;
227
228 /* Invert if this is reply direction */
229 if (dir == IP_CT_DIR_REPLY)
230 statusbit ^= IPS_NAT_MASK;
231
232 if (!(ct->status & statusbit))
233 return 1;
234
235 l4proto = __nf_nat_l4proto_find(NFPROTO_IPV6, inside->ip6.nexthdr);
236 if (!nf_nat_ipv6_manip_pkt(skb, hdrlen + sizeof(inside->icmp6),
237 l4proto, &ct->tuplehash[!dir].tuple, !manip))
238 return 0;
239
240 if (skb->ip_summed != CHECKSUM_PARTIAL) {
241 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
242 inside = (void *)skb->data + hdrlen;
243 inside->icmp6.icmp6_cksum = 0;
244 inside->icmp6.icmp6_cksum =
245 csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
246 skb->len - hdrlen, IPPROTO_ICMPV6,
247 csum_partial(&inside->icmp6,
248 skb->len - hdrlen, 0));
249 }
250
251 nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
252 l4proto = __nf_nat_l4proto_find(NFPROTO_IPV6, IPPROTO_ICMPV6);
253 if (!nf_nat_ipv6_manip_pkt(skb, 0, l4proto, &target, manip))
254 return 0;
255
256 return 1;
257}
258EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation);
259
260static int __init nf_nat_l3proto_ipv6_init(void)
261{
262 int err;
263
264 err = nf_nat_l4proto_register(NFPROTO_IPV6, &nf_nat_l4proto_icmpv6);
265 if (err < 0)
266 goto err1;
267 err = nf_nat_l3proto_register(&nf_nat_l3proto_ipv6);
268 if (err < 0)
269 goto err2;
270 return err;
271
272err2:
273 nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_icmpv6);
274err1:
275 return err;
276}
277
278static void __exit nf_nat_l3proto_ipv6_exit(void)
279{
280 nf_nat_l3proto_unregister(&nf_nat_l3proto_ipv6);
281 nf_nat_l4proto_unregister(NFPROTO_IPV6, &nf_nat_l4proto_icmpv6);
282}
283
284MODULE_LICENSE("GPL");
285MODULE_ALIAS("nf-nat-" __stringify(AF_INET6));
286
287module_init(nf_nat_l3proto_ipv6_init);
288module_exit(nf_nat_l3proto_ipv6_exit);
diff --git a/net/ipv6/netfilter/nf_nat_proto_icmpv6.c b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c
new file mode 100644
index 000000000000..5d6da784305b
--- /dev/null
+++ b/net/ipv6/netfilter/nf_nat_proto_icmpv6.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2011 Patrick Mchardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on Rusty Russell's IPv4 ICMP NAT code. Development of IPv6
9 * NAT funded by Astaro.
10 */
11
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/icmpv6.h>
15
16#include <linux/netfilter.h>
17#include <net/netfilter/nf_nat.h>
18#include <net/netfilter/nf_nat_core.h>
19#include <net/netfilter/nf_nat_l3proto.h>
20#include <net/netfilter/nf_nat_l4proto.h>
21
22static bool
23icmpv6_in_range(const struct nf_conntrack_tuple *tuple,
24 enum nf_nat_manip_type maniptype,
25 const union nf_conntrack_man_proto *min,
26 const union nf_conntrack_man_proto *max)
27{
28 return ntohs(tuple->src.u.icmp.id) >= ntohs(min->icmp.id) &&
29 ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id);
30}
31
32static void
33icmpv6_unique_tuple(const struct nf_nat_l3proto *l3proto,
34 struct nf_conntrack_tuple *tuple,
35 const struct nf_nat_range *range,
36 enum nf_nat_manip_type maniptype,
37 const struct nf_conn *ct)
38{
39 static u16 id;
40 unsigned int range_size;
41 unsigned int i;
42
43 range_size = ntohs(range->max_proto.icmp.id) -
44 ntohs(range->min_proto.icmp.id) + 1;
45
46 if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED))
47 range_size = 0xffff;
48
49 for (i = 0; ; ++id) {
50 tuple->src.u.icmp.id = htons(ntohs(range->min_proto.icmp.id) +
51 (id % range_size));
52 if (++i == range_size || !nf_nat_used_tuple(tuple, ct))
53 return;
54 }
55}
56
57static bool
58icmpv6_manip_pkt(struct sk_buff *skb,
59 const struct nf_nat_l3proto *l3proto,
60 unsigned int iphdroff, unsigned int hdroff,
61 const struct nf_conntrack_tuple *tuple,
62 enum nf_nat_manip_type maniptype)
63{
64 struct icmp6hdr *hdr;
65
66 if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
67 return false;
68
69 hdr = (struct icmp6hdr *)(skb->data + hdroff);
70 l3proto->csum_update(skb, iphdroff, &hdr->icmp6_cksum,
71 tuple, maniptype);
72 if (hdr->icmp6_code == ICMPV6_ECHO_REQUEST ||
73 hdr->icmp6_code == ICMPV6_ECHO_REPLY) {
74 inet_proto_csum_replace2(&hdr->icmp6_cksum, skb,
75 hdr->icmp6_identifier,
76 tuple->src.u.icmp.id, 0);
77 hdr->icmp6_identifier = tuple->src.u.icmp.id;
78 }
79 return true;
80}
81
82const struct nf_nat_l4proto nf_nat_l4proto_icmpv6 = {
83 .l4proto = IPPROTO_ICMPV6,
84 .manip_pkt = icmpv6_manip_pkt,
85 .in_range = icmpv6_in_range,
86 .unique_tuple = icmpv6_unique_tuple,
87#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
88 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
89#endif
90};
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ef0579d5bca6..7af88ef01657 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1251,7 +1251,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1251 sk_wmem_alloc_get(sp), 1251 sk_wmem_alloc_get(sp),
1252 sk_rmem_alloc_get(sp), 1252 sk_rmem_alloc_get(sp),
1253 0, 0L, 0, 1253 0, 0L, 0,
1254 sock_i_uid(sp), 0, 1254 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1255 0,
1255 sock_i_ino(sp), 1256 sock_i_ino(sp),
1256 atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); 1257 atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
1257} 1258}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8e80fd279100..83dafa528936 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -222,7 +222,7 @@ static const u32 ip6_template_metrics[RTAX_MAX] = {
222 [RTAX_HOPLIMIT - 1] = 255, 222 [RTAX_HOPLIMIT - 1] = 255,
223}; 223};
224 224
225static struct rt6_info ip6_null_entry_template = { 225static const struct rt6_info ip6_null_entry_template = {
226 .dst = { 226 .dst = {
227 .__refcnt = ATOMIC_INIT(1), 227 .__refcnt = ATOMIC_INIT(1),
228 .__use = 1, 228 .__use = 1,
@@ -242,7 +242,7 @@ static struct rt6_info ip6_null_entry_template = {
242static int ip6_pkt_prohibit(struct sk_buff *skb); 242static int ip6_pkt_prohibit(struct sk_buff *skb);
243static int ip6_pkt_prohibit_out(struct sk_buff *skb); 243static int ip6_pkt_prohibit_out(struct sk_buff *skb);
244 244
245static struct rt6_info ip6_prohibit_entry_template = { 245static const struct rt6_info ip6_prohibit_entry_template = {
246 .dst = { 246 .dst = {
247 .__refcnt = ATOMIC_INIT(1), 247 .__refcnt = ATOMIC_INIT(1),
248 .__use = 1, 248 .__use = 1,
@@ -257,7 +257,7 @@ static struct rt6_info ip6_prohibit_entry_template = {
257 .rt6i_ref = ATOMIC_INIT(1), 257 .rt6i_ref = ATOMIC_INIT(1),
258}; 258};
259 259
260static struct rt6_info ip6_blk_hole_entry_template = { 260static const struct rt6_info ip6_blk_hole_entry_template = {
261 .dst = { 261 .dst = {
262 .__refcnt = ATOMIC_INIT(1), 262 .__refcnt = ATOMIC_INIT(1),
263 .__use = 1, 263 .__use = 1,
@@ -451,10 +451,9 @@ static void rt6_probe(struct rt6_info *rt)
451 * Router Reachability Probe MUST be rate-limited 451 * Router Reachability Probe MUST be rate-limited
452 * to no more than one per minute. 452 * to no more than one per minute.
453 */ 453 */
454 rcu_read_lock();
455 neigh = rt ? rt->n : NULL; 454 neigh = rt ? rt->n : NULL;
456 if (!neigh || (neigh->nud_state & NUD_VALID)) 455 if (!neigh || (neigh->nud_state & NUD_VALID))
457 goto out; 456 return;
458 read_lock_bh(&neigh->lock); 457 read_lock_bh(&neigh->lock);
459 if (!(neigh->nud_state & NUD_VALID) && 458 if (!(neigh->nud_state & NUD_VALID) &&
460 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { 459 time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
@@ -470,8 +469,6 @@ static void rt6_probe(struct rt6_info *rt)
470 } else { 469 } else {
471 read_unlock_bh(&neigh->lock); 470 read_unlock_bh(&neigh->lock);
472 } 471 }
473out:
474 rcu_read_unlock();
475} 472}
476#else 473#else
477static inline void rt6_probe(struct rt6_info *rt) 474static inline void rt6_probe(struct rt6_info *rt)
@@ -498,7 +495,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
498 struct neighbour *neigh; 495 struct neighbour *neigh;
499 int m; 496 int m;
500 497
501 rcu_read_lock();
502 neigh = rt->n; 498 neigh = rt->n;
503 if (rt->rt6i_flags & RTF_NONEXTHOP || 499 if (rt->rt6i_flags & RTF_NONEXTHOP ||
504 !(rt->rt6i_flags & RTF_GATEWAY)) 500 !(rt->rt6i_flags & RTF_GATEWAY))
@@ -516,7 +512,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
516 read_unlock_bh(&neigh->lock); 512 read_unlock_bh(&neigh->lock);
517 } else 513 } else
518 m = 0; 514 m = 0;
519 rcu_read_unlock();
520 return m; 515 return m;
521} 516}
522 517
@@ -965,7 +960,7 @@ struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,
965{ 960{
966 int flags = 0; 961 int flags = 0;
967 962
968 fl6->flowi6_iif = net->loopback_dev->ifindex; 963 fl6->flowi6_iif = LOOPBACK_IFINDEX;
969 964
970 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) 965 if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr))
971 flags |= RT6_LOOKUP_F_IFACE; 966 flags |= RT6_LOOKUP_F_IFACE;
@@ -1463,8 +1458,21 @@ int ip6_route_add(struct fib6_config *cfg)
1463 } 1458 }
1464 rt->dst.output = ip6_pkt_discard_out; 1459 rt->dst.output = ip6_pkt_discard_out;
1465 rt->dst.input = ip6_pkt_discard; 1460 rt->dst.input = ip6_pkt_discard;
1466 rt->dst.error = -ENETUNREACH;
1467 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; 1461 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
1462 switch (cfg->fc_type) {
1463 case RTN_BLACKHOLE:
1464 rt->dst.error = -EINVAL;
1465 break;
1466 case RTN_PROHIBIT:
1467 rt->dst.error = -EACCES;
1468 break;
1469 case RTN_THROW:
1470 rt->dst.error = -EAGAIN;
1471 break;
1472 default:
1473 rt->dst.error = -ENETUNREACH;
1474 break;
1475 }
1468 goto install_route; 1476 goto install_route;
1469 } 1477 }
1470 1478
@@ -1829,7 +1837,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
1829 if (!table) 1837 if (!table)
1830 return NULL; 1838 return NULL;
1831 1839
1832 write_lock_bh(&table->tb6_lock); 1840 read_lock_bh(&table->tb6_lock);
1833 fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0); 1841 fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0);
1834 if (!fn) 1842 if (!fn)
1835 goto out; 1843 goto out;
@@ -1845,7 +1853,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
1845 break; 1853 break;
1846 } 1854 }
1847out: 1855out:
1848 write_unlock_bh(&table->tb6_lock); 1856 read_unlock_bh(&table->tb6_lock);
1849 return rt; 1857 return rt;
1850} 1858}
1851 1859
@@ -1861,7 +1869,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
1861 .fc_dst_len = prefixlen, 1869 .fc_dst_len = prefixlen,
1862 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | 1870 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
1863 RTF_UP | RTF_PREF(pref), 1871 RTF_UP | RTF_PREF(pref),
1864 .fc_nlinfo.pid = 0, 1872 .fc_nlinfo.portid = 0,
1865 .fc_nlinfo.nlh = NULL, 1873 .fc_nlinfo.nlh = NULL,
1866 .fc_nlinfo.nl_net = net, 1874 .fc_nlinfo.nl_net = net,
1867 }; 1875 };
@@ -1888,7 +1896,7 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev
1888 if (!table) 1896 if (!table)
1889 return NULL; 1897 return NULL;
1890 1898
1891 write_lock_bh(&table->tb6_lock); 1899 read_lock_bh(&table->tb6_lock);
1892 for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) { 1900 for (rt = table->tb6_root.leaf; rt; rt=rt->dst.rt6_next) {
1893 if (dev == rt->dst.dev && 1901 if (dev == rt->dst.dev &&
1894 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && 1902 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
@@ -1897,7 +1905,7 @@ struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_dev
1897 } 1905 }
1898 if (rt) 1906 if (rt)
1899 dst_hold(&rt->dst); 1907 dst_hold(&rt->dst);
1900 write_unlock_bh(&table->tb6_lock); 1908 read_unlock_bh(&table->tb6_lock);
1901 return rt; 1909 return rt;
1902} 1910}
1903 1911
@@ -1911,7 +1919,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
1911 .fc_ifindex = dev->ifindex, 1919 .fc_ifindex = dev->ifindex,
1912 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | 1920 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
1913 RTF_UP | RTF_EXPIRES | RTF_PREF(pref), 1921 RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
1914 .fc_nlinfo.pid = 0, 1922 .fc_nlinfo.portid = 0,
1915 .fc_nlinfo.nlh = NULL, 1923 .fc_nlinfo.nlh = NULL,
1916 .fc_nlinfo.nl_net = dev_net(dev), 1924 .fc_nlinfo.nl_net = dev_net(dev),
1917 }; 1925 };
@@ -2261,14 +2269,18 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
2261 cfg->fc_src_len = rtm->rtm_src_len; 2269 cfg->fc_src_len = rtm->rtm_src_len;
2262 cfg->fc_flags = RTF_UP; 2270 cfg->fc_flags = RTF_UP;
2263 cfg->fc_protocol = rtm->rtm_protocol; 2271 cfg->fc_protocol = rtm->rtm_protocol;
2272 cfg->fc_type = rtm->rtm_type;
2264 2273
2265 if (rtm->rtm_type == RTN_UNREACHABLE) 2274 if (rtm->rtm_type == RTN_UNREACHABLE ||
2275 rtm->rtm_type == RTN_BLACKHOLE ||
2276 rtm->rtm_type == RTN_PROHIBIT ||
2277 rtm->rtm_type == RTN_THROW)
2266 cfg->fc_flags |= RTF_REJECT; 2278 cfg->fc_flags |= RTF_REJECT;
2267 2279
2268 if (rtm->rtm_type == RTN_LOCAL) 2280 if (rtm->rtm_type == RTN_LOCAL)
2269 cfg->fc_flags |= RTF_LOCAL; 2281 cfg->fc_flags |= RTF_LOCAL;
2270 2282
2271 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; 2283 cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
2272 cfg->fc_nlinfo.nlh = nlh; 2284 cfg->fc_nlinfo.nlh = nlh;
2273 cfg->fc_nlinfo.nl_net = sock_net(skb->sk); 2285 cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
2274 2286
@@ -2359,7 +2371,7 @@ static inline size_t rt6_nlmsg_size(void)
2359static int rt6_fill_node(struct net *net, 2371static int rt6_fill_node(struct net *net,
2360 struct sk_buff *skb, struct rt6_info *rt, 2372 struct sk_buff *skb, struct rt6_info *rt,
2361 struct in6_addr *dst, struct in6_addr *src, 2373 struct in6_addr *dst, struct in6_addr *src,
2362 int iif, int type, u32 pid, u32 seq, 2374 int iif, int type, u32 portid, u32 seq,
2363 int prefix, int nowait, unsigned int flags) 2375 int prefix, int nowait, unsigned int flags)
2364{ 2376{
2365 struct rtmsg *rtm; 2377 struct rtmsg *rtm;
@@ -2375,7 +2387,7 @@ static int rt6_fill_node(struct net *net,
2375 } 2387 }
2376 } 2388 }
2377 2389
2378 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags); 2390 nlh = nlmsg_put(skb, portid, seq, type, sizeof(*rtm), flags);
2379 if (!nlh) 2391 if (!nlh)
2380 return -EMSGSIZE; 2392 return -EMSGSIZE;
2381 2393
@@ -2391,8 +2403,22 @@ static int rt6_fill_node(struct net *net,
2391 rtm->rtm_table = table; 2403 rtm->rtm_table = table;
2392 if (nla_put_u32(skb, RTA_TABLE, table)) 2404 if (nla_put_u32(skb, RTA_TABLE, table))
2393 goto nla_put_failure; 2405 goto nla_put_failure;
2394 if (rt->rt6i_flags & RTF_REJECT) 2406 if (rt->rt6i_flags & RTF_REJECT) {
2395 rtm->rtm_type = RTN_UNREACHABLE; 2407 switch (rt->dst.error) {
2408 case -EINVAL:
2409 rtm->rtm_type = RTN_BLACKHOLE;
2410 break;
2411 case -EACCES:
2412 rtm->rtm_type = RTN_PROHIBIT;
2413 break;
2414 case -EAGAIN:
2415 rtm->rtm_type = RTN_THROW;
2416 break;
2417 default:
2418 rtm->rtm_type = RTN_UNREACHABLE;
2419 break;
2420 }
2421 }
2396 else if (rt->rt6i_flags & RTF_LOCAL) 2422 else if (rt->rt6i_flags & RTF_LOCAL)
2397 rtm->rtm_type = RTN_LOCAL; 2423 rtm->rtm_type = RTN_LOCAL;
2398 else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) 2424 else if (rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK))
@@ -2465,15 +2491,11 @@ static int rt6_fill_node(struct net *net,
2465 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) 2491 if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
2466 goto nla_put_failure; 2492 goto nla_put_failure;
2467 2493
2468 rcu_read_lock();
2469 n = rt->n; 2494 n = rt->n;
2470 if (n) { 2495 if (n) {
2471 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0) { 2496 if (nla_put(skb, RTA_GATEWAY, 16, &n->primary_key) < 0)
2472 rcu_read_unlock();
2473 goto nla_put_failure; 2497 goto nla_put_failure;
2474 }
2475 } 2498 }
2476 rcu_read_unlock();
2477 2499
2478 if (rt->dst.dev && 2500 if (rt->dst.dev &&
2479 nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) 2501 nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
@@ -2506,7 +2528,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
2506 2528
2507 return rt6_fill_node(arg->net, 2529 return rt6_fill_node(arg->net,
2508 arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, 2530 arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
2509 NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, 2531 NETLINK_CB(arg->cb->skb).portid, arg->cb->nlh->nlmsg_seq,
2510 prefix, 0, NLM_F_MULTI); 2532 prefix, 0, NLM_F_MULTI);
2511} 2533}
2512 2534
@@ -2586,14 +2608,14 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2586 skb_dst_set(skb, &rt->dst); 2608 skb_dst_set(skb, &rt->dst);
2587 2609
2588 err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, 2610 err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif,
2589 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2611 RTM_NEWROUTE, NETLINK_CB(in_skb).portid,
2590 nlh->nlmsg_seq, 0, 0, 0); 2612 nlh->nlmsg_seq, 0, 0, 0);
2591 if (err < 0) { 2613 if (err < 0) {
2592 kfree_skb(skb); 2614 kfree_skb(skb);
2593 goto errout; 2615 goto errout;
2594 } 2616 }
2595 2617
2596 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 2618 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
2597errout: 2619errout:
2598 return err; 2620 return err;
2599} 2621}
@@ -2613,14 +2635,14 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2613 goto errout; 2635 goto errout;
2614 2636
2615 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, 2637 err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
2616 event, info->pid, seq, 0, 0, 0); 2638 event, info->portid, seq, 0, 0, 0);
2617 if (err < 0) { 2639 if (err < 0) {
2618 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ 2640 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
2619 WARN_ON(err == -EMSGSIZE); 2641 WARN_ON(err == -EMSGSIZE);
2620 kfree_skb(skb); 2642 kfree_skb(skb);
2621 goto errout; 2643 goto errout;
2622 } 2644 }
2623 rtnl_notify(skb, net, info->pid, RTNLGRP_IPV6_ROUTE, 2645 rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
2624 info->nlh, gfp_any()); 2646 info->nlh, gfp_any());
2625 return; 2647 return;
2626errout: 2648errout:
@@ -2675,14 +2697,12 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2675#else 2697#else
2676 seq_puts(m, "00000000000000000000000000000000 00 "); 2698 seq_puts(m, "00000000000000000000000000000000 00 ");
2677#endif 2699#endif
2678 rcu_read_lock();
2679 n = rt->n; 2700 n = rt->n;
2680 if (n) { 2701 if (n) {
2681 seq_printf(m, "%pi6", n->primary_key); 2702 seq_printf(m, "%pi6", n->primary_key);
2682 } else { 2703 } else {
2683 seq_puts(m, "00000000000000000000000000000000"); 2704 seq_puts(m, "00000000000000000000000000000000");
2684 } 2705 }
2685 rcu_read_unlock();
2686 seq_printf(m, " %08x %08x %08x %08x %8s\n", 2706 seq_printf(m, " %08x %08x %08x %08x %8s\n",
2687 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), 2707 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
2688 rt->dst.__use, rt->rt6i_flags, 2708 rt->dst.__use, rt->rt6i_flags,
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index bb46061c813a..182ab9a85d6c 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -190,6 +190,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
190 ireq = inet_rsk(req); 190 ireq = inet_rsk(req);
191 ireq6 = inet6_rsk(req); 191 ireq6 = inet6_rsk(req);
192 treq = tcp_rsk(req); 192 treq = tcp_rsk(req);
193 treq->listener = NULL;
193 194
194 if (security_inet_conn_request(sk, skb, req)) 195 if (security_inet_conn_request(sk, skb, req))
195 goto out_free; 196 goto out_free;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index acd32e3f1b68..f3bfb8bbfdec 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -476,7 +476,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
476 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) 476 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
477 goto done; 477 goto done;
478 478
479 skb = tcp_make_synack(sk, dst, req, rvp); 479 skb = tcp_make_synack(sk, dst, req, rvp, NULL);
480 480
481 if (skb) { 481 if (skb) {
482 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); 482 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
@@ -988,7 +988,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
988 &ipv6_hdr(skb)->saddr, 988 &ipv6_hdr(skb)->saddr,
989 &ipv6_hdr(skb)->daddr, inet6_iif(skb)); 989 &ipv6_hdr(skb)->daddr, inet6_iif(skb));
990 if (req) 990 if (req)
991 return tcp_check_req(sk, skb, req, prev); 991 return tcp_check_req(sk, skb, req, prev, false);
992 992
993 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, 993 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
994 &ipv6_hdr(skb)->saddr, th->source, 994 &ipv6_hdr(skb)->saddr, th->source,
@@ -1180,6 +1180,7 @@ have_isn:
1180 want_cookie) 1180 want_cookie)
1181 goto drop_and_free; 1181 goto drop_and_free;
1182 1182
1183 tcp_rsk(req)->listener = NULL;
1183 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1184 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1184 return 0; 1185 return 0;
1185 1186
@@ -1829,7 +1830,7 @@ static void tcp_v6_destroy_sock(struct sock *sk)
1829#ifdef CONFIG_PROC_FS 1830#ifdef CONFIG_PROC_FS
1830/* Proc filesystem TCPv6 sock list dumping. */ 1831/* Proc filesystem TCPv6 sock list dumping. */
1831static void get_openreq6(struct seq_file *seq, 1832static void get_openreq6(struct seq_file *seq,
1832 const struct sock *sk, struct request_sock *req, int i, int uid) 1833 const struct sock *sk, struct request_sock *req, int i, kuid_t uid)
1833{ 1834{
1834 int ttd = req->expires - jiffies; 1835 int ttd = req->expires - jiffies;
1835 const struct in6_addr *src = &inet6_rsk(req)->loc_addr; 1836 const struct in6_addr *src = &inet6_rsk(req)->loc_addr;
@@ -1853,7 +1854,7 @@ static void get_openreq6(struct seq_file *seq,
1853 1, /* timers active (only the expire timer) */ 1854 1, /* timers active (only the expire timer) */
1854 jiffies_to_clock_t(ttd), 1855 jiffies_to_clock_t(ttd),
1855 req->retrans, 1856 req->retrans,
1856 uid, 1857 from_kuid_munged(seq_user_ns(seq), uid),
1857 0, /* non standard timer */ 1858 0, /* non standard timer */
1858 0, /* open_requests have no inode */ 1859 0, /* open_requests have no inode */
1859 0, req); 1860 0, req);
@@ -1901,9 +1902,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1901 tp->write_seq-tp->snd_una, 1902 tp->write_seq-tp->snd_una,
1902 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq), 1903 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
1903 timer_active, 1904 timer_active,
1904 jiffies_to_clock_t(timer_expires - jiffies), 1905 jiffies_delta_to_clock_t(timer_expires - jiffies),
1905 icsk->icsk_retransmits, 1906 icsk->icsk_retransmits,
1906 sock_i_uid(sp), 1907 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1907 icsk->icsk_probes_out, 1908 icsk->icsk_probes_out,
1908 sock_i_ino(sp), 1909 sock_i_ino(sp),
1909 atomic_read(&sp->sk_refcnt), sp, 1910 atomic_read(&sp->sk_refcnt), sp,
@@ -1921,10 +1922,7 @@ static void get_timewait6_sock(struct seq_file *seq,
1921 const struct in6_addr *dest, *src; 1922 const struct in6_addr *dest, *src;
1922 __u16 destp, srcp; 1923 __u16 destp, srcp;
1923 const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw); 1924 const struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
1924 int ttd = tw->tw_ttd - jiffies; 1925 long delta = tw->tw_ttd - jiffies;
1925
1926 if (ttd < 0)
1927 ttd = 0;
1928 1926
1929 dest = &tw6->tw_v6_daddr; 1927 dest = &tw6->tw_v6_daddr;
1930 src = &tw6->tw_v6_rcv_saddr; 1928 src = &tw6->tw_v6_rcv_saddr;
@@ -1940,7 +1938,7 @@ static void get_timewait6_sock(struct seq_file *seq,
1940 dest->s6_addr32[0], dest->s6_addr32[1], 1938 dest->s6_addr32[0], dest->s6_addr32[1],
1941 dest->s6_addr32[2], dest->s6_addr32[3], destp, 1939 dest->s6_addr32[2], dest->s6_addr32[3], destp,
1942 tw->tw_substate, 0, 0, 1940 tw->tw_substate, 0, 0,
1943 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, 1941 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
1944 atomic_read(&tw->tw_refcnt), tw); 1942 atomic_read(&tw->tw_refcnt), tw);
1945} 1943}
1946 1944
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 07e2bfef6845..fc9997260a6b 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1469,7 +1469,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
1469 sk_wmem_alloc_get(sp), 1469 sk_wmem_alloc_get(sp),
1470 sk_rmem_alloc_get(sp), 1470 sk_rmem_alloc_get(sp),
1471 0, 0L, 0, 1471 0, 0L, 0,
1472 sock_i_uid(sp), 0, 1472 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1473 0,
1473 sock_i_ino(sp), 1474 sock_i_ino(sp),
1474 atomic_read(&sp->sk_refcnt), sp, 1475 atomic_read(&sp->sk_refcnt), sp,
1475 atomic_read(&sp->sk_drops)); 1476 atomic_read(&sp->sk_drops));