aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c95
-rw-r--r--net/ipv6/addrlabel.c106
-rw-r--r--net/ipv6/af_inet6.c17
-rw-r--r--net/ipv6/anycast.c2
-rw-r--r--net/ipv6/datagram.c2
-rw-r--r--net/ipv6/exthdrs.c4
-rw-r--r--net/ipv6/icmp.c5
-rw-r--r--net/ipv6/inet6_hashtables.c13
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_input.c7
-rw-r--r--net/ipv6/ip6_output.c19
-rw-r--r--net/ipv6/ip6_tunnel.c28
-rw-r--r--net/ipv6/ip6mr.c81
-rw-r--r--net/ipv6/ipv6_sockglue.c11
-rw-r--r--net/ipv6/mcast.c9
-rw-r--r--net/ipv6/ndisc.c11
-rw-r--r--net/ipv6/netfilter/Kconfig12
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6_queue.c5
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c31
-rw-r--r--net/ipv6/netfilter/ip6table_security.c172
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c5
-rw-r--r--net/ipv6/proc.c33
-rw-r--r--net/ipv6/protocol.c2
-rw-r--r--net/ipv6/raw.c10
-rw-r--r--net/ipv6/reassembly.c63
-rw-r--r--net/ipv6/route.c74
-rw-r--r--net/ipv6/sit.c26
-rw-r--r--net/ipv6/syncookies.c6
-rw-r--r--net/ipv6/sysctl_net_ipv6.c29
-rw-r--r--net/ipv6/tcp_ipv6.c269
-rw-r--r--net/ipv6/udp.c53
-rw-r--r--net/ipv6/udp_impl.h2
-rw-r--r--net/ipv6/udplite.c2
34 files changed, 728 insertions, 479 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ff61a5cdb0b3..580ae506c399 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6,8 +6,6 @@
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 * 8 *
9 * $Id: addrconf.c,v 1.69 2001/10/31 21:55:54 davem Exp $
10 *
11 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
@@ -121,6 +119,7 @@ static void ipv6_regen_rndid(unsigned long data);
121static int desync_factor = MAX_DESYNC_FACTOR * HZ; 119static int desync_factor = MAX_DESYNC_FACTOR * HZ;
122#endif 120#endif
123 121
122static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
124static int ipv6_count_addresses(struct inet6_dev *idev); 123static int ipv6_count_addresses(struct inet6_dev *idev);
125 124
126/* 125/*
@@ -185,6 +184,8 @@ struct ipv6_devconf ipv6_devconf __read_mostly = {
185#endif 184#endif
186 .proxy_ndp = 0, 185 .proxy_ndp = 0,
187 .accept_source_route = 0, /* we do not accept RH0 by default. */ 186 .accept_source_route = 0, /* we do not accept RH0 by default. */
187 .disable_ipv6 = 0,
188 .accept_dad = 1,
188}; 189};
189 190
190static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { 191static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -217,6 +218,8 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
217#endif 218#endif
218 .proxy_ndp = 0, 219 .proxy_ndp = 0,
219 .accept_source_route = 0, /* we do not accept RH0 by default. */ 220 .accept_source_route = 0, /* we do not accept RH0 by default. */
221 .disable_ipv6 = 0,
222 .accept_dad = 1,
220}; 223};
221 224
222/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ 225/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -226,9 +229,15 @@ const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_IN
226const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; 229const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
227 230
228/* Check if a valid qdisc is available */ 231/* Check if a valid qdisc is available */
229static inline int addrconf_qdisc_ok(struct net_device *dev) 232static inline bool addrconf_qdisc_ok(const struct net_device *dev)
233{
234 return !qdisc_tx_is_noop(dev);
235}
236
237/* Check if a route is valid prefix route */
238static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
230{ 239{
231 return (dev->qdisc != &noop_qdisc); 240 return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0);
232} 241}
233 242
234static void addrconf_del_timer(struct inet6_ifaddr *ifp) 243static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -344,6 +353,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
344 kfree(ndev); 353 kfree(ndev);
345 return NULL; 354 return NULL;
346 } 355 }
356 if (ndev->cnf.forwarding)
357 dev_disable_lro(dev);
347 /* We refer to the device */ 358 /* We refer to the device */
348 dev_hold(dev); 359 dev_hold(dev);
349 360
@@ -372,6 +383,9 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
372 */ 383 */
373 in6_dev_hold(ndev); 384 in6_dev_hold(ndev);
374 385
386 if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
387 ndev->cnf.accept_dad = -1;
388
375#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 389#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
376 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { 390 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
377 printk(KERN_INFO 391 printk(KERN_INFO
@@ -438,6 +452,8 @@ static void dev_forward_change(struct inet6_dev *idev)
438 if (!idev) 452 if (!idev)
439 return; 453 return;
440 dev = idev->dev; 454 dev = idev->dev;
455 if (idev->cnf.forwarding)
456 dev_disable_lro(dev);
441 if (dev && (dev->flags & IFF_MULTICAST)) { 457 if (dev && (dev->flags & IFF_MULTICAST)) {
442 if (idev->cnf.forwarding) 458 if (idev->cnf.forwarding)
443 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); 459 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
@@ -483,12 +499,14 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
483 if (p == &net->ipv6.devconf_dflt->forwarding) 499 if (p == &net->ipv6.devconf_dflt->forwarding)
484 return; 500 return;
485 501
502 rtnl_lock();
486 if (p == &net->ipv6.devconf_all->forwarding) { 503 if (p == &net->ipv6.devconf_all->forwarding) {
487 __s32 newf = net->ipv6.devconf_all->forwarding; 504 __s32 newf = net->ipv6.devconf_all->forwarding;
488 net->ipv6.devconf_dflt->forwarding = newf; 505 net->ipv6.devconf_dflt->forwarding = newf;
489 addrconf_forward_change(net, newf); 506 addrconf_forward_change(net, newf);
490 } else if ((!*p) ^ (!old)) 507 } else if ((!*p) ^ (!old))
491 dev_forward_change((struct inet6_dev *)table->extra1); 508 dev_forward_change((struct inet6_dev *)table->extra1);
509 rtnl_unlock();
492 510
493 if (*p) 511 if (*p)
494 rt6_purge_dflt_routers(net); 512 rt6_purge_dflt_routers(net);
@@ -568,6 +586,13 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
568 struct rt6_info *rt; 586 struct rt6_info *rt;
569 int hash; 587 int hash;
570 int err = 0; 588 int err = 0;
589 int addr_type = ipv6_addr_type(addr);
590
591 if (addr_type == IPV6_ADDR_ANY ||
592 addr_type & IPV6_ADDR_MULTICAST ||
593 (!(idev->dev->flags & IFF_LOOPBACK) &&
594 addr_type & IPV6_ADDR_LOOPBACK))
595 return ERR_PTR(-EADDRNOTAVAIL);
571 596
572 rcu_read_lock_bh(); 597 rcu_read_lock_bh();
573 if (idev->dead) { 598 if (idev->dead) {
@@ -777,7 +802,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
777 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 802 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
778 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 803 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
779 804
780 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 805 if (rt && addrconf_is_prefix_route(rt)) {
781 if (onlink == 0) { 806 if (onlink == 0) {
782 ip6_del_rt(rt); 807 ip6_del_rt(rt);
783 rt = NULL; 808 rt = NULL;
@@ -958,7 +983,8 @@ static inline int ipv6_saddr_preferred(int type)
958 return 0; 983 return 0;
959} 984}
960 985
961static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, 986static int ipv6_get_saddr_eval(struct net *net,
987 struct ipv6_saddr_score *score,
962 struct ipv6_saddr_dst *dst, 988 struct ipv6_saddr_dst *dst,
963 int i) 989 int i)
964{ 990{
@@ -1037,7 +1063,8 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score,
1037 break; 1063 break;
1038 case IPV6_SADDR_RULE_LABEL: 1064 case IPV6_SADDR_RULE_LABEL:
1039 /* Rule 6: Prefer matching label */ 1065 /* Rule 6: Prefer matching label */
1040 ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, 1066 ret = ipv6_addr_label(net,
1067 &score->ifa->addr, score->addr_type,
1041 score->ifa->idev->dev->ifindex) == dst->label; 1068 score->ifa->idev->dev->ifindex) == dst->label;
1042 break; 1069 break;
1043#ifdef CONFIG_IPV6_PRIVACY 1070#ifdef CONFIG_IPV6_PRIVACY
@@ -1091,7 +1118,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1091 dst.addr = daddr; 1118 dst.addr = daddr;
1092 dst.ifindex = dst_dev ? dst_dev->ifindex : 0; 1119 dst.ifindex = dst_dev ? dst_dev->ifindex : 0;
1093 dst.scope = __ipv6_addr_src_scope(dst_type); 1120 dst.scope = __ipv6_addr_src_scope(dst_type);
1094 dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); 1121 dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex);
1095 dst.prefs = prefs; 1122 dst.prefs = prefs;
1096 1123
1097 hiscore->rule = -1; 1124 hiscore->rule = -1;
@@ -1159,8 +1186,8 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1159 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { 1186 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) {
1160 int minihiscore, miniscore; 1187 int minihiscore, miniscore;
1161 1188
1162 minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); 1189 minihiscore = ipv6_get_saddr_eval(net, hiscore, &dst, i);
1163 miniscore = ipv6_get_saddr_eval(score, &dst, i); 1190 miniscore = ipv6_get_saddr_eval(net, score, &dst, i);
1164 1191
1165 if (minihiscore > miniscore) { 1192 if (minihiscore > miniscore) {
1166 if (i == IPV6_SADDR_RULE_SCOPE && 1193 if (i == IPV6_SADDR_RULE_SCOPE &&
@@ -1400,6 +1427,20 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
1400 1427
1401void addrconf_dad_failure(struct inet6_ifaddr *ifp) 1428void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1402{ 1429{
1430 struct inet6_dev *idev = ifp->idev;
1431 if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
1432 struct in6_addr addr;
1433
1434 addr.s6_addr32[0] = htonl(0xfe800000);
1435 addr.s6_addr32[1] = 0;
1436
1437 if (!ipv6_generate_eui64(addr.s6_addr + 8, idev->dev) &&
1438 ipv6_addr_equal(&ifp->addr, &addr)) {
1439 /* DAD failed for link-local based on MAC address */
1440 idev->cnf.disable_ipv6 = 1;
1441 }
1442 }
1443
1403 if (net_ratelimit()) 1444 if (net_ratelimit())
1404 printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name); 1445 printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
1405 addrconf_dad_stop(ifp); 1446 addrconf_dad_stop(ifp);
@@ -1788,7 +1829,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1788 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, 1829 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL,
1789 dev->ifindex, 1); 1830 dev->ifindex, 1);
1790 1831
1791 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 1832 if (rt && addrconf_is_prefix_route(rt)) {
1792 /* Autoconf prefix route */ 1833 /* Autoconf prefix route */
1793 if (valid_lft == 0) { 1834 if (valid_lft == 0) {
1794 ip6_del_rt(rt); 1835 ip6_del_rt(rt);
@@ -1822,6 +1863,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1822 struct inet6_ifaddr * ifp; 1863 struct inet6_ifaddr * ifp;
1823 struct in6_addr addr; 1864 struct in6_addr addr;
1824 int create = 0, update_lft = 0; 1865 int create = 0, update_lft = 0;
1866 struct net *net = dev_net(dev);
1825 1867
1826 if (pinfo->prefix_len == 64) { 1868 if (pinfo->prefix_len == 64) {
1827 memcpy(&addr, &pinfo->prefix, 8); 1869 memcpy(&addr, &pinfo->prefix, 8);
@@ -1840,7 +1882,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1840 1882
1841ok: 1883ok:
1842 1884
1843 ifp = ipv6_get_ifaddr(dev_net(dev), &addr, dev, 1); 1885 ifp = ipv6_get_ifaddr(net, &addr, dev, 1);
1844 1886
1845 if (ifp == NULL && valid_lft) { 1887 if (ifp == NULL && valid_lft) {
1846 int max_addresses = in6_dev->cnf.max_addresses; 1888 int max_addresses = in6_dev->cnf.max_addresses;
@@ -1848,7 +1890,7 @@ ok:
1848 1890
1849#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 1891#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1850 if (in6_dev->cnf.optimistic_dad && 1892 if (in6_dev->cnf.optimistic_dad &&
1851 !ipv6_devconf.forwarding) 1893 !net->ipv6.devconf_all->forwarding)
1852 addr_flags = IFA_F_OPTIMISTIC; 1894 addr_flags = IFA_F_OPTIMISTIC;
1853#endif 1895#endif
1854 1896
@@ -2273,11 +2315,12 @@ static void init_loopback(struct net_device *dev)
2273static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) 2315static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr)
2274{ 2316{
2275 struct inet6_ifaddr * ifp; 2317 struct inet6_ifaddr * ifp;
2318 struct net *net = dev_net(idev->dev);
2276 u32 addr_flags = IFA_F_PERMANENT; 2319 u32 addr_flags = IFA_F_PERMANENT;
2277 2320
2278#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 2321#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
2279 if (idev->cnf.optimistic_dad && 2322 if (idev->cnf.optimistic_dad &&
2280 !ipv6_devconf.forwarding) 2323 !net->ipv6.devconf_all->forwarding)
2281 addr_flags |= IFA_F_OPTIMISTIC; 2324 addr_flags |= IFA_F_OPTIMISTIC;
2282#endif 2325#endif
2283 2326
@@ -2732,6 +2775,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2732 spin_lock_bh(&ifp->lock); 2775 spin_lock_bh(&ifp->lock);
2733 2776
2734 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 2777 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
2778 idev->cnf.accept_dad < 1 ||
2735 !(ifp->flags&IFA_F_TENTATIVE) || 2779 !(ifp->flags&IFA_F_TENTATIVE) ||
2736 ifp->flags & IFA_F_NODAD) { 2780 ifp->flags & IFA_F_NODAD) {
2737 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); 2781 ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2779,6 +2823,11 @@ static void addrconf_dad_timer(unsigned long data)
2779 read_unlock_bh(&idev->lock); 2823 read_unlock_bh(&idev->lock);
2780 goto out; 2824 goto out;
2781 } 2825 }
2826 if (idev->cnf.accept_dad > 1 && idev->cnf.disable_ipv6) {
2827 read_unlock_bh(&idev->lock);
2828 addrconf_dad_failure(ifp);
2829 return;
2830 }
2782 spin_lock_bh(&ifp->lock); 2831 spin_lock_bh(&ifp->lock);
2783 if (ifp->probes == 0) { 2832 if (ifp->probes == 0) {
2784 /* 2833 /*
@@ -3638,6 +3687,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3638#ifdef CONFIG_IPV6_MROUTE 3687#ifdef CONFIG_IPV6_MROUTE
3639 array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; 3688 array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
3640#endif 3689#endif
3690 array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6;
3691 array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
3641} 3692}
3642 3693
3643static inline size_t inet6_if_nlmsg_size(void) 3694static inline size_t inet6_if_nlmsg_size(void)
@@ -4197,6 +4248,22 @@ static struct addrconf_sysctl_table
4197 }, 4248 },
4198#endif 4249#endif
4199 { 4250 {
4251 .ctl_name = CTL_UNNUMBERED,
4252 .procname = "disable_ipv6",
4253 .data = &ipv6_devconf.disable_ipv6,
4254 .maxlen = sizeof(int),
4255 .mode = 0644,
4256 .proc_handler = &proc_dointvec,
4257 },
4258 {
4259 .ctl_name = CTL_UNNUMBERED,
4260 .procname = "accept_dad",
4261 .data = &ipv6_devconf.accept_dad,
4262 .maxlen = sizeof(int),
4263 .mode = 0644,
4264 .proc_handler = &proc_dointvec,
4265 },
4266 {
4200 .ctl_name = 0, /* sentinel */ 4267 .ctl_name = 0, /* sentinel */
4201 } 4268 }
4202 }, 4269 },
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 9bfa8846f262..08909039d87b 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -29,6 +29,9 @@
29 */ 29 */
30struct ip6addrlbl_entry 30struct ip6addrlbl_entry
31{ 31{
32#ifdef CONFIG_NET_NS
33 struct net *lbl_net;
34#endif
32 struct in6_addr prefix; 35 struct in6_addr prefix;
33 int prefixlen; 36 int prefixlen;
34 int ifindex; 37 int ifindex;
@@ -46,6 +49,16 @@ static struct ip6addrlbl_table
46 u32 seq; 49 u32 seq;
47} ip6addrlbl_table; 50} ip6addrlbl_table;
48 51
52static inline
53struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
54{
55#ifdef CONFIG_NET_NS
56 return lbl->lbl_net;
57#else
58 return &init_net;
59#endif
60}
61
49/* 62/*
50 * Default policy table (RFC3484 + extensions) 63 * Default policy table (RFC3484 + extensions)
51 * 64 *
@@ -65,7 +78,7 @@ static struct ip6addrlbl_table
65 78
66#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 79#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL
67 80
68static const __initdata struct ip6addrlbl_init_table 81static const __net_initdata struct ip6addrlbl_init_table
69{ 82{
70 const struct in6_addr *prefix; 83 const struct in6_addr *prefix;
71 int prefixlen; 84 int prefixlen;
@@ -108,6 +121,9 @@ static const __initdata struct ip6addrlbl_init_table
108/* Object management */ 121/* Object management */
109static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) 122static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
110{ 123{
124#ifdef CONFIG_NET_NS
125 release_net(p->lbl_net);
126#endif
111 kfree(p); 127 kfree(p);
112} 128}
113 129
@@ -128,10 +144,13 @@ static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
128} 144}
129 145
130/* Find label */ 146/* Find label */
131static int __ip6addrlbl_match(struct ip6addrlbl_entry *p, 147static int __ip6addrlbl_match(struct net *net,
148 struct ip6addrlbl_entry *p,
132 const struct in6_addr *addr, 149 const struct in6_addr *addr,
133 int addrtype, int ifindex) 150 int addrtype, int ifindex)
134{ 151{
152 if (!net_eq(ip6addrlbl_net(p), net))
153 return 0;
135 if (p->ifindex && p->ifindex != ifindex) 154 if (p->ifindex && p->ifindex != ifindex)
136 return 0; 155 return 0;
137 if (p->addrtype && p->addrtype != addrtype) 156 if (p->addrtype && p->addrtype != addrtype)
@@ -141,19 +160,21 @@ static int __ip6addrlbl_match(struct ip6addrlbl_entry *p,
141 return 1; 160 return 1;
142} 161}
143 162
144static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr, 163static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net,
164 const struct in6_addr *addr,
145 int type, int ifindex) 165 int type, int ifindex)
146{ 166{
147 struct hlist_node *pos; 167 struct hlist_node *pos;
148 struct ip6addrlbl_entry *p; 168 struct ip6addrlbl_entry *p;
149 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 169 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
150 if (__ip6addrlbl_match(p, addr, type, ifindex)) 170 if (__ip6addrlbl_match(net, p, addr, type, ifindex))
151 return p; 171 return p;
152 } 172 }
153 return NULL; 173 return NULL;
154} 174}
155 175
156u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) 176u32 ipv6_addr_label(struct net *net,
177 const struct in6_addr *addr, int type, int ifindex)
157{ 178{
158 u32 label; 179 u32 label;
159 struct ip6addrlbl_entry *p; 180 struct ip6addrlbl_entry *p;
@@ -161,7 +182,7 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
161 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; 182 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK;
162 183
163 rcu_read_lock(); 184 rcu_read_lock();
164 p = __ipv6_addr_label(addr, type, ifindex); 185 p = __ipv6_addr_label(net, addr, type, ifindex);
165 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; 186 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
166 rcu_read_unlock(); 187 rcu_read_unlock();
167 188
@@ -174,7 +195,8 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
174} 195}
175 196
176/* allocate one entry */ 197/* allocate one entry */
177static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, 198static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
199 const struct in6_addr *prefix,
178 int prefixlen, int ifindex, 200 int prefixlen, int ifindex,
179 u32 label) 201 u32 label)
180{ 202{
@@ -216,6 +238,9 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
216 newp->addrtype = addrtype; 238 newp->addrtype = addrtype;
217 newp->label = label; 239 newp->label = label;
218 INIT_HLIST_NODE(&newp->list); 240 INIT_HLIST_NODE(&newp->list);
241#ifdef CONFIG_NET_NS
242 newp->lbl_net = hold_net(net);
243#endif
219 atomic_set(&newp->refcnt, 1); 244 atomic_set(&newp->refcnt, 1);
220 return newp; 245 return newp;
221} 246}
@@ -237,6 +262,7 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
237 hlist_for_each_entry_safe(p, pos, n, 262 hlist_for_each_entry_safe(p, pos, n,
238 &ip6addrlbl_table.head, list) { 263 &ip6addrlbl_table.head, list) {
239 if (p->prefixlen == newp->prefixlen && 264 if (p->prefixlen == newp->prefixlen &&
265 net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
240 p->ifindex == newp->ifindex && 266 p->ifindex == newp->ifindex &&
241 ipv6_addr_equal(&p->prefix, &newp->prefix)) { 267 ipv6_addr_equal(&p->prefix, &newp->prefix)) {
242 if (!replace) { 268 if (!replace) {
@@ -261,7 +287,8 @@ out:
261} 287}
262 288
263/* add a label */ 289/* add a label */
264static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen, 290static int ip6addrlbl_add(struct net *net,
291 const struct in6_addr *prefix, int prefixlen,
265 int ifindex, u32 label, int replace) 292 int ifindex, u32 label, int replace)
266{ 293{
267 struct ip6addrlbl_entry *newp; 294 struct ip6addrlbl_entry *newp;
@@ -274,7 +301,7 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
274 (unsigned int)label, 301 (unsigned int)label,
275 replace); 302 replace);
276 303
277 newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); 304 newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label);
278 if (IS_ERR(newp)) 305 if (IS_ERR(newp))
279 return PTR_ERR(newp); 306 return PTR_ERR(newp);
280 spin_lock(&ip6addrlbl_table.lock); 307 spin_lock(&ip6addrlbl_table.lock);
@@ -286,7 +313,8 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
286} 313}
287 314
288/* remove a label */ 315/* remove a label */
289static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 316static int __ip6addrlbl_del(struct net *net,
317 const struct in6_addr *prefix, int prefixlen,
290 int ifindex) 318 int ifindex)
291{ 319{
292 struct ip6addrlbl_entry *p = NULL; 320 struct ip6addrlbl_entry *p = NULL;
@@ -300,6 +328,7 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
300 328
301 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { 329 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
302 if (p->prefixlen == prefixlen && 330 if (p->prefixlen == prefixlen &&
331 net_eq(ip6addrlbl_net(p), net) &&
303 p->ifindex == ifindex && 332 p->ifindex == ifindex &&
304 ipv6_addr_equal(&p->prefix, prefix)) { 333 ipv6_addr_equal(&p->prefix, prefix)) {
305 hlist_del_rcu(&p->list); 334 hlist_del_rcu(&p->list);
@@ -311,7 +340,8 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
311 return ret; 340 return ret;
312} 341}
313 342
314static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 343static int ip6addrlbl_del(struct net *net,
344 const struct in6_addr *prefix, int prefixlen,
315 int ifindex) 345 int ifindex)
316{ 346{
317 struct in6_addr prefix_buf; 347 struct in6_addr prefix_buf;
@@ -324,13 +354,13 @@ static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
324 354
325 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); 355 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
326 spin_lock(&ip6addrlbl_table.lock); 356 spin_lock(&ip6addrlbl_table.lock);
327 ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex); 357 ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex);
328 spin_unlock(&ip6addrlbl_table.lock); 358 spin_unlock(&ip6addrlbl_table.lock);
329 return ret; 359 return ret;
330} 360}
331 361
332/* add default label */ 362/* add default label */
333static __init int ip6addrlbl_init(void) 363static int __net_init ip6addrlbl_net_init(struct net *net)
334{ 364{
335 int err = 0; 365 int err = 0;
336 int i; 366 int i;
@@ -338,7 +368,8 @@ static __init int ip6addrlbl_init(void)
338 ADDRLABEL(KERN_DEBUG "%s()\n", __func__); 368 ADDRLABEL(KERN_DEBUG "%s()\n", __func__);
339 369
340 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { 370 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
341 int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix, 371 int ret = ip6addrlbl_add(net,
372 ip6addrlbl_init_table[i].prefix,
342 ip6addrlbl_init_table[i].prefixlen, 373 ip6addrlbl_init_table[i].prefixlen,
343 0, 374 0,
344 ip6addrlbl_init_table[i].label, 0); 375 ip6addrlbl_init_table[i].label, 0);
@@ -349,11 +380,32 @@ static __init int ip6addrlbl_init(void)
349 return err; 380 return err;
350} 381}
351 382
383static void __net_exit ip6addrlbl_net_exit(struct net *net)
384{
385 struct ip6addrlbl_entry *p = NULL;
386 struct hlist_node *pos, *n;
387
388 /* Remove all labels belonging to the exiting net */
389 spin_lock(&ip6addrlbl_table.lock);
390 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
391 if (net_eq(ip6addrlbl_net(p), net)) {
392 hlist_del_rcu(&p->list);
393 ip6addrlbl_put(p);
394 }
395 }
396 spin_unlock(&ip6addrlbl_table.lock);
397}
398
399static struct pernet_operations ipv6_addr_label_ops = {
400 .init = ip6addrlbl_net_init,
401 .exit = ip6addrlbl_net_exit,
402};
403
352int __init ipv6_addr_label_init(void) 404int __init ipv6_addr_label_init(void)
353{ 405{
354 spin_lock_init(&ip6addrlbl_table.lock); 406 spin_lock_init(&ip6addrlbl_table.lock);
355 407
356 return ip6addrlbl_init(); 408 return register_pernet_subsys(&ipv6_addr_label_ops);
357} 409}
358 410
359static const struct nla_policy ifal_policy[IFAL_MAX+1] = { 411static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
@@ -371,9 +423,6 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
371 u32 label; 423 u32 label;
372 int err = 0; 424 int err = 0;
373 425
374 if (net != &init_net)
375 return 0;
376
377 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 426 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
378 if (err < 0) 427 if (err < 0)
379 return err; 428 return err;
@@ -385,7 +434,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
385 return -EINVAL; 434 return -EINVAL;
386 435
387 if (ifal->ifal_index && 436 if (ifal->ifal_index &&
388 !__dev_get_by_index(&init_net, ifal->ifal_index)) 437 !__dev_get_by_index(net, ifal->ifal_index))
389 return -EINVAL; 438 return -EINVAL;
390 439
391 if (!tb[IFAL_ADDRESS]) 440 if (!tb[IFAL_ADDRESS])
@@ -403,12 +452,12 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
403 452
404 switch(nlh->nlmsg_type) { 453 switch(nlh->nlmsg_type) {
405 case RTM_NEWADDRLABEL: 454 case RTM_NEWADDRLABEL:
406 err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen, 455 err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen,
407 ifal->ifal_index, label, 456 ifal->ifal_index, label,
408 nlh->nlmsg_flags & NLM_F_REPLACE); 457 nlh->nlmsg_flags & NLM_F_REPLACE);
409 break; 458 break;
410 case RTM_DELADDRLABEL: 459 case RTM_DELADDRLABEL:
411 err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen, 460 err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen,
412 ifal->ifal_index); 461 ifal->ifal_index);
413 break; 462 break;
414 default: 463 default:
@@ -458,12 +507,10 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
458 int idx = 0, s_idx = cb->args[0]; 507 int idx = 0, s_idx = cb->args[0];
459 int err; 508 int err;
460 509
461 if (net != &init_net)
462 return 0;
463
464 rcu_read_lock(); 510 rcu_read_lock();
465 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 511 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
466 if (idx >= s_idx) { 512 if (idx >= s_idx &&
513 net_eq(ip6addrlbl_net(p), net)) {
467 if ((err = ip6addrlbl_fill(skb, p, 514 if ((err = ip6addrlbl_fill(skb, p,
468 ip6addrlbl_table.seq, 515 ip6addrlbl_table.seq,
469 NETLINK_CB(cb->skb).pid, 516 NETLINK_CB(cb->skb).pid,
@@ -499,9 +546,6 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
499 struct ip6addrlbl_entry *p; 546 struct ip6addrlbl_entry *p;
500 struct sk_buff *skb; 547 struct sk_buff *skb;
501 548
502 if (net != &init_net)
503 return 0;
504
505 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 549 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
506 if (err < 0) 550 if (err < 0)
507 return err; 551 return err;
@@ -513,7 +557,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
513 return -EINVAL; 557 return -EINVAL;
514 558
515 if (ifal->ifal_index && 559 if (ifal->ifal_index &&
516 !__dev_get_by_index(&init_net, ifal->ifal_index)) 560 !__dev_get_by_index(net, ifal->ifal_index))
517 return -EINVAL; 561 return -EINVAL;
518 562
519 if (!tb[IFAL_ADDRESS]) 563 if (!tb[IFAL_ADDRESS])
@@ -524,7 +568,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
524 return -EINVAL; 568 return -EINVAL;
525 569
526 rcu_read_lock(); 570 rcu_read_lock();
527 p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index); 571 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
528 if (p && ip6addrlbl_hold(p)) 572 if (p && ip6addrlbl_hold(p))
529 p = NULL; 573 p = NULL;
530 lseq = ip6addrlbl_table.seq; 574 lseq = ip6addrlbl_table.seq;
@@ -552,7 +596,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
552 goto out; 596 goto out;
553 } 597 }
554 598
555 err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); 599 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
556out: 600out:
557 return err; 601 return err;
558} 602}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e84b3fd17fb4..3d828bc4b1cf 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Adapted from linux/net/ipv4/af_inet.c 8 * Adapted from linux/net/ipv4/af_inet.c
9 * 9 *
10 * $Id: af_inet6.c,v 1.66 2002/02/01 22:01:04 davem Exp $
11 *
12 * Fixes: 10 * Fixes:
13 * piggy, Karl Knutson : Socket protocol table 11 * piggy, Karl Knutson : Socket protocol table
14 * Hideaki YOSHIFUJI : sin6_scope_id support 12 * Hideaki YOSHIFUJI : sin6_scope_id support
@@ -61,9 +59,7 @@
61 59
62#include <asm/uaccess.h> 60#include <asm/uaccess.h>
63#include <asm/system.h> 61#include <asm/system.h>
64#ifdef CONFIG_IPV6_MROUTE
65#include <linux/mroute6.h> 62#include <linux/mroute6.h>
66#endif
67 63
68MODULE_AUTHOR("Cast of dozens"); 64MODULE_AUTHOR("Cast of dozens");
69MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); 65MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
@@ -373,7 +369,7 @@ int inet6_release(struct socket *sock)
373 369
374EXPORT_SYMBOL(inet6_release); 370EXPORT_SYMBOL(inet6_release);
375 371
376int inet6_destroy_sock(struct sock *sk) 372void inet6_destroy_sock(struct sock *sk)
377{ 373{
378 struct ipv6_pinfo *np = inet6_sk(sk); 374 struct ipv6_pinfo *np = inet6_sk(sk);
379 struct sk_buff *skb; 375 struct sk_buff *skb;
@@ -391,8 +387,6 @@ int inet6_destroy_sock(struct sock *sk)
391 387
392 if ((opt = xchg(&np->opt, NULL)) != NULL) 388 if ((opt = xchg(&np->opt, NULL)) != NULL)
393 sock_kfree_s(sk, opt, opt->tot_len); 389 sock_kfree_s(sk, opt, opt->tot_len);
394
395 return 0;
396} 390}
397 391
398EXPORT_SYMBOL_GPL(inet6_destroy_sock); 392EXPORT_SYMBOL_GPL(inet6_destroy_sock);
@@ -956,9 +950,9 @@ static int __init inet6_init(void)
956 err = icmpv6_init(); 950 err = icmpv6_init();
957 if (err) 951 if (err)
958 goto icmp_fail; 952 goto icmp_fail;
959#ifdef CONFIG_IPV6_MROUTE 953 err = ip6_mr_init();
960 ip6_mr_init(); 954 if (err)
961#endif 955 goto ipmr_fail;
962 err = ndisc_init(); 956 err = ndisc_init();
963 if (err) 957 if (err)
964 goto ndisc_fail; 958 goto ndisc_fail;
@@ -1061,6 +1055,8 @@ netfilter_fail:
1061igmp_fail: 1055igmp_fail:
1062 ndisc_cleanup(); 1056 ndisc_cleanup();
1063ndisc_fail: 1057ndisc_fail:
1058 ip6_mr_cleanup();
1059ipmr_fail:
1064 icmpv6_cleanup(); 1060 icmpv6_cleanup();
1065icmp_fail: 1061icmp_fail:
1066 unregister_pernet_subsys(&inet6_net_ops); 1062 unregister_pernet_subsys(&inet6_net_ops);
@@ -1115,6 +1111,7 @@ static void __exit inet6_exit(void)
1115 ipv6_netfilter_fini(); 1111 ipv6_netfilter_fini();
1116 igmp6_cleanup(); 1112 igmp6_cleanup();
1117 ndisc_cleanup(); 1113 ndisc_cleanup();
1114 ip6_mr_cleanup();
1118 icmpv6_cleanup(); 1115 icmpv6_cleanup();
1119 rawv6_exit(); 1116 rawv6_exit();
1120 1117
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 4e1b29fabdf0..8336cd81cb4f 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -60,7 +60,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
60 struct inet6_dev *idev; 60 struct inet6_dev *idev;
61 struct ipv6_ac_socklist *pac; 61 struct ipv6_ac_socklist *pac;
62 struct net *net = sock_net(sk); 62 struct net *net = sock_net(sk);
63 int ishost = !ipv6_devconf.forwarding; 63 int ishost = !net->ipv6.devconf_all->forwarding;
64 int err = 0; 64 int err = 0;
65 65
66 if (!capable(CAP_NET_ADMIN)) 66 if (!capable(CAP_NET_ADMIN))
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 0f0f94a40335..f7b535dec860 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: datagram.c,v 1.24 2002/02/01 22:01:04 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index dcf94fdfb863..837c830d6d8e 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -7,8 +7,6 @@
7 * Andi Kleen <ak@muc.de> 7 * Andi Kleen <ak@muc.de>
8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 8 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
9 * 9 *
10 * $Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
11 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
@@ -321,7 +319,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
321 int n, i; 319 int n, i;
322 struct ipv6_rt_hdr *hdr; 320 struct ipv6_rt_hdr *hdr;
323 struct rt0_hdr *rthdr; 321 struct rt0_hdr *rthdr;
324 int accept_source_route = ipv6_devconf.accept_source_route; 322 int accept_source_route = dev_net(skb->dev)->ipv6.devconf_all->accept_source_route;
325 323
326 idev = in6_dev_get(skb->dev); 324 idev = in6_dev_get(skb->dev);
327 if (idev) { 325 if (idev) {
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index d42dd16d3487..abedf95fdf2d 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: icmp.c,v 1.38 2002/02/08 03:57:19 davem Exp $
9 *
10 * Based on net/ipv4/icmp.c 8 * Based on net/ipv4/icmp.c
11 * 9 *
12 * RFC 1885 10 * RFC 1885
@@ -956,7 +954,8 @@ ctl_table ipv6_icmp_table_template[] = {
956 .data = &init_net.ipv6.sysctl.icmpv6_time, 954 .data = &init_net.ipv6.sysctl.icmpv6_time,
957 .maxlen = sizeof(int), 955 .maxlen = sizeof(int),
958 .mode = 0644, 956 .mode = 0644,
959 .proc_handler = &proc_dointvec 957 .proc_handler = &proc_dointvec_ms_jiffies,
958 .strategy = &sysctl_ms_jiffies
960 }, 959 },
961 { .ctl_name = 0 }, 960 { .ctl_name = 0 },
962}; 961};
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 580014aea4d6..00a8a5f9380c 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -68,7 +68,7 @@ struct sock *__inet6_lookup_established(struct net *net,
68 /* Optimize here for direct hit, only listening connections can 68 /* Optimize here for direct hit, only listening connections can
69 * have wildcards anyways. 69 * have wildcards anyways.
70 */ 70 */
71 unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport); 71 unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport);
72 struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); 72 struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
73 rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); 73 rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
74 74
@@ -104,7 +104,8 @@ struct sock *inet6_lookup_listener(struct net *net,
104 int score, hiscore = 0; 104 int score, hiscore = 0;
105 105
106 read_lock(&hashinfo->lhash_lock); 106 read_lock(&hashinfo->lhash_lock);
107 sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) { 107 sk_for_each(sk, node,
108 &hashinfo->listening_hash[inet_lhashfn(net, hnum)]) {
108 if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && 109 if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum &&
109 sk->sk_family == PF_INET6) { 110 sk->sk_family == PF_INET6) {
110 const struct ipv6_pinfo *np = inet6_sk(sk); 111 const struct ipv6_pinfo *np = inet6_sk(sk);
@@ -165,14 +166,14 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
165 const struct in6_addr *saddr = &np->daddr; 166 const struct in6_addr *saddr = &np->daddr;
166 const int dif = sk->sk_bound_dev_if; 167 const int dif = sk->sk_bound_dev_if;
167 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); 168 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
168 const unsigned int hash = inet6_ehashfn(daddr, lport, saddr, 169 struct net *net = sock_net(sk);
170 const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr,
169 inet->dport); 171 inet->dport);
170 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); 172 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
171 rwlock_t *lock = inet_ehash_lockp(hinfo, hash); 173 rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
172 struct sock *sk2; 174 struct sock *sk2;
173 const struct hlist_node *node; 175 const struct hlist_node *node;
174 struct inet_timewait_sock *tw; 176 struct inet_timewait_sock *tw;
175 struct net *net = sock_net(sk);
176 177
177 prefetch(head->chain.first); 178 prefetch(head->chain.first);
178 write_lock(lock); 179 write_lock(lock);
@@ -209,11 +210,11 @@ unique:
209 210
210 if (twp != NULL) { 211 if (twp != NULL) {
211 *twp = tw; 212 *twp = tw;
212 NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); 213 NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED);
213 } else if (tw != NULL) { 214 } else if (tw != NULL) {
214 /* Silly. Should hash-dance instead... */ 215 /* Silly. Should hash-dance instead... */
215 inet_twsk_deschedule(tw, death_row); 216 inet_twsk_deschedule(tw, death_row);
216 NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); 217 NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED);
217 218
218 inet_twsk_put(tw); 219 inet_twsk_put(tw);
219 } 220 }
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 1ee4fa17c129..4de2b9efcacb 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 17eb48b8e329..7e14cccd0561 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -6,8 +6,6 @@
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Ian P. Morris <I.P.Morris@soton.ac.uk> 7 * Ian P. Morris <I.P.Morris@soton.ac.uk>
8 * 8 *
9 * $Id: ip6_input.c,v 1.19 2000/12/13 18:31:50 davem Exp $
10 *
11 * Based in linux/net/ipv4/ip_input.c 9 * Based in linux/net/ipv4/ip_input.c
12 * 10 *
13 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
@@ -73,7 +71,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
73 71
74 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); 72 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES);
75 73
76 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 74 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
75 !idev || unlikely(idev->cnf.disable_ipv6)) {
77 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); 76 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS);
78 rcu_read_unlock(); 77 rcu_read_unlock();
79 goto out; 78 goto out;
@@ -250,7 +249,7 @@ int ip6_mc_input(struct sk_buff *skb)
250 /* 249 /*
251 * IPv6 multicast router mode is now supported ;) 250 * IPv6 multicast router mode is now supported ;)
252 */ 251 */
253 if (ipv6_devconf.mc_forwarding && 252 if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
254 likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) { 253 likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
255 /* 254 /*
256 * Okay, we try to forward - split and duplicate 255 * Okay, we try to forward - split and duplicate
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 48cdce9c696c..6407c64ea4a5 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: ip6_output.c,v 1.34 2002/02/01 22:01:04 davem Exp $
9 *
10 * Based on linux/net/ipv4/ip_output.c 8 * Based on linux/net/ipv4/ip_output.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -175,6 +173,13 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
175 173
176int ip6_output(struct sk_buff *skb) 174int ip6_output(struct sk_buff *skb)
177{ 175{
176 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
177 if (unlikely(idev->cnf.disable_ipv6)) {
178 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
179 kfree_skb(skb);
180 return 0;
181 }
182
178 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || 183 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
179 dst_allfrag(skb->dst)) 184 dst_allfrag(skb->dst))
180 return ip6_fragment(skb, ip6_output2); 185 return ip6_fragment(skb, ip6_output2);
@@ -406,9 +411,12 @@ int ip6_forward(struct sk_buff *skb)
406 struct inet6_skb_parm *opt = IP6CB(skb); 411 struct inet6_skb_parm *opt = IP6CB(skb);
407 struct net *net = dev_net(dst->dev); 412 struct net *net = dev_net(dst->dev);
408 413
409 if (ipv6_devconf.forwarding == 0) 414 if (net->ipv6.devconf_all->forwarding == 0)
410 goto error; 415 goto error;
411 416
417 if (skb_warn_if_lro(skb))
418 goto drop;
419
412 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 420 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
413 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 421 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
414 goto drop; 422 goto drop;
@@ -450,7 +458,7 @@ int ip6_forward(struct sk_buff *skb)
450 } 458 }
451 459
452 /* XXX: idev->cnf.proxy_ndp? */ 460 /* XXX: idev->cnf.proxy_ndp? */
453 if (ipv6_devconf.proxy_ndp && 461 if (net->ipv6.devconf_all->proxy_ndp &&
454 pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { 462 pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) {
455 int proxied = ip6_forward_proxy_check(skb); 463 int proxied = ip6_forward_proxy_check(skb);
456 if (proxied > 0) 464 if (proxied > 0)
@@ -497,7 +505,8 @@ int ip6_forward(struct sk_buff *skb)
497 int addrtype = ipv6_addr_type(&hdr->saddr); 505 int addrtype = ipv6_addr_type(&hdr->saddr);
498 506
499 /* This check is security critical. */ 507 /* This check is security critical. */
500 if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK)) 508 if (addrtype == IPV6_ADDR_ANY ||
509 addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK))
501 goto error; 510 goto error;
502 if (addrtype & IPV6_ADDR_LINKLOCAL) { 511 if (addrtype & IPV6_ADDR_LINKLOCAL) {
503 icmpv6_send(skb, ICMPV6_DEST_UNREACH, 512 icmpv6_send(skb, ICMPV6_DEST_UNREACH,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2bda3ba100b1..17c7b098cdb0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -6,8 +6,6 @@
6 * Ville Nuorvala <vnuorval@tcs.hut.fi> 6 * Ville Nuorvala <vnuorval@tcs.hut.fi>
7 * Yasuyuki Kozakai <kozakai@linux-ipv6.org> 7 * Yasuyuki Kozakai <kozakai@linux-ipv6.org>
8 * 8 *
9 * $Id$
10 *
11 * Based on: 9 * Based on:
12 * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c 10 * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c
13 * 11 *
@@ -711,7 +709,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
711 } 709 }
712 710
713 if (!ip6_tnl_rcv_ctl(t)) { 711 if (!ip6_tnl_rcv_ctl(t)) {
714 t->stat.rx_dropped++; 712 t->dev->stats.rx_dropped++;
715 read_unlock(&ip6_tnl_lock); 713 read_unlock(&ip6_tnl_lock);
716 goto discard; 714 goto discard;
717 } 715 }
@@ -728,8 +726,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
728 726
729 dscp_ecn_decapsulate(t, ipv6h, skb); 727 dscp_ecn_decapsulate(t, ipv6h, skb);
730 728
731 t->stat.rx_packets++; 729 t->dev->stats.rx_packets++;
732 t->stat.rx_bytes += skb->len; 730 t->dev->stats.rx_bytes += skb->len;
733 netif_rx(skb); 731 netif_rx(skb);
734 read_unlock(&ip6_tnl_lock); 732 read_unlock(&ip6_tnl_lock);
735 return 0; 733 return 0;
@@ -849,7 +847,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
849 __u32 *pmtu) 847 __u32 *pmtu)
850{ 848{
851 struct ip6_tnl *t = netdev_priv(dev); 849 struct ip6_tnl *t = netdev_priv(dev);
852 struct net_device_stats *stats = &t->stat; 850 struct net_device_stats *stats = &t->dev->stats;
853 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 851 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
854 struct ipv6_tel_txoption opt; 852 struct ipv6_tel_txoption opt;
855 struct dst_entry *dst; 853 struct dst_entry *dst;
@@ -1043,11 +1041,11 @@ static int
1043ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) 1041ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1044{ 1042{
1045 struct ip6_tnl *t = netdev_priv(dev); 1043 struct ip6_tnl *t = netdev_priv(dev);
1046 struct net_device_stats *stats = &t->stat; 1044 struct net_device_stats *stats = &t->dev->stats;
1047 int ret; 1045 int ret;
1048 1046
1049 if (t->recursion++) { 1047 if (t->recursion++) {
1050 t->stat.collisions++; 1048 stats->collisions++;
1051 goto tx_err; 1049 goto tx_err;
1052 } 1050 }
1053 1051
@@ -1289,19 +1287,6 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1289} 1287}
1290 1288
1291/** 1289/**
1292 * ip6_tnl_get_stats - return the stats for tunnel device
1293 * @dev: virtual device associated with tunnel
1294 *
1295 * Return: stats for device
1296 **/
1297
1298static struct net_device_stats *
1299ip6_tnl_get_stats(struct net_device *dev)
1300{
1301 return &(((struct ip6_tnl *)netdev_priv(dev))->stat);
1302}
1303
1304/**
1305 * ip6_tnl_change_mtu - change mtu manually for tunnel device 1290 * ip6_tnl_change_mtu - change mtu manually for tunnel device
1306 * @dev: virtual device associated with tunnel 1291 * @dev: virtual device associated with tunnel
1307 * @new_mtu: the new mtu 1292 * @new_mtu: the new mtu
@@ -1334,7 +1319,6 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
1334 dev->uninit = ip6_tnl_dev_uninit; 1319 dev->uninit = ip6_tnl_dev_uninit;
1335 dev->destructor = free_netdev; 1320 dev->destructor = free_netdev;
1336 dev->hard_start_xmit = ip6_tnl_xmit; 1321 dev->hard_start_xmit = ip6_tnl_xmit;
1337 dev->get_stats = ip6_tnl_get_stats;
1338 dev->do_ioctl = ip6_tnl_ioctl; 1322 dev->do_ioctl = ip6_tnl_ioctl;
1339 dev->change_mtu = ip6_tnl_change_mtu; 1323 dev->change_mtu = ip6_tnl_change_mtu;
1340 1324
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 14796181e8b5..095bc453ff4c 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -388,8 +388,8 @@ static int pim6_rcv(struct sk_buff *skb)
388 skb->ip_summed = 0; 388 skb->ip_summed = 0;
389 skb->pkt_type = PACKET_HOST; 389 skb->pkt_type = PACKET_HOST;
390 dst_release(skb->dst); 390 dst_release(skb->dst);
391 ((struct net_device_stats *)netdev_priv(reg_dev))->rx_bytes += skb->len; 391 reg_dev->stats.rx_bytes += skb->len;
392 ((struct net_device_stats *)netdev_priv(reg_dev))->rx_packets++; 392 reg_dev->stats.rx_packets++;
393 skb->dst = NULL; 393 skb->dst = NULL;
394 nf_reset(skb); 394 nf_reset(skb);
395 netif_rx(skb); 395 netif_rx(skb);
@@ -409,26 +409,20 @@ static struct inet6_protocol pim6_protocol = {
409static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) 409static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
410{ 410{
411 read_lock(&mrt_lock); 411 read_lock(&mrt_lock);
412 ((struct net_device_stats *)netdev_priv(dev))->tx_bytes += skb->len; 412 dev->stats.tx_bytes += skb->len;
413 ((struct net_device_stats *)netdev_priv(dev))->tx_packets++; 413 dev->stats.tx_packets++;
414 ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT); 414 ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT);
415 read_unlock(&mrt_lock); 415 read_unlock(&mrt_lock);
416 kfree_skb(skb); 416 kfree_skb(skb);
417 return 0; 417 return 0;
418} 418}
419 419
420static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
421{
422 return (struct net_device_stats *)netdev_priv(dev);
423}
424
425static void reg_vif_setup(struct net_device *dev) 420static void reg_vif_setup(struct net_device *dev)
426{ 421{
427 dev->type = ARPHRD_PIMREG; 422 dev->type = ARPHRD_PIMREG;
428 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; 423 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
429 dev->flags = IFF_NOARP; 424 dev->flags = IFF_NOARP;
430 dev->hard_start_xmit = reg_vif_xmit; 425 dev->hard_start_xmit = reg_vif_xmit;
431 dev->get_stats = reg_vif_get_stats;
432 dev->destructor = free_netdev; 426 dev->destructor = free_netdev;
433} 427}
434 428
@@ -436,9 +430,7 @@ static struct net_device *ip6mr_reg_vif(void)
436{ 430{
437 struct net_device *dev; 431 struct net_device *dev;
438 432
439 dev = alloc_netdev(sizeof(struct net_device_stats), "pim6reg", 433 dev = alloc_netdev(0, "pim6reg", reg_vif_setup);
440 reg_vif_setup);
441
442 if (dev == NULL) 434 if (dev == NULL)
443 return NULL; 435 return NULL;
444 436
@@ -451,6 +443,7 @@ static struct net_device *ip6mr_reg_vif(void)
451 if (dev_open(dev)) 443 if (dev_open(dev))
452 goto failure; 444 goto failure;
453 445
446 dev_hold(dev);
454 return dev; 447 return dev;
455 448
456failure: 449failure:
@@ -603,6 +596,7 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock)
603 int vifi = vifc->mif6c_mifi; 596 int vifi = vifc->mif6c_mifi;
604 struct mif_device *v = &vif6_table[vifi]; 597 struct mif_device *v = &vif6_table[vifi];
605 struct net_device *dev; 598 struct net_device *dev;
599 int err;
606 600
607 /* Is vif busy ? */ 601 /* Is vif busy ? */
608 if (MIF_EXISTS(vifi)) 602 if (MIF_EXISTS(vifi))
@@ -620,20 +614,28 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock)
620 dev = ip6mr_reg_vif(); 614 dev = ip6mr_reg_vif();
621 if (!dev) 615 if (!dev)
622 return -ENOBUFS; 616 return -ENOBUFS;
617 err = dev_set_allmulti(dev, 1);
618 if (err) {
619 unregister_netdevice(dev);
620 dev_put(dev);
621 return err;
622 }
623 break; 623 break;
624#endif 624#endif
625 case 0: 625 case 0:
626 dev = dev_get_by_index(&init_net, vifc->mif6c_pifi); 626 dev = dev_get_by_index(&init_net, vifc->mif6c_pifi);
627 if (!dev) 627 if (!dev)
628 return -EADDRNOTAVAIL; 628 return -EADDRNOTAVAIL;
629 dev_put(dev); 629 err = dev_set_allmulti(dev, 1);
630 if (err) {
631 dev_put(dev);
632 return err;
633 }
630 break; 634 break;
631 default: 635 default:
632 return -EINVAL; 636 return -EINVAL;
633 } 637 }
634 638
635 dev_set_allmulti(dev, 1);
636
637 /* 639 /*
638 * Fill in the VIF structures 640 * Fill in the VIF structures
639 */ 641 */
@@ -652,7 +654,6 @@ static int mif6_add(struct mif6ctl *vifc, int mrtsock)
652 654
653 /* And finish update writing critical data */ 655 /* And finish update writing critical data */
654 write_lock_bh(&mrt_lock); 656 write_lock_bh(&mrt_lock);
655 dev_hold(dev);
656 v->dev = dev; 657 v->dev = dev;
657#ifdef CONFIG_IPV6_PIMSM_V2 658#ifdef CONFIG_IPV6_PIMSM_V2
658 if (v->flags & MIFF_REGISTER) 659 if (v->flags & MIFF_REGISTER)
@@ -934,7 +935,7 @@ static int ip6mr_device_event(struct notifier_block *this,
934 struct mif_device *v; 935 struct mif_device *v;
935 int ct; 936 int ct;
936 937
937 if (dev_net(dev) != &init_net) 938 if (!net_eq(dev_net(dev), &init_net))
938 return NOTIFY_DONE; 939 return NOTIFY_DONE;
939 940
940 if (event != NETDEV_UNREGISTER) 941 if (event != NETDEV_UNREGISTER)
@@ -956,23 +957,51 @@ static struct notifier_block ip6_mr_notifier = {
956 * Setup for IP multicast routing 957 * Setup for IP multicast routing
957 */ 958 */
958 959
959void __init ip6_mr_init(void) 960int __init ip6_mr_init(void)
960{ 961{
962 int err;
963
961 mrt_cachep = kmem_cache_create("ip6_mrt_cache", 964 mrt_cachep = kmem_cache_create("ip6_mrt_cache",
962 sizeof(struct mfc6_cache), 965 sizeof(struct mfc6_cache),
963 0, SLAB_HWCACHE_ALIGN, 966 0, SLAB_HWCACHE_ALIGN,
964 NULL); 967 NULL);
965 if (!mrt_cachep) 968 if (!mrt_cachep)
966 panic("cannot allocate ip6_mrt_cache"); 969 return -ENOMEM;
967 970
968 setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0); 971 setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
969 register_netdevice_notifier(&ip6_mr_notifier); 972 err = register_netdevice_notifier(&ip6_mr_notifier);
973 if (err)
974 goto reg_notif_fail;
975#ifdef CONFIG_PROC_FS
976 err = -ENOMEM;
977 if (!proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops))
978 goto proc_vif_fail;
979 if (!proc_net_fops_create(&init_net, "ip6_mr_cache",
980 0, &ip6mr_mfc_fops))
981 goto proc_cache_fail;
982#endif
983 return 0;
984reg_notif_fail:
985 kmem_cache_destroy(mrt_cachep);
970#ifdef CONFIG_PROC_FS 986#ifdef CONFIG_PROC_FS
971 proc_net_fops_create(&init_net, "ip6_mr_vif", 0, &ip6mr_vif_fops); 987proc_vif_fail:
972 proc_net_fops_create(&init_net, "ip6_mr_cache", 0, &ip6mr_mfc_fops); 988 unregister_netdevice_notifier(&ip6_mr_notifier);
989proc_cache_fail:
990 proc_net_remove(&init_net, "ip6_mr_vif");
973#endif 991#endif
992 return err;
974} 993}
975 994
995void ip6_mr_cleanup(void)
996{
997#ifdef CONFIG_PROC_FS
998 proc_net_remove(&init_net, "ip6_mr_cache");
999 proc_net_remove(&init_net, "ip6_mr_vif");
1000#endif
1001 unregister_netdevice_notifier(&ip6_mr_notifier);
1002 del_timer(&ipmr_expire_timer);
1003 kmem_cache_destroy(mrt_cachep);
1004}
976 1005
977static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) 1006static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
978{ 1007{
@@ -1248,7 +1277,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
1248 1277
1249#endif 1278#endif
1250 /* 1279 /*
1251 * Spurious command, or MRT_VERSION which you cannot 1280 * Spurious command, or MRT6_VERSION which you cannot
1252 * set. 1281 * set.
1253 */ 1282 */
1254 default: 1283 default:
@@ -1377,8 +1406,8 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
1377 if (vif->flags & MIFF_REGISTER) { 1406 if (vif->flags & MIFF_REGISTER) {
1378 vif->pkt_out++; 1407 vif->pkt_out++;
1379 vif->bytes_out += skb->len; 1408 vif->bytes_out += skb->len;
1380 ((struct net_device_stats *)netdev_priv(vif->dev))->tx_bytes += skb->len; 1409 vif->dev->stats.tx_bytes += skb->len;
1381 ((struct net_device_stats *)netdev_priv(vif->dev))->tx_packets++; 1410 vif->dev->stats.tx_packets++;
1382 ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT); 1411 ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT);
1383 kfree_skb(skb); 1412 kfree_skb(skb);
1384 return 0; 1413 return 0;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 86e28a75267f..ea33b26512c2 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Based on linux/net/ipv4/ip_sockglue.c 8 * Based on linux/net/ipv4/ip_sockglue.c
9 * 9 *
10 * $Id: ipv6_sockglue.c,v 1.41 2002/02/01 22:01:04 davem Exp $
11 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
@@ -61,7 +59,7 @@ DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly;
61struct ip6_ra_chain *ip6_ra_chain; 59struct ip6_ra_chain *ip6_ra_chain;
62DEFINE_RWLOCK(ip6_ra_lock); 60DEFINE_RWLOCK(ip6_ra_lock);
63 61
64int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) 62int ip6_ra_control(struct sock *sk, int sel)
65{ 63{
66 struct ip6_ra_chain *ra, *new_ra, **rap; 64 struct ip6_ra_chain *ra, *new_ra, **rap;
67 65
@@ -83,8 +81,6 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
83 *rap = ra->next; 81 *rap = ra->next;
84 write_unlock_bh(&ip6_ra_lock); 82 write_unlock_bh(&ip6_ra_lock);
85 83
86 if (ra->destructor)
87 ra->destructor(sk);
88 sock_put(sk); 84 sock_put(sk);
89 kfree(ra); 85 kfree(ra);
90 return 0; 86 return 0;
@@ -96,7 +92,6 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
96 } 92 }
97 new_ra->sk = sk; 93 new_ra->sk = sk;
98 new_ra->sel = sel; 94 new_ra->sel = sel;
99 new_ra->destructor = destructor;
100 new_ra->next = ra; 95 new_ra->next = ra;
101 *rap = new_ra; 96 *rap = new_ra;
102 sock_hold(sk); 97 sock_hold(sk);
@@ -634,7 +629,7 @@ done:
634 case IPV6_ROUTER_ALERT: 629 case IPV6_ROUTER_ALERT:
635 if (optlen < sizeof(int)) 630 if (optlen < sizeof(int))
636 goto e_inval; 631 goto e_inval;
637 retv = ip6_ra_control(sk, val, NULL); 632 retv = ip6_ra_control(sk, val);
638 break; 633 break;
639 case IPV6_MTU_DISCOVER: 634 case IPV6_MTU_DISCOVER:
640 if (optlen < sizeof(int)) 635 if (optlen < sizeof(int))
@@ -1043,7 +1038,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1043 dst_release(dst); 1038 dst_release(dst);
1044 } 1039 }
1045 if (val < 0) 1040 if (val < 0)
1046 val = ipv6_devconf.hop_limit; 1041 val = sock_net(sk)->ipv6.devconf_all->hop_limit;
1047 break; 1042 break;
1048 } 1043 }
1049 1044
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index fd632dd7f98d..e7c03bcc2788 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: mcast.c,v 1.40 2002/02/08 03:57:19 davem Exp $
9 *
10 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c 8 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -153,7 +151,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
153#define IGMP6_UNSOLICITED_IVAL (10*HZ) 151#define IGMP6_UNSOLICITED_IVAL (10*HZ)
154#define MLD_QRV_DEFAULT 2 152#define MLD_QRV_DEFAULT 2
155 153
156#define MLD_V1_SEEN(idev) (ipv6_devconf.force_mld_version == 1 || \ 154#define MLD_V1_SEEN(idev) (dev_net((idev)->dev)->ipv6.devconf_all->force_mld_version == 1 || \
157 (idev)->cnf.force_mld_version == 1 || \ 155 (idev)->cnf.force_mld_version == 1 || \
158 ((idev)->mc_v1_seen && \ 156 ((idev)->mc_v1_seen && \
159 time_before(jiffies, (idev)->mc_v1_seen))) 157 time_before(jiffies, (idev)->mc_v1_seen)))
@@ -164,7 +162,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
164 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ 162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
165 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) 163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
166 164
167#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
168#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) 165#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
169 166
170#define IPV6_MLD_MAX_MSF 64 167#define IPV6_MLD_MAX_MSF 64
@@ -370,10 +367,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
370 int pmclocked = 0; 367 int pmclocked = 0;
371 int err; 368 int err;
372 369
373 if (pgsr->gsr_group.ss_family != AF_INET6 ||
374 pgsr->gsr_source.ss_family != AF_INET6)
375 return -EINVAL;
376
377 source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr; 370 source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
378 group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr; 371 group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr;
379 372
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 282fdb31f8ed..beb48e3f038a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -784,15 +784,17 @@ static void ndisc_recv_ns(struct sk_buff *skb)
784 784
785 idev = ifp->idev; 785 idev = ifp->idev;
786 } else { 786 } else {
787 struct net *net = dev_net(dev);
788
787 idev = in6_dev_get(dev); 789 idev = in6_dev_get(dev);
788 if (!idev) { 790 if (!idev) {
789 /* XXX: count this drop? */ 791 /* XXX: count this drop? */
790 return; 792 return;
791 } 793 }
792 794
793 if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) || 795 if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
794 (idev->cnf.forwarding && 796 (idev->cnf.forwarding &&
795 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && 797 (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
796 (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) { 798 (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
797 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && 799 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
798 skb->pkt_type != PACKET_HOST && 800 skb->pkt_type != PACKET_HOST &&
@@ -921,6 +923,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
921 923
922 if (neigh) { 924 if (neigh) {
923 u8 old_flags = neigh->flags; 925 u8 old_flags = neigh->flags;
926 struct net *net = dev_net(dev);
924 927
925 if (neigh->nud_state & NUD_FAILED) 928 if (neigh->nud_state & NUD_FAILED)
926 goto out; 929 goto out;
@@ -931,8 +934,8 @@ static void ndisc_recv_na(struct sk_buff *skb)
931 * has already sent a NA to us. 934 * has already sent a NA to us.
932 */ 935 */
933 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && 936 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
934 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && 937 net->ipv6.devconf_all->forwarding && net->ipv6.devconf_all->proxy_ndp &&
935 pneigh_lookup(&nd_tbl, dev_net(dev), &msg->target, dev, 0)) { 938 pneigh_lookup(&nd_tbl, net, &msg->target, dev, 0)) {
936 /* XXX: idev->cnf.prixy_ndp */ 939 /* XXX: idev->cnf.prixy_ndp */
937 goto out; 940 goto out;
938 } 941 }
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 6cae5475737e..689dec899c57 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -208,5 +208,17 @@ config IP6_NF_RAW
208 If you want to compile it as a module, say M here and read 208 If you want to compile it as a module, say M here and read
209 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 209 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
210 210
211# security table for MAC policy
212config IP6_NF_SECURITY
213 tristate "Security table"
214 depends on IP6_NF_IPTABLES
215 depends on SECURITY
216 default m if NETFILTER_ADVANCED=n
217 help
218 This option adds a `security' table to iptables, for use
219 with Mandatory Access Control (MAC) policy.
220
221 If unsure, say N.
222
211endmenu 223endmenu
212 224
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index fbf2c14ed887..3f17c948eefb 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_QUEUE) += ip6_queue.o 9obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
10obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 10obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
11obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
11 12
12# objects for l3 independent conntrack 13# objects for l3 independent conntrack
13nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o 14nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 2eff3ae8977d..5859c046cbc4 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -159,7 +159,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
159 case IPQ_COPY_META: 159 case IPQ_COPY_META:
160 case IPQ_COPY_NONE: 160 case IPQ_COPY_NONE:
161 size = NLMSG_SPACE(sizeof(*pmsg)); 161 size = NLMSG_SPACE(sizeof(*pmsg));
162 data_len = 0;
163 break; 162 break;
164 163
165 case IPQ_COPY_PACKET: 164 case IPQ_COPY_PACKET:
@@ -226,8 +225,6 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
226 return skb; 225 return skb;
227 226
228nlmsg_failure: 227nlmsg_failure:
229 if (skb)
230 kfree_skb(skb);
231 *errp = -EINVAL; 228 *errp = -EINVAL;
232 printk(KERN_ERR "ip6_queue: error creating packet message\n"); 229 printk(KERN_ERR "ip6_queue: error creating packet message\n");
233 return NULL; 230 return NULL;
@@ -483,7 +480,7 @@ ipq_rcv_dev_event(struct notifier_block *this,
483{ 480{
484 struct net_device *dev = ptr; 481 struct net_device *dev = ptr;
485 482
486 if (dev_net(dev) != &init_net) 483 if (!net_eq(dev_net(dev), &init_net))
487 return NOTIFY_DONE; 484 return NOTIFY_DONE;
488 485
489 /* Drop any packets associated with the downed device */ 486 /* Drop any packets associated with the downed device */
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index f979e48b469b..55a2c290bad4 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -61,13 +61,25 @@ static struct xt_table packet_filter = {
61 61
62/* The work comes in here from netfilter.c. */ 62/* The work comes in here from netfilter.c. */
63static unsigned int 63static unsigned int
64ip6t_hook(unsigned int hook, 64ip6t_local_in_hook(unsigned int hook,
65 struct sk_buff *skb, 65 struct sk_buff *skb,
66 const struct net_device *in, 66 const struct net_device *in,
67 const struct net_device *out, 67 const struct net_device *out,
68 int (*okfn)(struct sk_buff *)) 68 int (*okfn)(struct sk_buff *))
69{
70 return ip6t_do_table(skb, hook, in, out,
71 nf_local_in_net(in, out)->ipv6.ip6table_filter);
72}
73
74static unsigned int
75ip6t_forward_hook(unsigned int hook,
76 struct sk_buff *skb,
77 const struct net_device *in,
78 const struct net_device *out,
79 int (*okfn)(struct sk_buff *))
69{ 80{
70 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter); 81 return ip6t_do_table(skb, hook, in, out,
82 nf_forward_net(in, out)->ipv6.ip6table_filter);
71} 83}
72 84
73static unsigned int 85static unsigned int
@@ -87,19 +99,20 @@ ip6t_local_out_hook(unsigned int hook,
87 } 99 }
88#endif 100#endif
89 101
90 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter); 102 return ip6t_do_table(skb, hook, in, out,
103 nf_local_out_net(in, out)->ipv6.ip6table_filter);
91} 104}
92 105
93static struct nf_hook_ops ip6t_ops[] __read_mostly = { 106static struct nf_hook_ops ip6t_ops[] __read_mostly = {
94 { 107 {
95 .hook = ip6t_hook, 108 .hook = ip6t_local_in_hook,
96 .owner = THIS_MODULE, 109 .owner = THIS_MODULE,
97 .pf = PF_INET6, 110 .pf = PF_INET6,
98 .hooknum = NF_INET_LOCAL_IN, 111 .hooknum = NF_INET_LOCAL_IN,
99 .priority = NF_IP6_PRI_FILTER, 112 .priority = NF_IP6_PRI_FILTER,
100 }, 113 },
101 { 114 {
102 .hook = ip6t_hook, 115 .hook = ip6t_forward_hook,
103 .owner = THIS_MODULE, 116 .owner = THIS_MODULE,
104 .pf = PF_INET6, 117 .pf = PF_INET6,
105 .hooknum = NF_INET_FORWARD, 118 .hooknum = NF_INET_FORWARD,
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
new file mode 100644
index 000000000000..a07abee30497
--- /dev/null
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -0,0 +1,172 @@
1/*
2 * "security" table for IPv6
3 *
4 * This is for use by Mandatory Access Control (MAC) security models,
5 * which need to be able to manage security policy in separate context
6 * to DAC.
7 *
8 * Based on iptable_mangle.c
9 *
10 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
11 * Copyright (C) 2000-2004 Netfilter Core Team <coreteam <at> netfilter.org>
12 * Copyright (C) 2008 Red Hat, Inc., James Morris <jmorris <at> redhat.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/module.h>
19#include <linux/netfilter_ipv6/ip6_tables.h>
20
21MODULE_LICENSE("GPL");
22MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>");
23MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
24
25#define SECURITY_VALID_HOOKS (1 << NF_INET_LOCAL_IN) | \
26 (1 << NF_INET_FORWARD) | \
27 (1 << NF_INET_LOCAL_OUT)
28
29static struct
30{
31 struct ip6t_replace repl;
32 struct ip6t_standard entries[3];
33 struct ip6t_error term;
34} initial_table __initdata = {
35 .repl = {
36 .name = "security",
37 .valid_hooks = SECURITY_VALID_HOOKS,
38 .num_entries = 4,
39 .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
40 .hook_entry = {
41 [NF_INET_LOCAL_IN] = 0,
42 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
43 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
44 },
45 .underflow = {
46 [NF_INET_LOCAL_IN] = 0,
47 [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
48 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2,
49 },
50 },
51 .entries = {
52 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
53 IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
54 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
55 },
56 .term = IP6T_ERROR_INIT, /* ERROR */
57};
58
59static struct xt_table security_table = {
60 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS,
62 .lock = __RW_LOCK_UNLOCKED(security_table.lock),
63 .me = THIS_MODULE,
64 .af = AF_INET6,
65};
66
67static unsigned int
68ip6t_local_in_hook(unsigned int hook,
69 struct sk_buff *skb,
70 const struct net_device *in,
71 const struct net_device *out,
72 int (*okfn)(struct sk_buff *))
73{
74 return ip6t_do_table(skb, hook, in, out,
75 nf_local_in_net(in, out)->ipv6.ip6table_security);
76}
77
78static unsigned int
79ip6t_forward_hook(unsigned int hook,
80 struct sk_buff *skb,
81 const struct net_device *in,
82 const struct net_device *out,
83 int (*okfn)(struct sk_buff *))
84{
85 return ip6t_do_table(skb, hook, in, out,
86 nf_forward_net(in, out)->ipv6.ip6table_security);
87}
88
89static unsigned int
90ip6t_local_out_hook(unsigned int hook,
91 struct sk_buff *skb,
92 const struct net_device *in,
93 const struct net_device *out,
94 int (*okfn)(struct sk_buff *))
95{
96 /* TBD: handle short packets via raw socket */
97 return ip6t_do_table(skb, hook, in, out,
98 nf_local_out_net(in, out)->ipv6.ip6table_security);
99}
100
101static struct nf_hook_ops ip6t_ops[] __read_mostly = {
102 {
103 .hook = ip6t_local_in_hook,
104 .owner = THIS_MODULE,
105 .pf = PF_INET6,
106 .hooknum = NF_INET_LOCAL_IN,
107 .priority = NF_IP6_PRI_SECURITY,
108 },
109 {
110 .hook = ip6t_forward_hook,
111 .owner = THIS_MODULE,
112 .pf = PF_INET6,
113 .hooknum = NF_INET_FORWARD,
114 .priority = NF_IP6_PRI_SECURITY,
115 },
116 {
117 .hook = ip6t_local_out_hook,
118 .owner = THIS_MODULE,
119 .pf = PF_INET6,
120 .hooknum = NF_INET_LOCAL_OUT,
121 .priority = NF_IP6_PRI_SECURITY,
122 },
123};
124
125static int __net_init ip6table_security_net_init(struct net *net)
126{
127 net->ipv6.ip6table_security =
128 ip6t_register_table(net, &security_table, &initial_table.repl);
129
130 if (IS_ERR(net->ipv6.ip6table_security))
131 return PTR_ERR(net->ipv6.ip6table_security);
132
133 return 0;
134}
135
136static void __net_exit ip6table_security_net_exit(struct net *net)
137{
138 ip6t_unregister_table(net->ipv6.ip6table_security);
139}
140
141static struct pernet_operations ip6table_security_net_ops = {
142 .init = ip6table_security_net_init,
143 .exit = ip6table_security_net_exit,
144};
145
146static int __init ip6table_security_init(void)
147{
148 int ret;
149
150 ret = register_pernet_subsys(&ip6table_security_net_ops);
151 if (ret < 0)
152 return ret;
153
154 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
155 if (ret < 0)
156 goto cleanup_table;
157
158 return ret;
159
160cleanup_table:
161 unregister_pernet_subsys(&ip6table_security_net_ops);
162 return ret;
163}
164
165static void __exit ip6table_security_fini(void)
166{
167 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
168 unregister_pernet_subsys(&ip6table_security_net_ops);
169}
170
171module_init(ip6table_security_init);
172module_exit(ip6table_security_fini);
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index ee713b03e9ec..14d47d833545 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -89,9 +89,8 @@ static int icmpv6_packet(struct nf_conn *ct,
89 means this will only run once even if count hits zero twice 89 means this will only run once even if count hits zero twice
90 (theoretically possible with SMP) */ 90 (theoretically possible with SMP) */
91 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { 91 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
92 if (atomic_dec_and_test(&ct->proto.icmp.count) 92 if (atomic_dec_and_test(&ct->proto.icmp.count))
93 && del_timer(&ct->timeout)) 93 nf_ct_kill_acct(ct, ctinfo, skb);
94 ct->timeout.function((unsigned long)ct);
95 } else { 94 } else {
96 atomic_inc(&ct->proto.icmp.count); 95 atomic_inc(&ct->proto.icmp.count);
97 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index df0736a4cafa..f82f6074cf85 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -7,8 +7,6 @@
7 * PROC file system. This is very similar to the IPv4 version, 7 * PROC file system. This is very similar to the IPv4 version,
8 * except it reports the sockets in the INET6 address family. 8 * except it reports the sockets in the INET6 address family.
9 * 9 *
10 * Version: $Id: proc.c,v 1.17 2002/02/01 22:01:04 davem Exp $
11 *
12 * Authors: David S. Miller (davem@caip.rutgers.edu) 10 * Authors: David S. Miller (davem@caip.rutgers.edu)
13 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> 11 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
14 * 12 *
@@ -185,32 +183,7 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
185 183
186static int sockstat6_seq_open(struct inode *inode, struct file *file) 184static int sockstat6_seq_open(struct inode *inode, struct file *file)
187{ 185{
188 int err; 186 return single_open_net(inode, file, sockstat6_seq_show);
189 struct net *net;
190
191 err = -ENXIO;
192 net = get_proc_net(inode);
193 if (net == NULL)
194 goto err_net;
195
196 err = single_open(file, sockstat6_seq_show, net);
197 if (err < 0)
198 goto err_open;
199
200 return 0;
201
202err_open:
203 put_net(net);
204err_net:
205 return err;
206}
207
208static int sockstat6_seq_release(struct inode *inode, struct file *file)
209{
210 struct net *net = ((struct seq_file *)file->private_data)->private;
211
212 put_net(net);
213 return single_release(inode, file);
214} 187}
215 188
216static const struct file_operations sockstat6_seq_fops = { 189static const struct file_operations sockstat6_seq_fops = {
@@ -218,7 +191,7 @@ static const struct file_operations sockstat6_seq_fops = {
218 .open = sockstat6_seq_open, 191 .open = sockstat6_seq_open,
219 .read = seq_read, 192 .read = seq_read,
220 .llseek = seq_lseek, 193 .llseek = seq_lseek,
221 .release = sockstat6_seq_release, 194 .release = single_release_net,
222}; 195};
223 196
224static int snmp6_seq_open(struct inode *inode, struct file *file) 197static int snmp6_seq_open(struct inode *inode, struct file *file)
@@ -241,7 +214,7 @@ int snmp6_register_dev(struct inet6_dev *idev)
241 if (!idev || !idev->dev) 214 if (!idev || !idev->dev)
242 return -EINVAL; 215 return -EINVAL;
243 216
244 if (dev_net(idev->dev) != &init_net) 217 if (!net_eq(dev_net(idev->dev), &init_net))
245 return 0; 218 return 0;
246 219
247 if (!proc_net_devsnmp6) 220 if (!proc_net_devsnmp6)
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index f929f47b925e..9ab789159913 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * PF_INET6 protocol dispatch tables. 6 * PF_INET6 protocol dispatch tables.
7 * 7 *
8 * Version: $Id: protocol.c,v 1.10 2001/05/18 02:25:49 davem Exp $
9 *
10 * Authors: Pedro Roque <roque@di.fc.ul.pt> 8 * Authors: Pedro Roque <roque@di.fc.ul.pt>
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 3aee12310d94..01d47674f7e5 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Adapted from linux/net/ipv4/raw.c 8 * Adapted from linux/net/ipv4/raw.c
9 * 9 *
10 * $Id: raw.c,v 1.51 2002/02/01 22:01:04 davem Exp $
11 *
12 * Fixes: 10 * Fixes:
13 * Hideaki YOSHIFUJI : sin6_scope_id support 11 * Hideaki YOSHIFUJI : sin6_scope_id support
14 * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) 12 * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance)
@@ -1159,18 +1157,18 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
1159static void rawv6_close(struct sock *sk, long timeout) 1157static void rawv6_close(struct sock *sk, long timeout)
1160{ 1158{
1161 if (inet_sk(sk)->num == IPPROTO_RAW) 1159 if (inet_sk(sk)->num == IPPROTO_RAW)
1162 ip6_ra_control(sk, -1, NULL); 1160 ip6_ra_control(sk, -1);
1163 ip6mr_sk_done(sk); 1161 ip6mr_sk_done(sk);
1164 sk_common_release(sk); 1162 sk_common_release(sk);
1165} 1163}
1166 1164
1167static int raw6_destroy(struct sock *sk) 1165static void raw6_destroy(struct sock *sk)
1168{ 1166{
1169 lock_sock(sk); 1167 lock_sock(sk);
1170 ip6_flush_pending_frames(sk); 1168 ip6_flush_pending_frames(sk);
1171 release_sock(sk); 1169 release_sock(sk);
1172 1170
1173 return inet6_destroy_sock(sk); 1171 inet6_destroy_sock(sk);
1174} 1172}
1175 1173
1176static int rawv6_init_sk(struct sock *sk) 1174static int rawv6_init_sk(struct sock *sk)
@@ -1253,7 +1251,7 @@ static int raw6_seq_show(struct seq_file *seq, void *v)
1253 "local_address " 1251 "local_address "
1254 "remote_address " 1252 "remote_address "
1255 "st tx_queue rx_queue tr tm->when retrnsmt" 1253 "st tx_queue rx_queue tr tm->when retrnsmt"
1256 " uid timeout inode drops\n"); 1254 " uid timeout inode ref pointer drops\n");
1257 else 1255 else
1258 raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket); 1256 raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
1259 return 0; 1257 return 0;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index a60d7d129713..6ab957ec2dd6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: reassembly.c,v 1.26 2001/03/07 22:00:57 davem Exp $
9 *
10 * Based on: net/ipv4/ip_fragment.c 8 * Based on: net/ipv4/ip_fragment.c
11 * 9 *
12 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
@@ -634,7 +632,7 @@ static struct inet6_protocol frag_protocol =
634}; 632};
635 633
636#ifdef CONFIG_SYSCTL 634#ifdef CONFIG_SYSCTL
637static struct ctl_table ip6_frags_ctl_table[] = { 635static struct ctl_table ip6_frags_ns_ctl_table[] = {
638 { 636 {
639 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH, 637 .ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
640 .procname = "ip6frag_high_thresh", 638 .procname = "ip6frag_high_thresh",
@@ -660,6 +658,10 @@ static struct ctl_table ip6_frags_ctl_table[] = {
660 .proc_handler = &proc_dointvec_jiffies, 658 .proc_handler = &proc_dointvec_jiffies,
661 .strategy = &sysctl_jiffies, 659 .strategy = &sysctl_jiffies,
662 }, 660 },
661 { }
662};
663
664static struct ctl_table ip6_frags_ctl_table[] = {
663 { 665 {
664 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL, 666 .ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
665 .procname = "ip6frag_secret_interval", 667 .procname = "ip6frag_secret_interval",
@@ -672,21 +674,20 @@ static struct ctl_table ip6_frags_ctl_table[] = {
672 { } 674 { }
673}; 675};
674 676
675static int ip6_frags_sysctl_register(struct net *net) 677static int ip6_frags_ns_sysctl_register(struct net *net)
676{ 678{
677 struct ctl_table *table; 679 struct ctl_table *table;
678 struct ctl_table_header *hdr; 680 struct ctl_table_header *hdr;
679 681
680 table = ip6_frags_ctl_table; 682 table = ip6_frags_ns_ctl_table;
681 if (net != &init_net) { 683 if (net != &init_net) {
682 table = kmemdup(table, sizeof(ip6_frags_ctl_table), GFP_KERNEL); 684 table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL);
683 if (table == NULL) 685 if (table == NULL)
684 goto err_alloc; 686 goto err_alloc;
685 687
686 table[0].data = &net->ipv6.frags.high_thresh; 688 table[0].data = &net->ipv6.frags.high_thresh;
687 table[1].data = &net->ipv6.frags.low_thresh; 689 table[1].data = &net->ipv6.frags.low_thresh;
688 table[2].data = &net->ipv6.frags.timeout; 690 table[2].data = &net->ipv6.frags.timeout;
689 table[3].mode &= ~0222;
690 } 691 }
691 692
692 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table); 693 hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table);
@@ -703,7 +704,7 @@ err_alloc:
703 return -ENOMEM; 704 return -ENOMEM;
704} 705}
705 706
706static void ip6_frags_sysctl_unregister(struct net *net) 707static void ip6_frags_ns_sysctl_unregister(struct net *net)
707{ 708{
708 struct ctl_table *table; 709 struct ctl_table *table;
709 710
@@ -711,13 +712,36 @@ static void ip6_frags_sysctl_unregister(struct net *net)
711 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr); 712 unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
712 kfree(table); 713 kfree(table);
713} 714}
715
716static struct ctl_table_header *ip6_ctl_header;
717
718static int ip6_frags_sysctl_register(void)
719{
720 ip6_ctl_header = register_net_sysctl_rotable(net_ipv6_ctl_path,
721 ip6_frags_ctl_table);
722 return ip6_ctl_header == NULL ? -ENOMEM : 0;
723}
724
725static void ip6_frags_sysctl_unregister(void)
726{
727 unregister_net_sysctl_table(ip6_ctl_header);
728}
714#else 729#else
715static inline int ip6_frags_sysctl_register(struct net *net) 730static inline int ip6_frags_ns_sysctl_register(struct net *net)
716{ 731{
717 return 0; 732 return 0;
718} 733}
719 734
720static inline void ip6_frags_sysctl_unregister(struct net *net) 735static inline void ip6_frags_ns_sysctl_unregister(struct net *net)
736{
737}
738
739static inline int ip6_frags_sysctl_register(void)
740{
741 return 0;
742}
743
744static inline void ip6_frags_sysctl_unregister(void)
721{ 745{
722} 746}
723#endif 747#endif
@@ -730,12 +754,12 @@ static int ipv6_frags_init_net(struct net *net)
730 754
731 inet_frags_init_net(&net->ipv6.frags); 755 inet_frags_init_net(&net->ipv6.frags);
732 756
733 return ip6_frags_sysctl_register(net); 757 return ip6_frags_ns_sysctl_register(net);
734} 758}
735 759
736static void ipv6_frags_exit_net(struct net *net) 760static void ipv6_frags_exit_net(struct net *net)
737{ 761{
738 ip6_frags_sysctl_unregister(net); 762 ip6_frags_ns_sysctl_unregister(net);
739 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags); 763 inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
740} 764}
741 765
@@ -752,7 +776,13 @@ int __init ipv6_frag_init(void)
752 if (ret) 776 if (ret)
753 goto out; 777 goto out;
754 778
755 register_pernet_subsys(&ip6_frags_ops); 779 ret = ip6_frags_sysctl_register();
780 if (ret)
781 goto err_sysctl;
782
783 ret = register_pernet_subsys(&ip6_frags_ops);
784 if (ret)
785 goto err_pernet;
756 786
757 ip6_frags.hashfn = ip6_hashfn; 787 ip6_frags.hashfn = ip6_hashfn;
758 ip6_frags.constructor = ip6_frag_init; 788 ip6_frags.constructor = ip6_frag_init;
@@ -765,11 +795,18 @@ int __init ipv6_frag_init(void)
765 inet_frags_init(&ip6_frags); 795 inet_frags_init(&ip6_frags);
766out: 796out:
767 return ret; 797 return ret;
798
799err_pernet:
800 ip6_frags_sysctl_unregister();
801err_sysctl:
802 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
803 goto out;
768} 804}
769 805
770void ipv6_frag_exit(void) 806void ipv6_frag_exit(void)
771{ 807{
772 inet_frags_fini(&ip6_frags); 808 inet_frags_fini(&ip6_frags);
809 ip6_frags_sysctl_unregister();
773 unregister_pernet_subsys(&ip6_frags_ops); 810 unregister_pernet_subsys(&ip6_frags_ops);
774 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT); 811 inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
775} 812}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7ff687020fa9..615b328de251 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: route.c,v 1.56 2001/10/31 21:55:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -230,7 +228,7 @@ static __inline__ int rt6_check_expired(const struct rt6_info *rt)
230static inline int rt6_need_strict(struct in6_addr *daddr) 228static inline int rt6_need_strict(struct in6_addr *daddr)
231{ 229{
232 return (ipv6_addr_type(daddr) & 230 return (ipv6_addr_type(daddr) &
233 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); 231 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK));
234} 232}
235 233
236/* 234/*
@@ -239,15 +237,20 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
239 237
240static inline struct rt6_info *rt6_device_match(struct net *net, 238static inline struct rt6_info *rt6_device_match(struct net *net,
241 struct rt6_info *rt, 239 struct rt6_info *rt,
240 struct in6_addr *saddr,
242 int oif, 241 int oif,
243 int flags) 242 int flags)
244{ 243{
245 struct rt6_info *local = NULL; 244 struct rt6_info *local = NULL;
246 struct rt6_info *sprt; 245 struct rt6_info *sprt;
247 246
248 if (oif) { 247 if (!oif && ipv6_addr_any(saddr))
249 for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) { 248 goto out;
250 struct net_device *dev = sprt->rt6i_dev; 249
250 for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) {
251 struct net_device *dev = sprt->rt6i_dev;
252
253 if (oif) {
251 if (dev->ifindex == oif) 254 if (dev->ifindex == oif)
252 return sprt; 255 return sprt;
253 if (dev->flags & IFF_LOOPBACK) { 256 if (dev->flags & IFF_LOOPBACK) {
@@ -261,14 +264,21 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
261 } 264 }
262 local = sprt; 265 local = sprt;
263 } 266 }
267 } else {
268 if (ipv6_chk_addr(net, saddr, dev,
269 flags & RT6_LOOKUP_F_IFACE))
270 return sprt;
264 } 271 }
272 }
265 273
274 if (oif) {
266 if (local) 275 if (local)
267 return local; 276 return local;
268 277
269 if (flags & RT6_LOOKUP_F_IFACE) 278 if (flags & RT6_LOOKUP_F_IFACE)
270 return net->ipv6.ip6_null_entry; 279 return net->ipv6.ip6_null_entry;
271 } 280 }
281out:
272 return rt; 282 return rt;
273} 283}
274 284
@@ -541,7 +551,7 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
541 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); 551 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
542restart: 552restart:
543 rt = fn->leaf; 553 rt = fn->leaf;
544 rt = rt6_device_match(net, rt, fl->oif, flags); 554 rt = rt6_device_match(net, rt, &fl->fl6_src, fl->oif, flags);
545 BACKTRACK(net, &fl->fl6_src); 555 BACKTRACK(net, &fl->fl6_src);
546out: 556out:
547 dst_use(&rt->u.dst, jiffies); 557 dst_use(&rt->u.dst, jiffies);
@@ -666,7 +676,7 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
666 int strict = 0; 676 int strict = 0;
667 int attempts = 3; 677 int attempts = 3;
668 int err; 678 int err;
669 int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; 679 int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
670 680
671 strict |= flags & RT6_LOOKUP_F_IFACE; 681 strict |= flags & RT6_LOOKUP_F_IFACE;
672 682
@@ -1048,7 +1058,7 @@ int ip6_dst_hoplimit(struct dst_entry *dst)
1048 hoplimit = idev->cnf.hop_limit; 1058 hoplimit = idev->cnf.hop_limit;
1049 in6_dev_put(idev); 1059 in6_dev_put(idev);
1050 } else 1060 } else
1051 hoplimit = ipv6_devconf.hop_limit; 1061 hoplimit = dev_net(dev)->ipv6.devconf_all->hop_limit;
1052 } 1062 }
1053 return hoplimit; 1063 return hoplimit;
1054} 1064}
@@ -2406,26 +2416,7 @@ static int ipv6_route_show(struct seq_file *m, void *v)
2406 2416
2407static int ipv6_route_open(struct inode *inode, struct file *file) 2417static int ipv6_route_open(struct inode *inode, struct file *file)
2408{ 2418{
2409 int err; 2419 return single_open_net(inode, file, ipv6_route_show);
2410 struct net *net = get_proc_net(inode);
2411 if (!net)
2412 return -ENXIO;
2413
2414 err = single_open(file, ipv6_route_show, net);
2415 if (err < 0) {
2416 put_net(net);
2417 return err;
2418 }
2419
2420 return 0;
2421}
2422
2423static int ipv6_route_release(struct inode *inode, struct file *file)
2424{
2425 struct seq_file *seq = file->private_data;
2426 struct net *net = seq->private;
2427 put_net(net);
2428 return single_release(inode, file);
2429} 2420}
2430 2421
2431static const struct file_operations ipv6_route_proc_fops = { 2422static const struct file_operations ipv6_route_proc_fops = {
@@ -2433,7 +2424,7 @@ static const struct file_operations ipv6_route_proc_fops = {
2433 .open = ipv6_route_open, 2424 .open = ipv6_route_open,
2434 .read = seq_read, 2425 .read = seq_read,
2435 .llseek = seq_lseek, 2426 .llseek = seq_lseek,
2436 .release = ipv6_route_release, 2427 .release = single_release_net,
2437}; 2428};
2438 2429
2439static int rt6_stats_seq_show(struct seq_file *seq, void *v) 2430static int rt6_stats_seq_show(struct seq_file *seq, void *v)
@@ -2453,26 +2444,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
2453 2444
2454static int rt6_stats_seq_open(struct inode *inode, struct file *file) 2445static int rt6_stats_seq_open(struct inode *inode, struct file *file)
2455{ 2446{
2456 int err; 2447 return single_open_net(inode, file, rt6_stats_seq_show);
2457 struct net *net = get_proc_net(inode);
2458 if (!net)
2459 return -ENXIO;
2460
2461 err = single_open(file, rt6_stats_seq_show, net);
2462 if (err < 0) {
2463 put_net(net);
2464 return err;
2465 }
2466
2467 return 0;
2468}
2469
2470static int rt6_stats_seq_release(struct inode *inode, struct file *file)
2471{
2472 struct seq_file *seq = file->private_data;
2473 struct net *net = (struct net *)seq->private;
2474 put_net(net);
2475 return single_release(inode, file);
2476} 2448}
2477 2449
2478static const struct file_operations rt6_stats_seq_fops = { 2450static const struct file_operations rt6_stats_seq_fops = {
@@ -2480,7 +2452,7 @@ static const struct file_operations rt6_stats_seq_fops = {
2480 .open = rt6_stats_seq_open, 2452 .open = rt6_stats_seq_open,
2481 .read = seq_read, 2453 .read = seq_read,
2482 .llseek = seq_lseek, 2454 .llseek = seq_lseek,
2483 .release = rt6_stats_seq_release, 2455 .release = single_release_net,
2484}; 2456};
2485#endif /* CONFIG_PROC_FS */ 2457#endif /* CONFIG_PROC_FS */
2486 2458
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 32e871a6c25a..b7a50e968506 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -6,8 +6,6 @@
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 * 8 *
9 * $Id: sit.c,v 1.53 2001/09/25 05:09:53 davem Exp $
10 *
11 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 11 * as published by the Free Software Foundation; either version
@@ -493,13 +491,13 @@ static int ipip6_rcv(struct sk_buff *skb)
493 491
494 if ((tunnel->dev->priv_flags & IFF_ISATAP) && 492 if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
495 !isatap_chksrc(skb, iph, tunnel)) { 493 !isatap_chksrc(skb, iph, tunnel)) {
496 tunnel->stat.rx_errors++; 494 tunnel->dev->stats.rx_errors++;
497 read_unlock(&ipip6_lock); 495 read_unlock(&ipip6_lock);
498 kfree_skb(skb); 496 kfree_skb(skb);
499 return 0; 497 return 0;
500 } 498 }
501 tunnel->stat.rx_packets++; 499 tunnel->dev->stats.rx_packets++;
502 tunnel->stat.rx_bytes += skb->len; 500 tunnel->dev->stats.rx_bytes += skb->len;
503 skb->dev = tunnel->dev; 501 skb->dev = tunnel->dev;
504 dst_release(skb->dst); 502 dst_release(skb->dst);
505 skb->dst = NULL; 503 skb->dst = NULL;
@@ -539,7 +537,7 @@ static inline __be32 try_6to4(struct in6_addr *v6dst)
539static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 537static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
540{ 538{
541 struct ip_tunnel *tunnel = netdev_priv(dev); 539 struct ip_tunnel *tunnel = netdev_priv(dev);
542 struct net_device_stats *stats = &tunnel->stat; 540 struct net_device_stats *stats = &tunnel->dev->stats;
543 struct iphdr *tiph = &tunnel->parms.iph; 541 struct iphdr *tiph = &tunnel->parms.iph;
544 struct ipv6hdr *iph6 = ipv6_hdr(skb); 542 struct ipv6hdr *iph6 = ipv6_hdr(skb);
545 u8 tos = tunnel->parms.iph.tos; 543 u8 tos = tunnel->parms.iph.tos;
@@ -553,7 +551,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
553 int addr_type; 551 int addr_type;
554 552
555 if (tunnel->recursion++) { 553 if (tunnel->recursion++) {
556 tunnel->stat.collisions++; 554 stats->collisions++;
557 goto tx_error; 555 goto tx_error;
558 } 556 }
559 557
@@ -620,20 +618,20 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
620 .oif = tunnel->parms.link, 618 .oif = tunnel->parms.link,
621 .proto = IPPROTO_IPV6 }; 619 .proto = IPPROTO_IPV6 };
622 if (ip_route_output_key(dev_net(dev), &rt, &fl)) { 620 if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
623 tunnel->stat.tx_carrier_errors++; 621 stats->tx_carrier_errors++;
624 goto tx_error_icmp; 622 goto tx_error_icmp;
625 } 623 }
626 } 624 }
627 if (rt->rt_type != RTN_UNICAST) { 625 if (rt->rt_type != RTN_UNICAST) {
628 ip_rt_put(rt); 626 ip_rt_put(rt);
629 tunnel->stat.tx_carrier_errors++; 627 stats->tx_carrier_errors++;
630 goto tx_error_icmp; 628 goto tx_error_icmp;
631 } 629 }
632 tdev = rt->u.dst.dev; 630 tdev = rt->u.dst.dev;
633 631
634 if (tdev == dev) { 632 if (tdev == dev) {
635 ip_rt_put(rt); 633 ip_rt_put(rt);
636 tunnel->stat.collisions++; 634 stats->collisions++;
637 goto tx_error; 635 goto tx_error;
638 } 636 }
639 637
@@ -643,7 +641,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
643 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; 641 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
644 642
645 if (mtu < 68) { 643 if (mtu < 68) {
646 tunnel->stat.collisions++; 644 stats->collisions++;
647 ip_rt_put(rt); 645 ip_rt_put(rt);
648 goto tx_error; 646 goto tx_error;
649 } 647 }
@@ -920,11 +918,6 @@ done:
920 return err; 918 return err;
921} 919}
922 920
923static struct net_device_stats *ipip6_tunnel_get_stats(struct net_device *dev)
924{
925 return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
926}
927
928static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) 921static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
929{ 922{
930 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr)) 923 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr))
@@ -938,7 +931,6 @@ static void ipip6_tunnel_setup(struct net_device *dev)
938 dev->uninit = ipip6_tunnel_uninit; 931 dev->uninit = ipip6_tunnel_uninit;
939 dev->destructor = free_netdev; 932 dev->destructor = free_netdev;
940 dev->hard_start_xmit = ipip6_tunnel_xmit; 933 dev->hard_start_xmit = ipip6_tunnel_xmit;
941 dev->get_stats = ipip6_tunnel_get_stats;
942 dev->do_ioctl = ipip6_tunnel_ioctl; 934 dev->do_ioctl = ipip6_tunnel_ioctl;
943 dev->change_mtu = ipip6_tunnel_change_mtu; 935 dev->change_mtu = ipip6_tunnel_change_mtu;
944 936
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 3ecc1157994e..6a68eeb7bbf8 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -137,7 +137,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
137 ; 137 ;
138 *mssp = msstab[mssind] + 1; 138 *mssp = msstab[mssind] + 1;
139 139
140 NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESSENT); 140 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT);
141 141
142 return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source, 142 return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source,
143 th->dest, ntohl(th->seq), 143 th->dest, ntohl(th->seq),
@@ -177,11 +177,11 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
177 177
178 if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || 178 if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) ||
179 (mss = cookie_check(skb, cookie)) == 0) { 179 (mss = cookie_check(skb, cookie)) == 0) {
180 NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESFAILED); 180 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
181 goto out; 181 goto out;
182 } 182 }
183 183
184 NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV); 184 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
185 185
186 /* check for timestamp cookie support */ 186 /* check for timestamp cookie support */
187 memset(&tcp_opt, 0, sizeof(tcp_opt)); 187 memset(&tcp_opt, 0, sizeof(tcp_opt));
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 3804dcbbfab0..5c99274558bf 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -37,6 +37,10 @@ static ctl_table ipv6_table_template[] = {
37 .mode = 0644, 37 .mode = 0644,
38 .proc_handler = &proc_dointvec 38 .proc_handler = &proc_dointvec
39 }, 39 },
40 { .ctl_name = 0 }
41};
42
43static ctl_table ipv6_table[] = {
40 { 44 {
41 .ctl_name = NET_IPV6_MLD_MAX_MSF, 45 .ctl_name = NET_IPV6_MLD_MAX_MSF,
42 .procname = "mld_max_msf", 46 .procname = "mld_max_msf",
@@ -80,12 +84,6 @@ static int ipv6_sysctl_net_init(struct net *net)
80 84
81 ipv6_table[2].data = &net->ipv6.sysctl.bindv6only; 85 ipv6_table[2].data = &net->ipv6.sysctl.bindv6only;
82 86
83 /* We don't want this value to be per namespace, it should be global
84 to all namespaces, so make it read-only when we are not in the
85 init network namespace */
86 if (net != &init_net)
87 ipv6_table[3].mode = 0444;
88
89 net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path, 87 net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path,
90 ipv6_table); 88 ipv6_table);
91 if (!net->ipv6.sysctl.table) 89 if (!net->ipv6.sysctl.table)
@@ -126,12 +124,29 @@ static struct pernet_operations ipv6_sysctl_net_ops = {
126 .exit = ipv6_sysctl_net_exit, 124 .exit = ipv6_sysctl_net_exit,
127}; 125};
128 126
127static struct ctl_table_header *ip6_header;
128
129int ipv6_sysctl_register(void) 129int ipv6_sysctl_register(void)
130{ 130{
131 return register_pernet_subsys(&ipv6_sysctl_net_ops); 131 int err = -ENOMEM;;
132
133 ip6_header = register_net_sysctl_rotable(net_ipv6_ctl_path, ipv6_table);
134 if (ip6_header == NULL)
135 goto out;
136
137 err = register_pernet_subsys(&ipv6_sysctl_net_ops);
138 if (err)
139 goto err_pernet;
140out:
141 return err;
142
143err_pernet:
144 unregister_net_sysctl_table(ip6_header);
145 goto out;
132} 146}
133 147
134void ipv6_sysctl_unregister(void) 148void ipv6_sysctl_unregister(void)
135{ 149{
150 unregister_net_sysctl_table(ip6_header);
136 unregister_pernet_subsys(&ipv6_sysctl_net_ops); 151 unregister_pernet_subsys(&ipv6_sysctl_net_ops);
137} 152}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 40ea9c36d24b..ae45f9835014 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt> 6 * Pedro Roque <roque@di.fc.ul.pt>
7 * 7 *
8 * $Id: tcp_ipv6.c,v 1.144 2002/02/01 22:01:04 davem Exp $
9 *
10 * Based on: 8 * Based on:
11 * linux/net/ipv4/tcp.c 9 * linux/net/ipv4/tcp.c
12 * linux/net/ipv4/tcp_input.c 10 * linux/net/ipv4/tcp_input.c
@@ -72,8 +70,6 @@
72 70
73static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); 71static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
74static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); 72static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
75static void tcp_v6_send_check(struct sock *sk, int len,
76 struct sk_buff *skb);
77 73
78static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); 74static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
79 75
@@ -82,6 +78,12 @@ static struct inet_connection_sock_af_ops ipv6_specific;
82#ifdef CONFIG_TCP_MD5SIG 78#ifdef CONFIG_TCP_MD5SIG
83static struct tcp_sock_af_ops tcp_sock_ipv6_specific; 79static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
84static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; 80static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
81#else
82static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
83 struct in6_addr *addr)
84{
85 return NULL;
86}
85#endif 87#endif
86 88
87static void tcp_v6_hash(struct sock *sk) 89static void tcp_v6_hash(struct sock *sk)
@@ -321,8 +323,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
321 int err; 323 int err;
322 struct tcp_sock *tp; 324 struct tcp_sock *tp;
323 __u32 seq; 325 __u32 seq;
326 struct net *net = dev_net(skb->dev);
324 327
325 sk = inet6_lookup(dev_net(skb->dev), &tcp_hashinfo, &hdr->daddr, 328 sk = inet6_lookup(net, &tcp_hashinfo, &hdr->daddr,
326 th->dest, &hdr->saddr, th->source, skb->dev->ifindex); 329 th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
327 330
328 if (sk == NULL) { 331 if (sk == NULL) {
@@ -337,7 +340,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
337 340
338 bh_lock_sock(sk); 341 bh_lock_sock(sk);
339 if (sock_owned_by_user(sk)) 342 if (sock_owned_by_user(sk))
340 NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); 343 NET_INC_STATS_BH(net, LINUX_MIB_LOCKDROPPEDICMPS);
341 344
342 if (sk->sk_state == TCP_CLOSE) 345 if (sk->sk_state == TCP_CLOSE)
343 goto out; 346 goto out;
@@ -346,7 +349,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
346 seq = ntohl(th->seq); 349 seq = ntohl(th->seq);
347 if (sk->sk_state != TCP_LISTEN && 350 if (sk->sk_state != TCP_LISTEN &&
348 !between(seq, tp->snd_una, tp->snd_nxt)) { 351 !between(seq, tp->snd_una, tp->snd_nxt)) {
349 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); 352 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
350 goto out; 353 goto out;
351 } 354 }
352 355
@@ -421,7 +424,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
421 BUG_TRAP(req->sk == NULL); 424 BUG_TRAP(req->sk == NULL);
422 425
423 if (seq != tcp_rsk(req)->snt_isn) { 426 if (seq != tcp_rsk(req)->snt_isn) {
424 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); 427 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
425 goto out; 428 goto out;
426 } 429 }
427 430
@@ -733,109 +736,105 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
733 return tcp_v6_md5_do_add(sk, &sin6->sin6_addr, newkey, cmd.tcpm_keylen); 736 return tcp_v6_md5_do_add(sk, &sin6->sin6_addr, newkey, cmd.tcpm_keylen);
734} 737}
735 738
736static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 739static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
737 struct in6_addr *saddr, 740 struct in6_addr *daddr,
738 struct in6_addr *daddr, 741 struct in6_addr *saddr, int nbytes)
739 struct tcphdr *th, int protocol,
740 unsigned int tcplen)
741{ 742{
742 struct scatterlist sg[4];
743 __u16 data_len;
744 int block = 0;
745 __sum16 cksum;
746 struct tcp_md5sig_pool *hp;
747 struct tcp6_pseudohdr *bp; 743 struct tcp6_pseudohdr *bp;
748 struct hash_desc *desc; 744 struct scatterlist sg;
749 int err;
750 unsigned int nbytes = 0;
751 745
752 hp = tcp_get_md5sig_pool();
753 if (!hp) {
754 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__);
755 goto clear_hash_noput;
756 }
757 bp = &hp->md5_blk.ip6; 746 bp = &hp->md5_blk.ip6;
758 desc = &hp->md5_desc;
759
760 /* 1. TCP pseudo-header (RFC2460) */ 747 /* 1. TCP pseudo-header (RFC2460) */
761 ipv6_addr_copy(&bp->saddr, saddr); 748 ipv6_addr_copy(&bp->saddr, saddr);
762 ipv6_addr_copy(&bp->daddr, daddr); 749 ipv6_addr_copy(&bp->daddr, daddr);
763 bp->len = htonl(tcplen); 750 bp->protocol = cpu_to_be32(IPPROTO_TCP);
764 bp->protocol = htonl(protocol); 751 bp->len = cpu_to_be16(nbytes);
765
766 sg_init_table(sg, 4);
767
768 sg_set_buf(&sg[block++], bp, sizeof(*bp));
769 nbytes += sizeof(*bp);
770 752
771 /* 2. TCP header, excluding options */ 753 sg_init_one(&sg, bp, sizeof(*bp));
772 cksum = th->check; 754 return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp));
773 th->check = 0; 755}
774 sg_set_buf(&sg[block++], th, sizeof(*th));
775 nbytes += sizeof(*th);
776
777 /* 3. TCP segment data (if any) */
778 data_len = tcplen - (th->doff << 2);
779 if (data_len > 0) {
780 u8 *data = (u8 *)th + (th->doff << 2);
781 sg_set_buf(&sg[block++], data, data_len);
782 nbytes += data_len;
783 }
784 756
785 /* 4. shared key */ 757static int tcp_v6_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
786 sg_set_buf(&sg[block++], key->key, key->keylen); 758 struct in6_addr *daddr, struct in6_addr *saddr,
787 nbytes += key->keylen; 759 struct tcphdr *th)
760{
761 struct tcp_md5sig_pool *hp;
762 struct hash_desc *desc;
788 763
789 sg_mark_end(&sg[block - 1]); 764 hp = tcp_get_md5sig_pool();
765 if (!hp)
766 goto clear_hash_noput;
767 desc = &hp->md5_desc;
790 768
791 /* Now store the hash into the packet */ 769 if (crypto_hash_init(desc))
792 err = crypto_hash_init(desc);
793 if (err) {
794 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
795 goto clear_hash; 770 goto clear_hash;
796 } 771 if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, th->doff << 2))
797 err = crypto_hash_update(desc, sg, nbytes);
798 if (err) {
799 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
800 goto clear_hash; 772 goto clear_hash;
801 } 773 if (tcp_md5_hash_header(hp, th))
802 err = crypto_hash_final(desc, md5_hash); 774 goto clear_hash;
803 if (err) { 775 if (tcp_md5_hash_key(hp, key))
804 printk(KERN_WARNING "%s(): hash_final failed\n", __func__); 776 goto clear_hash;
777 if (crypto_hash_final(desc, md5_hash))
805 goto clear_hash; 778 goto clear_hash;
806 }
807 779
808 /* Reset header, and free up the crypto */
809 tcp_put_md5sig_pool(); 780 tcp_put_md5sig_pool();
810 th->check = cksum;
811out:
812 return 0; 781 return 0;
782
813clear_hash: 783clear_hash:
814 tcp_put_md5sig_pool(); 784 tcp_put_md5sig_pool();
815clear_hash_noput: 785clear_hash_noput:
816 memset(md5_hash, 0, 16); 786 memset(md5_hash, 0, 16);
817 goto out; 787 return 1;
818} 788}
819 789
820static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 790static int tcp_v6_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
821 struct sock *sk, 791 struct sock *sk, struct request_sock *req,
822 struct dst_entry *dst, 792 struct sk_buff *skb)
823 struct request_sock *req,
824 struct tcphdr *th, int protocol,
825 unsigned int tcplen)
826{ 793{
827 struct in6_addr *saddr, *daddr; 794 struct in6_addr *saddr, *daddr;
795 struct tcp_md5sig_pool *hp;
796 struct hash_desc *desc;
797 struct tcphdr *th = tcp_hdr(skb);
828 798
829 if (sk) { 799 if (sk) {
830 saddr = &inet6_sk(sk)->saddr; 800 saddr = &inet6_sk(sk)->saddr;
831 daddr = &inet6_sk(sk)->daddr; 801 daddr = &inet6_sk(sk)->daddr;
832 } else { 802 } else if (req) {
833 saddr = &inet6_rsk(req)->loc_addr; 803 saddr = &inet6_rsk(req)->loc_addr;
834 daddr = &inet6_rsk(req)->rmt_addr; 804 daddr = &inet6_rsk(req)->rmt_addr;
805 } else {
806 struct ipv6hdr *ip6h = ipv6_hdr(skb);
807 saddr = &ip6h->saddr;
808 daddr = &ip6h->daddr;
835 } 809 }
836 return tcp_v6_do_calc_md5_hash(md5_hash, key, 810
837 saddr, daddr, 811 hp = tcp_get_md5sig_pool();
838 th, protocol, tcplen); 812 if (!hp)
813 goto clear_hash_noput;
814 desc = &hp->md5_desc;
815
816 if (crypto_hash_init(desc))
817 goto clear_hash;
818
819 if (tcp_v6_md5_hash_pseudoheader(hp, daddr, saddr, skb->len))
820 goto clear_hash;
821 if (tcp_md5_hash_header(hp, th))
822 goto clear_hash;
823 if (tcp_md5_hash_skb_data(hp, skb, th->doff << 2))
824 goto clear_hash;
825 if (tcp_md5_hash_key(hp, key))
826 goto clear_hash;
827 if (crypto_hash_final(desc, md5_hash))
828 goto clear_hash;
829
830 tcp_put_md5sig_pool();
831 return 0;
832
833clear_hash:
834 tcp_put_md5sig_pool();
835clear_hash_noput:
836 memset(md5_hash, 0, 16);
837 return 1;
839} 838}
840 839
841static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) 840static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
@@ -844,43 +843,12 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
844 struct tcp_md5sig_key *hash_expected; 843 struct tcp_md5sig_key *hash_expected;
845 struct ipv6hdr *ip6h = ipv6_hdr(skb); 844 struct ipv6hdr *ip6h = ipv6_hdr(skb);
846 struct tcphdr *th = tcp_hdr(skb); 845 struct tcphdr *th = tcp_hdr(skb);
847 int length = (th->doff << 2) - sizeof (*th);
848 int genhash; 846 int genhash;
849 u8 *ptr;
850 u8 newhash[16]; 847 u8 newhash[16];
851 848
852 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); 849 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
850 hash_location = tcp_parse_md5sig_option(th);
853 851
854 /* If the TCP option is too short, we can short cut */
855 if (length < TCPOLEN_MD5SIG)
856 return hash_expected ? 1 : 0;
857
858 /* parse options */
859 ptr = (u8*)(th + 1);
860 while (length > 0) {
861 int opcode = *ptr++;
862 int opsize;
863
864 switch(opcode) {
865 case TCPOPT_EOL:
866 goto done_opts;
867 case TCPOPT_NOP:
868 length--;
869 continue;
870 default:
871 opsize = *ptr++;
872 if (opsize < 2 || opsize > length)
873 goto done_opts;
874 if (opcode == TCPOPT_MD5SIG) {
875 hash_location = ptr;
876 goto done_opts;
877 }
878 }
879 ptr += opsize - 2;
880 length -= opsize;
881 }
882
883done_opts:
884 /* do we have a hash as expected? */ 852 /* do we have a hash as expected? */
885 if (!hash_expected) { 853 if (!hash_expected) {
886 if (!hash_location) 854 if (!hash_location)
@@ -907,11 +875,10 @@ done_opts:
907 } 875 }
908 876
909 /* check the signature */ 877 /* check the signature */
910 genhash = tcp_v6_do_calc_md5_hash(newhash, 878 genhash = tcp_v6_md5_hash_skb(newhash,
911 hash_expected, 879 hash_expected,
912 &ip6h->saddr, &ip6h->daddr, 880 NULL, NULL, skb);
913 th, sk->sk_protocol, 881
914 skb->len);
915 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 882 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
916 if (net_ratelimit()) { 883 if (net_ratelimit()) {
917 printk(KERN_INFO "MD5 Hash %s for " 884 printk(KERN_INFO "MD5 Hash %s for "
@@ -1048,10 +1015,9 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1048 (TCPOPT_NOP << 16) | 1015 (TCPOPT_NOP << 16) |
1049 (TCPOPT_MD5SIG << 8) | 1016 (TCPOPT_MD5SIG << 8) |
1050 TCPOLEN_MD5SIG); 1017 TCPOLEN_MD5SIG);
1051 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key, 1018 tcp_v6_md5_hash_hdr((__u8 *)&opt[1], key,
1052 &ipv6_hdr(skb)->daddr, 1019 &ipv6_hdr(skb)->daddr,
1053 &ipv6_hdr(skb)->saddr, 1020 &ipv6_hdr(skb)->saddr, t1);
1054 t1, IPPROTO_TCP, tot_len);
1055 } 1021 }
1056#endif 1022#endif
1057 1023
@@ -1079,8 +1045,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1079 1045
1080 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 1046 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1081 ip6_xmit(ctl_sk, buff, &fl, NULL, 0); 1047 ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
1082 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1048 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1083 TCP_INC_STATS_BH(TCP_MIB_OUTRSTS); 1049 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
1084 return; 1050 return;
1085 } 1051 }
1086 } 1052 }
@@ -1088,8 +1054,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1088 kfree_skb(buff); 1054 kfree_skb(buff);
1089} 1055}
1090 1056
1091static void tcp_v6_send_ack(struct tcp_timewait_sock *tw, 1057static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1092 struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1058 struct tcp_md5sig_key *key)
1093{ 1059{
1094 struct tcphdr *th = tcp_hdr(skb), *t1; 1060 struct tcphdr *th = tcp_hdr(skb), *t1;
1095 struct sk_buff *buff; 1061 struct sk_buff *buff;
@@ -1098,22 +1064,6 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1098 struct sock *ctl_sk = net->ipv6.tcp_sk; 1064 struct sock *ctl_sk = net->ipv6.tcp_sk;
1099 unsigned int tot_len = sizeof(struct tcphdr); 1065 unsigned int tot_len = sizeof(struct tcphdr);
1100 __be32 *topt; 1066 __be32 *topt;
1101#ifdef CONFIG_TCP_MD5SIG
1102 struct tcp_md5sig_key *key;
1103 struct tcp_md5sig_key tw_key;
1104#endif
1105
1106#ifdef CONFIG_TCP_MD5SIG
1107 if (!tw && skb->sk) {
1108 key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr);
1109 } else if (tw && tw->tw_md5_keylen) {
1110 tw_key.key = tw->tw_md5_key;
1111 tw_key.keylen = tw->tw_md5_keylen;
1112 key = &tw_key;
1113 } else {
1114 key = NULL;
1115 }
1116#endif
1117 1067
1118 if (ts) 1068 if (ts)
1119 tot_len += TCPOLEN_TSTAMP_ALIGNED; 1069 tot_len += TCPOLEN_TSTAMP_ALIGNED;
@@ -1154,10 +1104,9 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1154 if (key) { 1104 if (key) {
1155 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 1105 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
1156 (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); 1106 (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
1157 tcp_v6_do_calc_md5_hash((__u8 *)topt, key, 1107 tcp_v6_md5_hash_hdr((__u8 *)topt, key,
1158 &ipv6_hdr(skb)->daddr, 1108 &ipv6_hdr(skb)->daddr,
1159 &ipv6_hdr(skb)->saddr, 1109 &ipv6_hdr(skb)->saddr, t1);
1160 t1, IPPROTO_TCP, tot_len);
1161 } 1110 }
1162#endif 1111#endif
1163 1112
@@ -1180,7 +1129,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1180 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { 1129 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
1181 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 1130 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1182 ip6_xmit(ctl_sk, buff, &fl, NULL, 0); 1131 ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
1183 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1132 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1184 return; 1133 return;
1185 } 1134 }
1186 } 1135 }
@@ -1193,16 +1142,17 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1193 struct inet_timewait_sock *tw = inet_twsk(sk); 1142 struct inet_timewait_sock *tw = inet_twsk(sk);
1194 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1143 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
1195 1144
1196 tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1145 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
1197 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1146 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
1198 tcptw->tw_ts_recent); 1147 tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
1199 1148
1200 inet_twsk_put(tw); 1149 inet_twsk_put(tw);
1201} 1150}
1202 1151
1203static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1152static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
1204{ 1153{
1205 tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1154 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
1155 tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr));
1206} 1156}
1207 1157
1208 1158
@@ -1538,9 +1488,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1538 return newsk; 1488 return newsk;
1539 1489
1540out_overflow: 1490out_overflow:
1541 NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS); 1491 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
1542out: 1492out:
1543 NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS); 1493 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1544 if (opt && opt != np->opt) 1494 if (opt && opt != np->opt)
1545 sock_kfree_s(sk, opt, opt->tot_len); 1495 sock_kfree_s(sk, opt, opt->tot_len);
1546 dst_release(dst); 1496 dst_release(dst);
@@ -1669,7 +1619,7 @@ discard:
1669 kfree_skb(skb); 1619 kfree_skb(skb);
1670 return 0; 1620 return 0;
1671csum_err: 1621csum_err:
1672 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1622 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
1673 goto discard; 1623 goto discard;
1674 1624
1675 1625
@@ -1707,6 +1657,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1707 struct tcphdr *th; 1657 struct tcphdr *th;
1708 struct sock *sk; 1658 struct sock *sk;
1709 int ret; 1659 int ret;
1660 struct net *net = dev_net(skb->dev);
1710 1661
1711 if (skb->pkt_type != PACKET_HOST) 1662 if (skb->pkt_type != PACKET_HOST)
1712 goto discard_it; 1663 goto discard_it;
@@ -1714,7 +1665,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1714 /* 1665 /*
1715 * Count it even if it's bad. 1666 * Count it even if it's bad.
1716 */ 1667 */
1717 TCP_INC_STATS_BH(TCP_MIB_INSEGS); 1668 TCP_INC_STATS_BH(net, TCP_MIB_INSEGS);
1718 1669
1719 if (!pskb_may_pull(skb, sizeof(struct tcphdr))) 1670 if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
1720 goto discard_it; 1671 goto discard_it;
@@ -1738,7 +1689,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1738 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); 1689 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
1739 TCP_SKB_CB(skb)->sacked = 0; 1690 TCP_SKB_CB(skb)->sacked = 0;
1740 1691
1741 sk = __inet6_lookup(dev_net(skb->dev), &tcp_hashinfo, 1692 sk = __inet6_lookup(net, &tcp_hashinfo,
1742 &ipv6_hdr(skb)->saddr, th->source, 1693 &ipv6_hdr(skb)->saddr, th->source,
1743 &ipv6_hdr(skb)->daddr, ntohs(th->dest), 1694 &ipv6_hdr(skb)->daddr, ntohs(th->dest),
1744 inet6_iif(skb)); 1695 inet6_iif(skb));
@@ -1786,7 +1737,7 @@ no_tcp_socket:
1786 1737
1787 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1738 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1788bad_packet: 1739bad_packet:
1789 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1740 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
1790 } else { 1741 } else {
1791 tcp_v6_send_reset(NULL, skb); 1742 tcp_v6_send_reset(NULL, skb);
1792 } 1743 }
@@ -1811,7 +1762,7 @@ do_time_wait:
1811 } 1762 }
1812 1763
1813 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1764 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1814 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1765 TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
1815 inet_twsk_put(inet_twsk(sk)); 1766 inet_twsk_put(inet_twsk(sk));
1816 goto discard_it; 1767 goto discard_it;
1817 } 1768 }
@@ -1871,7 +1822,7 @@ static struct inet_connection_sock_af_ops ipv6_specific = {
1871#ifdef CONFIG_TCP_MD5SIG 1822#ifdef CONFIG_TCP_MD5SIG
1872static struct tcp_sock_af_ops tcp_sock_ipv6_specific = { 1823static struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
1873 .md5_lookup = tcp_v6_md5_lookup, 1824 .md5_lookup = tcp_v6_md5_lookup,
1874 .calc_md5_hash = tcp_v6_calc_md5_hash, 1825 .calc_md5_hash = tcp_v6_md5_hash_skb,
1875 .md5_add = tcp_v6_md5_add_func, 1826 .md5_add = tcp_v6_md5_add_func,
1876 .md5_parse = tcp_v6_parse_md5_keys, 1827 .md5_parse = tcp_v6_parse_md5_keys,
1877}; 1828};
@@ -1903,7 +1854,7 @@ static struct inet_connection_sock_af_ops ipv6_mapped = {
1903#ifdef CONFIG_TCP_MD5SIG 1854#ifdef CONFIG_TCP_MD5SIG
1904static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = { 1855static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
1905 .md5_lookup = tcp_v4_md5_lookup, 1856 .md5_lookup = tcp_v4_md5_lookup,
1906 .calc_md5_hash = tcp_v4_calc_md5_hash, 1857 .calc_md5_hash = tcp_v4_md5_hash_skb,
1907 .md5_add = tcp_v6_md5_add_func, 1858 .md5_add = tcp_v6_md5_add_func,
1908 .md5_parse = tcp_v6_parse_md5_keys, 1859 .md5_parse = tcp_v6_parse_md5_keys,
1909}; 1860};
@@ -1960,7 +1911,7 @@ static int tcp_v6_init_sock(struct sock *sk)
1960 return 0; 1911 return 0;
1961} 1912}
1962 1913
1963static int tcp_v6_destroy_sock(struct sock *sk) 1914static void tcp_v6_destroy_sock(struct sock *sk)
1964{ 1915{
1965#ifdef CONFIG_TCP_MD5SIG 1916#ifdef CONFIG_TCP_MD5SIG
1966 /* Clean up the MD5 key list */ 1917 /* Clean up the MD5 key list */
@@ -1968,7 +1919,7 @@ static int tcp_v6_destroy_sock(struct sock *sk)
1968 tcp_v6_clear_md5_list(sk); 1919 tcp_v6_clear_md5_list(sk);
1969#endif 1920#endif
1970 tcp_v4_destroy_sock(sk); 1921 tcp_v4_destroy_sock(sk);
1971 return inet6_destroy_sock(sk); 1922 inet6_destroy_sock(sk);
1972} 1923}
1973 1924
1974#ifdef CONFIG_PROC_FS 1925#ifdef CONFIG_PROC_FS
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index dd309626ae9a..d1477b350f76 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -7,8 +7,6 @@
7 * 7 *
8 * Based on linux/ipv4/udp.c 8 * Based on linux/ipv4/udp.c
9 * 9 *
10 * $Id: udp.c,v 1.65 2002/02/01 22:01:04 davem Exp $
11 *
12 * Fixes: 10 * Fixes:
13 * Hideaki YOSHIFUJI : sin6_scope_id support 11 * Hideaki YOSHIFUJI : sin6_scope_id support
14 * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which 12 * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which
@@ -67,7 +65,7 @@ static struct sock *__udp6_lib_lookup(struct net *net,
67 int badness = -1; 65 int badness = -1;
68 66
69 read_lock(&udp_hash_lock); 67 read_lock(&udp_hash_lock);
70 sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { 68 sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) {
71 struct inet_sock *inet = inet_sk(sk); 69 struct inet_sock *inet = inet_sk(sk);
72 70
73 if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && 71 if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum &&
@@ -168,7 +166,8 @@ try_again:
168 goto out_free; 166 goto out_free;
169 167
170 if (!peeked) 168 if (!peeked)
171 UDP6_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite); 169 UDP6_INC_STATS_USER(sock_net(sk),
170 UDP_MIB_INDATAGRAMS, is_udplite);
172 171
173 sock_recv_timestamp(msg, sk, skb); 172 sock_recv_timestamp(msg, sk, skb);
174 173
@@ -215,7 +214,7 @@ out:
215csum_copy_err: 214csum_copy_err:
216 lock_sock(sk); 215 lock_sock(sk);
217 if (!skb_kill_datagram(sk, skb, flags)) 216 if (!skb_kill_datagram(sk, skb, flags))
218 UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite); 217 UDP6_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
219 release_sock(sk); 218 release_sock(sk);
220 219
221 if (flags & MSG_DONTWAIT) 220 if (flags & MSG_DONTWAIT)
@@ -299,14 +298,17 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
299 298
300 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { 299 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
301 /* Note that an ENOMEM error is charged twice */ 300 /* Note that an ENOMEM error is charged twice */
302 if (rc == -ENOMEM) 301 if (rc == -ENOMEM) {
303 UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite); 302 UDP6_INC_STATS_BH(sock_net(sk),
303 UDP_MIB_RCVBUFERRORS, is_udplite);
304 atomic_inc(&sk->sk_drops);
305 }
304 goto drop; 306 goto drop;
305 } 307 }
306 308
307 return 0; 309 return 0;
308drop: 310drop:
309 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite); 311 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
310 kfree_skb(skb); 312 kfree_skb(skb);
311 return -1; 313 return -1;
312} 314}
@@ -355,15 +357,16 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
355 * Note: called only from the BH handler context, 357 * Note: called only from the BH handler context,
356 * so we don't need to lock the hashes. 358 * so we don't need to lock the hashes.
357 */ 359 */
358static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr, 360static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
359 struct in6_addr *daddr, struct hlist_head udptable[]) 361 struct in6_addr *saddr, struct in6_addr *daddr,
362 struct hlist_head udptable[])
360{ 363{
361 struct sock *sk, *sk2; 364 struct sock *sk, *sk2;
362 const struct udphdr *uh = udp_hdr(skb); 365 const struct udphdr *uh = udp_hdr(skb);
363 int dif; 366 int dif;
364 367
365 read_lock(&udp_hash_lock); 368 read_lock(&udp_hash_lock);
366 sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); 369 sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]);
367 dif = inet6_iif(skb); 370 dif = inet6_iif(skb);
368 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); 371 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
369 if (!sk) { 372 if (!sk) {
@@ -437,6 +440,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
437 struct net_device *dev = skb->dev; 440 struct net_device *dev = skb->dev;
438 struct in6_addr *saddr, *daddr; 441 struct in6_addr *saddr, *daddr;
439 u32 ulen = 0; 442 u32 ulen = 0;
443 struct net *net = dev_net(skb->dev);
440 444
441 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 445 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
442 goto short_packet; 446 goto short_packet;
@@ -475,7 +479,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
475 * Multicast receive code 479 * Multicast receive code
476 */ 480 */
477 if (ipv6_addr_is_multicast(daddr)) 481 if (ipv6_addr_is_multicast(daddr))
478 return __udp6_lib_mcast_deliver(skb, saddr, daddr, udptable); 482 return __udp6_lib_mcast_deliver(net, skb,
483 saddr, daddr, udptable);
479 484
480 /* Unicast */ 485 /* Unicast */
481 486
@@ -483,7 +488,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
483 * check socket cache ... must talk to Alan about his plans 488 * check socket cache ... must talk to Alan about his plans
484 * for sock caches... i'll skip this for now. 489 * for sock caches... i'll skip this for now.
485 */ 490 */
486 sk = __udp6_lib_lookup(dev_net(skb->dev), saddr, uh->source, 491 sk = __udp6_lib_lookup(net, saddr, uh->source,
487 daddr, uh->dest, inet6_iif(skb), udptable); 492 daddr, uh->dest, inet6_iif(skb), udptable);
488 493
489 if (sk == NULL) { 494 if (sk == NULL) {
@@ -492,7 +497,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
492 497
493 if (udp_lib_checksum_complete(skb)) 498 if (udp_lib_checksum_complete(skb))
494 goto discard; 499 goto discard;
495 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); 500 UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS,
501 proto == IPPROTO_UDPLITE);
496 502
497 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); 503 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
498 504
@@ -517,7 +523,7 @@ short_packet:
517 ulen, skb->len); 523 ulen, skb->len);
518 524
519discard: 525discard:
520 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); 526 UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
521 kfree_skb(skb); 527 kfree_skb(skb);
522 return 0; 528 return 0;
523} 529}
@@ -587,7 +593,8 @@ out:
587 up->len = 0; 593 up->len = 0;
588 up->pending = 0; 594 up->pending = 0;
589 if (!err) 595 if (!err)
590 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite); 596 UDP6_INC_STATS_USER(sock_net(sk),
597 UDP_MIB_OUTDATAGRAMS, is_udplite);
591 return err; 598 return err;
592} 599}
593 600
@@ -869,7 +876,8 @@ out:
869 * seems like overkill. 876 * seems like overkill.
870 */ 877 */
871 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { 878 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
872 UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite); 879 UDP6_INC_STATS_USER(sock_net(sk),
880 UDP_MIB_SNDBUFERRORS, is_udplite);
873 } 881 }
874 return err; 882 return err;
875 883
@@ -881,15 +889,13 @@ do_confirm:
881 goto out; 889 goto out;
882} 890}
883 891
884int udpv6_destroy_sock(struct sock *sk) 892void udpv6_destroy_sock(struct sock *sk)
885{ 893{
886 lock_sock(sk); 894 lock_sock(sk);
887 udp_v6_flush_pending_frames(sk); 895 udp_v6_flush_pending_frames(sk);
888 release_sock(sk); 896 release_sock(sk);
889 897
890 inet6_destroy_sock(sk); 898 inet6_destroy_sock(sk);
891
892 return 0;
893} 899}
894 900
895/* 901/*
@@ -955,7 +961,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
955 srcp = ntohs(inet->sport); 961 srcp = ntohs(inet->sport);
956 seq_printf(seq, 962 seq_printf(seq,
957 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 963 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
958 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p\n", 964 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
959 bucket, 965 bucket,
960 src->s6_addr32[0], src->s6_addr32[1], 966 src->s6_addr32[0], src->s6_addr32[1],
961 src->s6_addr32[2], src->s6_addr32[3], srcp, 967 src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -967,7 +973,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
967 0, 0L, 0, 973 0, 0L, 0,
968 sock_i_uid(sp), 0, 974 sock_i_uid(sp), 0,
969 sock_i_ino(sp), 975 sock_i_ino(sp),
970 atomic_read(&sp->sk_refcnt), sp); 976 atomic_read(&sp->sk_refcnt), sp,
977 atomic_read(&sp->sk_drops));
971} 978}
972 979
973int udp6_seq_show(struct seq_file *seq, void *v) 980int udp6_seq_show(struct seq_file *seq, void *v)
@@ -978,7 +985,7 @@ int udp6_seq_show(struct seq_file *seq, void *v)
978 "local_address " 985 "local_address "
979 "remote_address " 986 "remote_address "
980 "st tx_queue rx_queue tr tm->when retrnsmt" 987 "st tx_queue rx_queue tr tm->when retrnsmt"
981 " uid timeout inode\n"); 988 " uid timeout inode ref pointer drops\n");
982 else 989 else
983 udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket); 990 udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket);
984 return 0; 991 return 0;
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 321b81a4d418..92dd7da766d8 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -29,7 +29,7 @@ extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
29 struct msghdr *msg, size_t len, 29 struct msghdr *msg, size_t len,
30 int noblock, int flags, int *addr_len); 30 int noblock, int flags, int *addr_len);
31extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); 31extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
32extern int udpv6_destroy_sock(struct sock *sk); 32extern void udpv6_destroy_sock(struct sock *sk);
33 33
34#ifdef CONFIG_PROC_FS 34#ifdef CONFIG_PROC_FS
35extern int udp6_seq_show(struct seq_file *seq, void *v); 35extern int udp6_seq_show(struct seq_file *seq, void *v);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 491efd00a866..f6cdcb348e05 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -2,8 +2,6 @@
2 * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6. 2 * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6.
3 * See also net/ipv4/udplite.c 3 * See also net/ipv4/udplite.c
4 * 4 *
5 * Version: $Id: udplite.c,v 1.9 2006/10/19 08:28:10 gerrit Exp $
6 *
7 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk> 5 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk>
8 * 6 *
9 * Changes: 7 * Changes: