aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig45
-rw-r--r--net/ipv6/Makefile4
-rw-r--r--net/ipv6/addrconf.c723
-rw-r--r--net/ipv6/af_inet6.c26
-rw-r--r--net/ipv6/ah6.c125
-rw-r--r--net/ipv6/anycast.c9
-rw-r--r--net/ipv6/datagram.c22
-rw-r--r--net/ipv6/esp6.c107
-rw-r--r--net/ipv6/exthdrs.c266
-rw-r--r--net/ipv6/fib6_rules.c305
-rw-r--r--net/ipv6/icmp.c48
-rw-r--r--net/ipv6/inet6_connection_sock.c6
-rw-r--r--net/ipv6/inet6_hashtables.c9
-rw-r--r--net/ipv6/ip6_fib.c464
-rw-r--r--net/ipv6/ip6_flowlabel.c1
-rw-r--r--net/ipv6/ip6_input.c11
-rw-r--r--net/ipv6/ip6_output.c230
-rw-r--r--net/ipv6/ip6_tunnel.c4
-rw-r--r--net/ipv6/ipcomp6.c40
-rw-r--r--net/ipv6/ipv6_sockglue.c122
-rw-r--r--net/ipv6/ipv6_syms.c4
-rw-r--r--net/ipv6/mcast.c13
-rw-r--r--net/ipv6/mip6.c519
-rw-r--r--net/ipv6/ndisc.c54
-rw-r--r--net/ipv6/netfilter.c2
-rw-r--r--net/ipv6/netfilter/Makefile2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c18
-rw-r--r--net/ipv6/netfilter/ip6_tables.c65
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c9
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c4
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c10
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c1
-rw-r--r--net/ipv6/netfilter/ip6t_dst.c220
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c1
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c49
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c1
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c1
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c1
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c4
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c12
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c3
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c13
-rw-r--r--net/ipv6/proc.c1
-rw-r--r--net/ipv6/raw.c52
-rw-r--r--net/ipv6/reassembly.c15
-rw-r--r--net/ipv6/route.c1071
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/sysctl_net_ipv6.c1
-rw-r--r--net/ipv6/tcp_ipv6.c55
-rw-r--r--net/ipv6/udp.c107
-rw-r--r--net/ipv6/xfrm6_input.c114
-rw-r--r--net/ipv6/xfrm6_mode_ro.c93
-rw-r--r--net/ipv6/xfrm6_mode_transport.c5
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c3
-rw-r--r--net/ipv6/xfrm6_output.c22
-rw-r--r--net/ipv6/xfrm6_policy.c88
-rw-r--r--net/ipv6/xfrm6_state.c193
-rw-r--r--net/ipv6/xfrm6_tunnel.c145
60 files changed, 3864 insertions, 1680 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index e923d4dea418..a2d211da2aba 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -77,6 +77,7 @@ config INET6_ESP
77 select CRYPTO 77 select CRYPTO
78 select CRYPTO_HMAC 78 select CRYPTO_HMAC
79 select CRYPTO_MD5 79 select CRYPTO_MD5
80 select CRYPTO_CBC
80 select CRYPTO_SHA1 81 select CRYPTO_SHA1
81 select CRYPTO_DES 82 select CRYPTO_DES
82 ---help--- 83 ---help---
@@ -97,6 +98,15 @@ config INET6_IPCOMP
97 98
98 If unsure, say Y. 99 If unsure, say Y.
99 100
101config IPV6_MIP6
102 bool "IPv6: Mobility (EXPERIMENTAL)"
103 depends on IPV6 && EXPERIMENTAL
104 select XFRM
105 ---help---
106 Support for IPv6 Mobility described in RFC 3775.
107
108 If unsure, say N.
109
100config INET6_XFRM_TUNNEL 110config INET6_XFRM_TUNNEL
101 tristate 111 tristate
102 select INET6_TUNNEL 112 select INET6_TUNNEL
@@ -126,6 +136,13 @@ config INET6_XFRM_MODE_TUNNEL
126 136
127 If unsure, say Y. 137 If unsure, say Y.
128 138
139config INET6_XFRM_MODE_ROUTEOPTIMIZATION
140 tristate "IPv6: MIPv6 route optimization mode (EXPERIMENTAL)"
141 depends on IPV6 && EXPERIMENTAL
142 select XFRM
143 ---help---
144 Support for MIPv6 route optimization mode.
145
129config IPV6_TUNNEL 146config IPV6_TUNNEL
130 tristate "IPv6: IPv6-in-IPv6 tunnel" 147 tristate "IPv6: IPv6-in-IPv6 tunnel"
131 select INET6_TUNNEL 148 select INET6_TUNNEL
@@ -135,3 +152,31 @@ config IPV6_TUNNEL
135 152
136 If unsure, say N. 153 If unsure, say N.
137 154
155config IPV6_SUBTREES
156 bool "IPv6: source address based routing"
157 depends on IPV6 && EXPERIMENTAL
158 ---help---
159 Enable routing by source address or prefix.
160
161 The destination address is still the primary routing key, so mixing
162 normal and source prefix specific routes in the same routing table
163 may sometimes lead to unintended routing behavior. This can be
164 avoided by defining different routing tables for the normal and
165 source prefix specific routes.
166
167 If unsure, say N.
168
169config IPV6_MULTIPLE_TABLES
170 bool "IPv6: Multiple Routing Tables"
171 depends on IPV6 && EXPERIMENTAL
172 select FIB_RULES
173 ---help---
174 Support multiple routing tables.
175
176config IPV6_ROUTE_FWMARK
177 bool "IPv6: use netfilter MARK value as routing key"
178 depends on IPV6_MULTIPLE_TABLES && NETFILTER
179 ---help---
180 If you say Y here, you will be able to specify different routes for
181 packets with different mark values (see iptables(8), MARK target).
182
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 386e0a626948..0213c6612b58 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -13,6 +13,9 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
13ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ 13ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
14 xfrm6_output.o 14 xfrm6_output.o
15ipv6-$(CONFIG_NETFILTER) += netfilter.o 15ipv6-$(CONFIG_NETFILTER) += netfilter.o
16ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
17ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
18
16ipv6-objs += $(ipv6-y) 19ipv6-objs += $(ipv6-y)
17 20
18obj-$(CONFIG_INET6_AH) += ah6.o 21obj-$(CONFIG_INET6_AH) += ah6.o
@@ -22,6 +25,7 @@ obj-$(CONFIG_INET6_XFRM_TUNNEL) += xfrm6_tunnel.o
22obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o 25obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o
23obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o 26obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
24obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o 27obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
28obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
25obj-$(CONFIG_NETFILTER) += netfilter/ 29obj-$(CONFIG_NETFILTER) += netfilter/
26 30
27obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 31obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 4da664538f52..e03c33b2465b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -40,7 +40,6 @@
40 * status etc. 40 * status etc.
41 */ 41 */
42 42
43#include <linux/config.h>
44#include <linux/errno.h> 43#include <linux/errno.h>
45#include <linux/types.h> 44#include <linux/types.h>
46#include <linux/socket.h> 45#include <linux/socket.h>
@@ -49,6 +48,7 @@
49#include <linux/net.h> 48#include <linux/net.h>
50#include <linux/in6.h> 49#include <linux/in6.h>
51#include <linux/netdevice.h> 50#include <linux/netdevice.h>
51#include <linux/if_addr.h>
52#include <linux/if_arp.h> 52#include <linux/if_arp.h>
53#include <linux/if_arcnet.h> 53#include <linux/if_arcnet.h>
54#include <linux/if_infiniband.h> 54#include <linux/if_infiniband.h>
@@ -73,6 +73,7 @@
73#include <net/addrconf.h> 73#include <net/addrconf.h>
74#include <net/tcp.h> 74#include <net/tcp.h>
75#include <net/ip.h> 75#include <net/ip.h>
76#include <net/netlink.h>
76#include <linux/if_tunnel.h> 77#include <linux/if_tunnel.h>
77#include <linux/rtnetlink.h> 78#include <linux/rtnetlink.h>
78 79
@@ -118,9 +119,6 @@ static int ipv6_count_addresses(struct inet6_dev *idev);
118static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE]; 119static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE];
119static DEFINE_RWLOCK(addrconf_hash_lock); 120static DEFINE_RWLOCK(addrconf_hash_lock);
120 121
121/* Protects inet6 devices */
122DEFINE_RWLOCK(addrconf_lock);
123
124static void addrconf_verify(unsigned long); 122static void addrconf_verify(unsigned long);
125 123
126static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0); 124static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
@@ -145,7 +143,7 @@ static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *de
145 143
146static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); 144static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
147 145
148struct ipv6_devconf ipv6_devconf = { 146struct ipv6_devconf ipv6_devconf __read_mostly = {
149 .forwarding = 0, 147 .forwarding = 0,
150 .hop_limit = IPV6_DEFAULT_HOPLIMIT, 148 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
151 .mtu6 = IPV6_MIN_MTU, 149 .mtu6 = IPV6_MIN_MTU,
@@ -174,9 +172,10 @@ struct ipv6_devconf ipv6_devconf = {
174 .accept_ra_rt_info_max_plen = 0, 172 .accept_ra_rt_info_max_plen = 0,
175#endif 173#endif
176#endif 174#endif
175 .proxy_ndp = 0,
177}; 176};
178 177
179static struct ipv6_devconf ipv6_devconf_dflt = { 178static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
180 .forwarding = 0, 179 .forwarding = 0,
181 .hop_limit = IPV6_DEFAULT_HOPLIMIT, 180 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
182 .mtu6 = IPV6_MIN_MTU, 181 .mtu6 = IPV6_MIN_MTU,
@@ -204,6 +203,7 @@ static struct ipv6_devconf ipv6_devconf_dflt = {
204 .accept_ra_rt_info_max_plen = 0, 203 .accept_ra_rt_info_max_plen = 0,
205#endif 204#endif
206#endif 205#endif
206 .proxy_ndp = 0,
207}; 207};
208 208
209/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ 209/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -315,6 +315,12 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
315 315
316/* Nobody refers to this device, we may destroy it. */ 316/* Nobody refers to this device, we may destroy it. */
317 317
318static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
319{
320 struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
321 kfree(idev);
322}
323
318void in6_dev_finish_destroy(struct inet6_dev *idev) 324void in6_dev_finish_destroy(struct inet6_dev *idev)
319{ 325{
320 struct net_device *dev = idev->dev; 326 struct net_device *dev = idev->dev;
@@ -329,7 +335,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev)
329 return; 335 return;
330 } 336 }
331 snmp6_free_dev(idev); 337 snmp6_free_dev(idev);
332 kfree(idev); 338 call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
333} 339}
334 340
335static struct inet6_dev * ipv6_add_dev(struct net_device *dev) 341static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
@@ -405,9 +411,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
405 if (netif_carrier_ok(dev)) 411 if (netif_carrier_ok(dev))
406 ndev->if_flags |= IF_READY; 412 ndev->if_flags |= IF_READY;
407 413
408 write_lock_bh(&addrconf_lock); 414 /* protected by rtnl_lock */
409 dev->ip6_ptr = ndev; 415 rcu_assign_pointer(dev->ip6_ptr, ndev);
410 write_unlock_bh(&addrconf_lock);
411 416
412 ipv6_mc_init_dev(ndev); 417 ipv6_mc_init_dev(ndev);
413 ndev->tstamp = jiffies; 418 ndev->tstamp = jiffies;
@@ -471,7 +476,7 @@ static void addrconf_forward_change(void)
471 476
472 read_lock(&dev_base_lock); 477 read_lock(&dev_base_lock);
473 for (dev=dev_base; dev; dev=dev->next) { 478 for (dev=dev_base; dev; dev=dev->next) {
474 read_lock(&addrconf_lock); 479 rcu_read_lock();
475 idev = __in6_dev_get(dev); 480 idev = __in6_dev_get(dev);
476 if (idev) { 481 if (idev) {
477 int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding); 482 int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding);
@@ -479,7 +484,7 @@ static void addrconf_forward_change(void)
479 if (changed) 484 if (changed)
480 dev_forward_change(idev); 485 dev_forward_change(idev);
481 } 486 }
482 read_unlock(&addrconf_lock); 487 rcu_read_unlock();
483 } 488 }
484 read_unlock(&dev_base_lock); 489 read_unlock(&dev_base_lock);
485} 490}
@@ -509,6 +514,26 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
509 kfree(ifp); 514 kfree(ifp);
510} 515}
511 516
517static void
518ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
519{
520 struct inet6_ifaddr *ifa, **ifap;
521 int ifp_scope = ipv6_addr_src_scope(&ifp->addr);
522
523 /*
524 * Each device address list is sorted in order of scope -
525 * global before linklocal.
526 */
527 for (ifap = &idev->addr_list; (ifa = *ifap) != NULL;
528 ifap = &ifa->if_next) {
529 if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
530 break;
531 }
532
533 ifp->if_next = *ifap;
534 *ifap = ifp;
535}
536
512/* On success it returns ifp with increased reference count */ 537/* On success it returns ifp with increased reference count */
513 538
514static struct inet6_ifaddr * 539static struct inet6_ifaddr *
@@ -520,7 +545,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
520 int hash; 545 int hash;
521 int err = 0; 546 int err = 0;
522 547
523 read_lock_bh(&addrconf_lock); 548 rcu_read_lock_bh();
524 if (idev->dead) { 549 if (idev->dead) {
525 err = -ENODEV; /*XXX*/ 550 err = -ENODEV; /*XXX*/
526 goto out2; 551 goto out2;
@@ -559,6 +584,8 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
559 ifa->flags = flags | IFA_F_TENTATIVE; 584 ifa->flags = flags | IFA_F_TENTATIVE;
560 ifa->cstamp = ifa->tstamp = jiffies; 585 ifa->cstamp = ifa->tstamp = jiffies;
561 586
587 ifa->rt = rt;
588
562 ifa->idev = idev; 589 ifa->idev = idev;
563 in6_dev_hold(idev); 590 in6_dev_hold(idev);
564 /* For caller */ 591 /* For caller */
@@ -574,8 +601,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
574 601
575 write_lock(&idev->lock); 602 write_lock(&idev->lock);
576 /* Add to inet6_dev unicast addr list. */ 603 /* Add to inet6_dev unicast addr list. */
577 ifa->if_next = idev->addr_list; 604 ipv6_link_dev_addr(idev, ifa);
578 idev->addr_list = ifa;
579 605
580#ifdef CONFIG_IPV6_PRIVACY 606#ifdef CONFIG_IPV6_PRIVACY
581 if (ifa->flags&IFA_F_TEMPORARY) { 607 if (ifa->flags&IFA_F_TEMPORARY) {
@@ -585,12 +611,10 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
585 } 611 }
586#endif 612#endif
587 613
588 ifa->rt = rt;
589
590 in6_ifa_hold(ifa); 614 in6_ifa_hold(ifa);
591 write_unlock(&idev->lock); 615 write_unlock(&idev->lock);
592out2: 616out2:
593 read_unlock_bh(&addrconf_lock); 617 rcu_read_unlock_bh();
594 618
595 if (likely(err == 0)) 619 if (likely(err == 0))
596 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); 620 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
@@ -716,7 +740,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
716 740
717 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 741 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
718 if (onlink == 0) { 742 if (onlink == 0) {
719 ip6_del_rt(rt, NULL, NULL, NULL); 743 ip6_del_rt(rt);
720 rt = NULL; 744 rt = NULL;
721 } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { 745 } else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
722 rt->rt6i_expires = expires; 746 rt->rt6i_expires = expires;
@@ -893,7 +917,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
893 memset(&hiscore, 0, sizeof(hiscore)); 917 memset(&hiscore, 0, sizeof(hiscore));
894 918
895 read_lock(&dev_base_lock); 919 read_lock(&dev_base_lock);
896 read_lock(&addrconf_lock); 920 rcu_read_lock();
897 921
898 for (dev = dev_base; dev; dev=dev->next) { 922 for (dev = dev_base; dev; dev=dev->next) {
899 struct inet6_dev *idev; 923 struct inet6_dev *idev;
@@ -988,7 +1012,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
988 continue; 1012 continue;
989 } else if (score.scope < hiscore.scope) { 1013 } else if (score.scope < hiscore.scope) {
990 if (score.scope < daddr_scope) 1014 if (score.scope < daddr_scope)
991 continue; 1015 break; /* addresses sorted by scope */
992 else { 1016 else {
993 score.rule = 2; 1017 score.rule = 2;
994 goto record_it; 1018 goto record_it;
@@ -1014,9 +1038,27 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1014 continue; 1038 continue;
1015 } 1039 }
1016 1040
1017 /* Rule 4: Prefer home address -- not implemented yet */ 1041 /* Rule 4: Prefer home address */
1042#ifdef CONFIG_IPV6_MIP6
1043 if (hiscore.rule < 4) {
1044 if (ifa_result->flags & IFA_F_HOMEADDRESS)
1045 hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
1046 hiscore.rule++;
1047 }
1048 if (ifa->flags & IFA_F_HOMEADDRESS) {
1049 score.attrs |= IPV6_SADDR_SCORE_HOA;
1050 if (!(ifa_result->flags & IFA_F_HOMEADDRESS)) {
1051 score.rule = 4;
1052 goto record_it;
1053 }
1054 } else {
1055 if (hiscore.attrs & IPV6_SADDR_SCORE_HOA)
1056 continue;
1057 }
1058#else
1018 if (hiscore.rule < 4) 1059 if (hiscore.rule < 4)
1019 hiscore.rule++; 1060 hiscore.rule++;
1061#endif
1020 1062
1021 /* Rule 5: Prefer outgoing interface */ 1063 /* Rule 5: Prefer outgoing interface */
1022 if (hiscore.rule < 5) { 1064 if (hiscore.rule < 5) {
@@ -1105,7 +1147,7 @@ record_it:
1105 } 1147 }
1106 read_unlock_bh(&idev->lock); 1148 read_unlock_bh(&idev->lock);
1107 } 1149 }
1108 read_unlock(&addrconf_lock); 1150 rcu_read_unlock();
1109 read_unlock(&dev_base_lock); 1151 read_unlock(&dev_base_lock);
1110 1152
1111 if (!ifa_result) 1153 if (!ifa_result)
@@ -1129,7 +1171,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)
1129 struct inet6_dev *idev; 1171 struct inet6_dev *idev;
1130 int err = -EADDRNOTAVAIL; 1172 int err = -EADDRNOTAVAIL;
1131 1173
1132 read_lock(&addrconf_lock); 1174 rcu_read_lock();
1133 if ((idev = __in6_dev_get(dev)) != NULL) { 1175 if ((idev = __in6_dev_get(dev)) != NULL) {
1134 struct inet6_ifaddr *ifp; 1176 struct inet6_ifaddr *ifp;
1135 1177
@@ -1143,7 +1185,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)
1143 } 1185 }
1144 read_unlock_bh(&idev->lock); 1186 read_unlock_bh(&idev->lock);
1145 } 1187 }
1146 read_unlock(&addrconf_lock); 1188 rcu_read_unlock();
1147 return err; 1189 return err;
1148} 1190}
1149 1191
@@ -1216,8 +1258,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
1216{ 1258{
1217 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; 1259 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
1218 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); 1260 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
1219 u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; 1261 __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
1220 u32 sk2_rcv_saddr = inet_rcv_saddr(sk2); 1262 __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
1221 int sk_ipv6only = ipv6_only_sock(sk); 1263 int sk_ipv6only = ipv6_only_sock(sk);
1222 int sk2_ipv6only = inet_v6_ipv6only(sk2); 1264 int sk2_ipv6only = inet_v6_ipv6only(sk2);
1223 int addr_type = ipv6_addr_type(sk_rcv_saddr6); 1265 int addr_type = ipv6_addr_type(sk_rcv_saddr6);
@@ -1444,7 +1486,7 @@ static void ipv6_regen_rndid(unsigned long data)
1444 struct inet6_dev *idev = (struct inet6_dev *) data; 1486 struct inet6_dev *idev = (struct inet6_dev *) data;
1445 unsigned long expires; 1487 unsigned long expires;
1446 1488
1447 read_lock_bh(&addrconf_lock); 1489 rcu_read_lock_bh();
1448 write_lock_bh(&idev->lock); 1490 write_lock_bh(&idev->lock);
1449 1491
1450 if (idev->dead) 1492 if (idev->dead)
@@ -1468,7 +1510,7 @@ static void ipv6_regen_rndid(unsigned long data)
1468 1510
1469out: 1511out:
1470 write_unlock_bh(&idev->lock); 1512 write_unlock_bh(&idev->lock);
1471 read_unlock_bh(&addrconf_lock); 1513 rcu_read_unlock_bh();
1472 in6_dev_put(idev); 1514 in6_dev_put(idev);
1473} 1515}
1474 1516
@@ -1489,59 +1531,56 @@ static void
1489addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, 1531addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
1490 unsigned long expires, u32 flags) 1532 unsigned long expires, u32 flags)
1491{ 1533{
1492 struct in6_rtmsg rtmsg; 1534 struct fib6_config cfg = {
1535 .fc_table = RT6_TABLE_PREFIX,
1536 .fc_metric = IP6_RT_PRIO_ADDRCONF,
1537 .fc_ifindex = dev->ifindex,
1538 .fc_expires = expires,
1539 .fc_dst_len = plen,
1540 .fc_flags = RTF_UP | flags,
1541 };
1493 1542
1494 memset(&rtmsg, 0, sizeof(rtmsg)); 1543 ipv6_addr_copy(&cfg.fc_dst, pfx);
1495 ipv6_addr_copy(&rtmsg.rtmsg_dst, pfx);
1496 rtmsg.rtmsg_dst_len = plen;
1497 rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
1498 rtmsg.rtmsg_ifindex = dev->ifindex;
1499 rtmsg.rtmsg_info = expires;
1500 rtmsg.rtmsg_flags = RTF_UP|flags;
1501 rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1502 1544
1503 /* Prevent useless cloning on PtP SIT. 1545 /* Prevent useless cloning on PtP SIT.
1504 This thing is done here expecting that the whole 1546 This thing is done here expecting that the whole
1505 class of non-broadcast devices need not cloning. 1547 class of non-broadcast devices need not cloning.
1506 */ 1548 */
1507 if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT)) 1549 if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
1508 rtmsg.rtmsg_flags |= RTF_NONEXTHOP; 1550 cfg.fc_flags |= RTF_NONEXTHOP;
1509 1551
1510 ip6_route_add(&rtmsg, NULL, NULL, NULL); 1552 ip6_route_add(&cfg);
1511} 1553}
1512 1554
1513/* Create "default" multicast route to the interface */ 1555/* Create "default" multicast route to the interface */
1514 1556
1515static void addrconf_add_mroute(struct net_device *dev) 1557static void addrconf_add_mroute(struct net_device *dev)
1516{ 1558{
1517 struct in6_rtmsg rtmsg; 1559 struct fib6_config cfg = {
1560 .fc_table = RT6_TABLE_LOCAL,
1561 .fc_metric = IP6_RT_PRIO_ADDRCONF,
1562 .fc_ifindex = dev->ifindex,
1563 .fc_dst_len = 8,
1564 .fc_flags = RTF_UP,
1565 };
1566
1567 ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
1518 1568
1519 memset(&rtmsg, 0, sizeof(rtmsg)); 1569 ip6_route_add(&cfg);
1520 ipv6_addr_set(&rtmsg.rtmsg_dst,
1521 htonl(0xFF000000), 0, 0, 0);
1522 rtmsg.rtmsg_dst_len = 8;
1523 rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
1524 rtmsg.rtmsg_ifindex = dev->ifindex;
1525 rtmsg.rtmsg_flags = RTF_UP;
1526 rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1527 ip6_route_add(&rtmsg, NULL, NULL, NULL);
1528} 1570}
1529 1571
1530static void sit_route_add(struct net_device *dev) 1572static void sit_route_add(struct net_device *dev)
1531{ 1573{
1532 struct in6_rtmsg rtmsg; 1574 struct fib6_config cfg = {
1533 1575 .fc_table = RT6_TABLE_MAIN,
1534 memset(&rtmsg, 0, sizeof(rtmsg)); 1576 .fc_metric = IP6_RT_PRIO_ADDRCONF,
1535 1577 .fc_ifindex = dev->ifindex,
1536 rtmsg.rtmsg_type = RTMSG_NEWROUTE; 1578 .fc_dst_len = 96,
1537 rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF; 1579 .fc_flags = RTF_UP | RTF_NONEXTHOP,
1580 };
1538 1581
1539 /* prefix length - 96 bits "::d.d.d.d" */ 1582 /* prefix length - 96 bits "::d.d.d.d" */
1540 rtmsg.rtmsg_dst_len = 96; 1583 ip6_route_add(&cfg);
1541 rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP;
1542 rtmsg.rtmsg_ifindex = dev->ifindex;
1543
1544 ip6_route_add(&rtmsg, NULL, NULL, NULL);
1545} 1584}
1546 1585
1547static void addrconf_add_lroute(struct net_device *dev) 1586static void addrconf_add_lroute(struct net_device *dev)
@@ -1642,7 +1681,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1642 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 1681 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
1643 if (rt->rt6i_flags&RTF_EXPIRES) { 1682 if (rt->rt6i_flags&RTF_EXPIRES) {
1644 if (valid_lft == 0) { 1683 if (valid_lft == 0) {
1645 ip6_del_rt(rt, NULL, NULL, NULL); 1684 ip6_del_rt(rt);
1646 rt = NULL; 1685 rt = NULL;
1647 } else { 1686 } else {
1648 rt->rt6i_expires = jiffies + rt_expires; 1687 rt->rt6i_expires = jiffies + rt_expires;
@@ -1851,7 +1890,8 @@ err_exit:
1851/* 1890/*
1852 * Manual configuration of address on an interface 1891 * Manual configuration of address on an interface
1853 */ 1892 */
1854static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen) 1893static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
1894 __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft)
1855{ 1895{
1856 struct inet6_ifaddr *ifp; 1896 struct inet6_ifaddr *ifp;
1857 struct inet6_dev *idev; 1897 struct inet6_dev *idev;
@@ -1860,21 +1900,41 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen)
1860 1900
1861 ASSERT_RTNL(); 1901 ASSERT_RTNL();
1862 1902
1903 /* check the lifetime */
1904 if (!valid_lft || prefered_lft > valid_lft)
1905 return -EINVAL;
1906
1863 if ((dev = __dev_get_by_index(ifindex)) == NULL) 1907 if ((dev = __dev_get_by_index(ifindex)) == NULL)
1864 return -ENODEV; 1908 return -ENODEV;
1865 1909
1866 if (!(dev->flags&IFF_UP))
1867 return -ENETDOWN;
1868
1869 if ((idev = addrconf_add_dev(dev)) == NULL) 1910 if ((idev = addrconf_add_dev(dev)) == NULL)
1870 return -ENOBUFS; 1911 return -ENOBUFS;
1871 1912
1872 scope = ipv6_addr_scope(pfx); 1913 scope = ipv6_addr_scope(pfx);
1873 1914
1874 ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT); 1915 if (valid_lft == INFINITY_LIFE_TIME)
1916 ifa_flags |= IFA_F_PERMANENT;
1917 else if (valid_lft >= 0x7FFFFFFF/HZ)
1918 valid_lft = 0x7FFFFFFF/HZ;
1919
1920 if (prefered_lft == 0)
1921 ifa_flags |= IFA_F_DEPRECATED;
1922 else if ((prefered_lft >= 0x7FFFFFFF/HZ) &&
1923 (prefered_lft != INFINITY_LIFE_TIME))
1924 prefered_lft = 0x7FFFFFFF/HZ;
1925
1926 ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags);
1927
1875 if (!IS_ERR(ifp)) { 1928 if (!IS_ERR(ifp)) {
1929 spin_lock_bh(&ifp->lock);
1930 ifp->valid_lft = valid_lft;
1931 ifp->prefered_lft = prefered_lft;
1932 ifp->tstamp = jiffies;
1933 spin_unlock_bh(&ifp->lock);
1934
1876 addrconf_dad_start(ifp, 0); 1935 addrconf_dad_start(ifp, 0);
1877 in6_ifa_put(ifp); 1936 in6_ifa_put(ifp);
1937 addrconf_verify(0);
1878 return 0; 1938 return 0;
1879 } 1939 }
1880 1940
@@ -1927,7 +1987,8 @@ int addrconf_add_ifaddr(void __user *arg)
1927 return -EFAULT; 1987 return -EFAULT;
1928 1988
1929 rtnl_lock(); 1989 rtnl_lock();
1930 err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); 1990 err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen,
1991 IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
1931 rtnl_unlock(); 1992 rtnl_unlock();
1932 return err; 1993 return err;
1933} 1994}
@@ -2300,10 +2361,10 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2300 Do not dev_put! 2361 Do not dev_put!
2301 */ 2362 */
2302 if (how == 1) { 2363 if (how == 1) {
2303 write_lock_bh(&addrconf_lock);
2304 dev->ip6_ptr = NULL;
2305 idev->dead = 1; 2364 idev->dead = 1;
2306 write_unlock_bh(&addrconf_lock); 2365
2366 /* protected by rtnl_lock */
2367 rcu_assign_pointer(dev->ip6_ptr, NULL);
2307 2368
2308 /* Step 1.5: remove snmp6 entry */ 2369 /* Step 1.5: remove snmp6 entry */
2309 snmp6_unregister_dev(idev); 2370 snmp6_unregister_dev(idev);
@@ -2470,7 +2531,8 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
2470 spin_lock_bh(&ifp->lock); 2531 spin_lock_bh(&ifp->lock);
2471 2532
2472 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || 2533 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
2473 !(ifp->flags&IFA_F_TENTATIVE)) { 2534 !(ifp->flags&IFA_F_TENTATIVE) ||
2535 ifp->flags & IFA_F_NODAD) {
2474 ifp->flags &= ~IFA_F_TENTATIVE; 2536 ifp->flags &= ~IFA_F_TENTATIVE;
2475 spin_unlock_bh(&ifp->lock); 2537 spin_unlock_bh(&ifp->lock);
2476 read_unlock_bh(&idev->lock); 2538 read_unlock_bh(&idev->lock);
@@ -2715,6 +2777,26 @@ void if6_proc_exit(void)
2715} 2777}
2716#endif /* CONFIG_PROC_FS */ 2778#endif /* CONFIG_PROC_FS */
2717 2779
2780#ifdef CONFIG_IPV6_MIP6
2781/* Check if address is a home address configured on any interface. */
2782int ipv6_chk_home_addr(struct in6_addr *addr)
2783{
2784 int ret = 0;
2785 struct inet6_ifaddr * ifp;
2786 u8 hash = ipv6_addr_hash(addr);
2787 read_lock_bh(&addrconf_hash_lock);
2788 for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
2789 if (ipv6_addr_cmp(&ifp->addr, addr) == 0 &&
2790 (ifp->flags & IFA_F_HOMEADDRESS)) {
2791 ret = 1;
2792 break;
2793 }
2794 }
2795 read_unlock_bh(&addrconf_hash_lock);
2796 return ret;
2797}
2798#endif
2799
2718/* 2800/*
2719 * Periodic address status verification 2801 * Periodic address status verification
2720 */ 2802 */
@@ -2753,12 +2835,16 @@ restart:
2753 ifp->idev->nd_parms->retrans_time / HZ; 2835 ifp->idev->nd_parms->retrans_time / HZ;
2754#endif 2836#endif
2755 2837
2756 if (age >= ifp->valid_lft) { 2838 if (ifp->valid_lft != INFINITY_LIFE_TIME &&
2839 age >= ifp->valid_lft) {
2757 spin_unlock(&ifp->lock); 2840 spin_unlock(&ifp->lock);
2758 in6_ifa_hold(ifp); 2841 in6_ifa_hold(ifp);
2759 read_unlock(&addrconf_hash_lock); 2842 read_unlock(&addrconf_hash_lock);
2760 ipv6_del_addr(ifp); 2843 ipv6_del_addr(ifp);
2761 goto restart; 2844 goto restart;
2845 } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) {
2846 spin_unlock(&ifp->lock);
2847 continue;
2762 } else if (age >= ifp->prefered_lft) { 2848 } else if (age >= ifp->prefered_lft) {
2763 /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */ 2849 /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */
2764 int deprecate = 0; 2850 int deprecate = 0;
@@ -2821,178 +2907,267 @@ restart:
2821 spin_unlock_bh(&addrconf_verify_lock); 2907 spin_unlock_bh(&addrconf_verify_lock);
2822} 2908}
2823 2909
2910static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
2911{
2912 struct in6_addr *pfx = NULL;
2913
2914 if (addr)
2915 pfx = nla_data(addr);
2916
2917 if (local) {
2918 if (pfx && nla_memcmp(local, pfx, sizeof(*pfx)))
2919 pfx = NULL;
2920 else
2921 pfx = nla_data(local);
2922 }
2923
2924 return pfx;
2925}
2926
2927static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = {
2928 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) },
2929 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) },
2930 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
2931};
2932
2824static int 2933static int
2825inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 2934inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2826{ 2935{
2827 struct rtattr **rta = arg; 2936 struct ifaddrmsg *ifm;
2828 struct ifaddrmsg *ifm = NLMSG_DATA(nlh); 2937 struct nlattr *tb[IFA_MAX+1];
2829 struct in6_addr *pfx; 2938 struct in6_addr *pfx;
2939 int err;
2830 2940
2831 pfx = NULL; 2941 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
2832 if (rta[IFA_ADDRESS-1]) { 2942 if (err < 0)
2833 if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*pfx)) 2943 return err;
2834 return -EINVAL; 2944
2835 pfx = RTA_DATA(rta[IFA_ADDRESS-1]); 2945 ifm = nlmsg_data(nlh);
2836 } 2946 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
2837 if (rta[IFA_LOCAL-1]) {
2838 if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))
2839 return -EINVAL;
2840 pfx = RTA_DATA(rta[IFA_LOCAL-1]);
2841 }
2842 if (pfx == NULL) 2947 if (pfx == NULL)
2843 return -EINVAL; 2948 return -EINVAL;
2844 2949
2845 return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); 2950 return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen);
2846} 2951}
2847 2952
2953static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
2954 u32 prefered_lft, u32 valid_lft)
2955{
2956 if (!valid_lft || (prefered_lft > valid_lft))
2957 return -EINVAL;
2958
2959 if (valid_lft == INFINITY_LIFE_TIME)
2960 ifa_flags |= IFA_F_PERMANENT;
2961 else if (valid_lft >= 0x7FFFFFFF/HZ)
2962 valid_lft = 0x7FFFFFFF/HZ;
2963
2964 if (prefered_lft == 0)
2965 ifa_flags |= IFA_F_DEPRECATED;
2966 else if ((prefered_lft >= 0x7FFFFFFF/HZ) &&
2967 (prefered_lft != INFINITY_LIFE_TIME))
2968 prefered_lft = 0x7FFFFFFF/HZ;
2969
2970 spin_lock_bh(&ifp->lock);
2971 ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags;
2972 ifp->tstamp = jiffies;
2973 ifp->valid_lft = valid_lft;
2974 ifp->prefered_lft = prefered_lft;
2975
2976 spin_unlock_bh(&ifp->lock);
2977 if (!(ifp->flags&IFA_F_TENTATIVE))
2978 ipv6_ifa_notify(0, ifp);
2979
2980 addrconf_verify(0);
2981
2982 return 0;
2983}
2984
2848static int 2985static int
2849inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 2986inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2850{ 2987{
2851 struct rtattr **rta = arg; 2988 struct ifaddrmsg *ifm;
2852 struct ifaddrmsg *ifm = NLMSG_DATA(nlh); 2989 struct nlattr *tb[IFA_MAX+1];
2853 struct in6_addr *pfx; 2990 struct in6_addr *pfx;
2991 struct inet6_ifaddr *ifa;
2992 struct net_device *dev;
2993 u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME;
2994 u8 ifa_flags;
2995 int err;
2854 2996
2855 pfx = NULL; 2997 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
2856 if (rta[IFA_ADDRESS-1]) { 2998 if (err < 0)
2857 if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*pfx)) 2999 return err;
2858 return -EINVAL; 3000
2859 pfx = RTA_DATA(rta[IFA_ADDRESS-1]); 3001 ifm = nlmsg_data(nlh);
2860 } 3002 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
2861 if (rta[IFA_LOCAL-1]) {
2862 if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))
2863 return -EINVAL;
2864 pfx = RTA_DATA(rta[IFA_LOCAL-1]);
2865 }
2866 if (pfx == NULL) 3003 if (pfx == NULL)
2867 return -EINVAL; 3004 return -EINVAL;
2868 3005
2869 return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen); 3006 if (tb[IFA_CACHEINFO]) {
3007 struct ifa_cacheinfo *ci;
3008
3009 ci = nla_data(tb[IFA_CACHEINFO]);
3010 valid_lft = ci->ifa_valid;
3011 preferred_lft = ci->ifa_prefered;
3012 } else {
3013 preferred_lft = INFINITY_LIFE_TIME;
3014 valid_lft = INFINITY_LIFE_TIME;
3015 }
3016
3017 dev = __dev_get_by_index(ifm->ifa_index);
3018 if (dev == NULL)
3019 return -ENODEV;
3020
3021 /* We ignore other flags so far. */
3022 ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
3023
3024 ifa = ipv6_get_ifaddr(pfx, dev, 1);
3025 if (ifa == NULL) {
3026 /*
3027 * It would be best to check for !NLM_F_CREATE here but
3028 * userspace alreay relies on not having to provide this.
3029 */
3030 return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
3031 ifa_flags, preferred_lft, valid_lft);
3032 }
3033
3034 if (nlh->nlmsg_flags & NLM_F_EXCL ||
3035 !(nlh->nlmsg_flags & NLM_F_REPLACE))
3036 err = -EEXIST;
3037 else
3038 err = inet6_addr_modify(ifa, ifa_flags, preferred_lft, valid_lft);
3039
3040 in6_ifa_put(ifa);
3041
3042 return err;
3043}
3044
3045static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags,
3046 u8 scope, int ifindex)
3047{
3048 struct ifaddrmsg *ifm;
3049
3050 ifm = nlmsg_data(nlh);
3051 ifm->ifa_family = AF_INET6;
3052 ifm->ifa_prefixlen = prefixlen;
3053 ifm->ifa_flags = flags;
3054 ifm->ifa_scope = scope;
3055 ifm->ifa_index = ifindex;
3056}
3057
3058static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
3059 unsigned long tstamp, u32 preferred, u32 valid)
3060{
3061 struct ifa_cacheinfo ci;
3062
3063 ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100
3064 + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3065 ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
3066 + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3067 ci.ifa_prefered = preferred;
3068 ci.ifa_valid = valid;
3069
3070 return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
2870} 3071}
2871 3072
2872/* Maximum length of ifa_cacheinfo attributes */ 3073static inline int rt_scope(int ifa_scope)
2873#define INET6_IFADDR_RTA_SPACE \ 3074{
2874 RTA_SPACE(16) /* IFA_ADDRESS */ + \ 3075 if (ifa_scope & IFA_HOST)
2875 RTA_SPACE(sizeof(struct ifa_cacheinfo)) /* CACHEINFO */ 3076 return RT_SCOPE_HOST;
3077 else if (ifa_scope & IFA_LINK)
3078 return RT_SCOPE_LINK;
3079 else if (ifa_scope & IFA_SITE)
3080 return RT_SCOPE_SITE;
3081 else
3082 return RT_SCOPE_UNIVERSE;
3083}
3084
3085static inline int inet6_ifaddr_msgsize(void)
3086{
3087 return nlmsg_total_size(sizeof(struct ifaddrmsg) +
3088 nla_total_size(16) +
3089 nla_total_size(sizeof(struct ifa_cacheinfo)) +
3090 128);
3091}
2876 3092
2877static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3093static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
2878 u32 pid, u32 seq, int event, unsigned int flags) 3094 u32 pid, u32 seq, int event, unsigned int flags)
2879{ 3095{
2880 struct ifaddrmsg *ifm;
2881 struct nlmsghdr *nlh; 3096 struct nlmsghdr *nlh;
2882 struct ifa_cacheinfo ci; 3097 u32 preferred, valid;
2883 unsigned char *b = skb->tail; 3098
3099 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3100 if (nlh == NULL)
3101 return -ENOBUFS;
3102
3103 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
3104 ifa->idev->dev->ifindex);
2884 3105
2885 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
2886 ifm = NLMSG_DATA(nlh);
2887 ifm->ifa_family = AF_INET6;
2888 ifm->ifa_prefixlen = ifa->prefix_len;
2889 ifm->ifa_flags = ifa->flags;
2890 ifm->ifa_scope = RT_SCOPE_UNIVERSE;
2891 if (ifa->scope&IFA_HOST)
2892 ifm->ifa_scope = RT_SCOPE_HOST;
2893 else if (ifa->scope&IFA_LINK)
2894 ifm->ifa_scope = RT_SCOPE_LINK;
2895 else if (ifa->scope&IFA_SITE)
2896 ifm->ifa_scope = RT_SCOPE_SITE;
2897 ifm->ifa_index = ifa->idev->dev->ifindex;
2898 RTA_PUT(skb, IFA_ADDRESS, 16, &ifa->addr);
2899 if (!(ifa->flags&IFA_F_PERMANENT)) { 3106 if (!(ifa->flags&IFA_F_PERMANENT)) {
2900 ci.ifa_prefered = ifa->prefered_lft; 3107 preferred = ifa->prefered_lft;
2901 ci.ifa_valid = ifa->valid_lft; 3108 valid = ifa->valid_lft;
2902 if (ci.ifa_prefered != INFINITY_LIFE_TIME) { 3109 if (preferred != INFINITY_LIFE_TIME) {
2903 long tval = (jiffies - ifa->tstamp)/HZ; 3110 long tval = (jiffies - ifa->tstamp)/HZ;
2904 ci.ifa_prefered -= tval; 3111 preferred -= tval;
2905 if (ci.ifa_valid != INFINITY_LIFE_TIME) 3112 if (valid != INFINITY_LIFE_TIME)
2906 ci.ifa_valid -= tval; 3113 valid -= tval;
2907 } 3114 }
2908 } else { 3115 } else {
2909 ci.ifa_prefered = INFINITY_LIFE_TIME; 3116 preferred = INFINITY_LIFE_TIME;
2910 ci.ifa_valid = INFINITY_LIFE_TIME; 3117 valid = INFINITY_LIFE_TIME;
2911 } 3118 }
2912 ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) / HZ * 100
2913 + TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
2914 ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) / HZ * 100
2915 + TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
2916 RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
2917 nlh->nlmsg_len = skb->tail - b;
2918 return skb->len;
2919 3119
2920nlmsg_failure: 3120 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 ||
2921rtattr_failure: 3121 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0)
2922 skb_trim(skb, b - skb->data); 3122 return nlmsg_cancel(skb, nlh);
2923 return -1; 3123
3124 return nlmsg_end(skb, nlh);
2924} 3125}
2925 3126
2926static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3127static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
2927 u32 pid, u32 seq, int event, u16 flags) 3128 u32 pid, u32 seq, int event, u16 flags)
2928{ 3129{
2929 struct ifaddrmsg *ifm;
2930 struct nlmsghdr *nlh; 3130 struct nlmsghdr *nlh;
2931 struct ifa_cacheinfo ci; 3131 u8 scope = RT_SCOPE_UNIVERSE;
2932 unsigned char *b = skb->tail; 3132 int ifindex = ifmca->idev->dev->ifindex;
2933
2934 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
2935 ifm = NLMSG_DATA(nlh);
2936 ifm->ifa_family = AF_INET6;
2937 ifm->ifa_prefixlen = 128;
2938 ifm->ifa_flags = IFA_F_PERMANENT;
2939 ifm->ifa_scope = RT_SCOPE_UNIVERSE;
2940 if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
2941 ifm->ifa_scope = RT_SCOPE_SITE;
2942 ifm->ifa_index = ifmca->idev->dev->ifindex;
2943 RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
2944 ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ
2945 * 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ
2946 * 100 / HZ);
2947 ci.tstamp = (__u32)(TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) / HZ
2948 * 100 + TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) % HZ
2949 * 100 / HZ);
2950 ci.ifa_prefered = INFINITY_LIFE_TIME;
2951 ci.ifa_valid = INFINITY_LIFE_TIME;
2952 RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
2953 nlh->nlmsg_len = skb->tail - b;
2954 return skb->len;
2955 3133
2956nlmsg_failure: 3134 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
2957rtattr_failure: 3135 scope = RT_SCOPE_SITE;
2958 skb_trim(skb, b - skb->data); 3136
2959 return -1; 3137 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3138 if (nlh == NULL)
3139 return -ENOBUFS;
3140
3141 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3142 if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 ||
3143 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
3144 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0)
3145 return nlmsg_cancel(skb, nlh);
3146
3147 return nlmsg_end(skb, nlh);
2960} 3148}
2961 3149
2962static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, 3150static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
2963 u32 pid, u32 seq, int event, unsigned int flags) 3151 u32 pid, u32 seq, int event, unsigned int flags)
2964{ 3152{
2965 struct ifaddrmsg *ifm;
2966 struct nlmsghdr *nlh; 3153 struct nlmsghdr *nlh;
2967 struct ifa_cacheinfo ci; 3154 u8 scope = RT_SCOPE_UNIVERSE;
2968 unsigned char *b = skb->tail; 3155 int ifindex = ifaca->aca_idev->dev->ifindex;
2969
2970 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
2971 ifm = NLMSG_DATA(nlh);
2972 ifm->ifa_family = AF_INET6;
2973 ifm->ifa_prefixlen = 128;
2974 ifm->ifa_flags = IFA_F_PERMANENT;
2975 ifm->ifa_scope = RT_SCOPE_UNIVERSE;
2976 if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
2977 ifm->ifa_scope = RT_SCOPE_SITE;
2978 ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
2979 RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
2980 ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ
2981 * 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ
2982 * 100 / HZ);
2983 ci.tstamp = (__u32)(TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) / HZ
2984 * 100 + TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) % HZ
2985 * 100 / HZ);
2986 ci.ifa_prefered = INFINITY_LIFE_TIME;
2987 ci.ifa_valid = INFINITY_LIFE_TIME;
2988 RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
2989 nlh->nlmsg_len = skb->tail - b;
2990 return skb->len;
2991 3156
2992nlmsg_failure: 3157 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
2993rtattr_failure: 3158 scope = RT_SCOPE_SITE;
2994 skb_trim(skb, b - skb->data); 3159
2995 return -1; 3160 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3161 if (nlh == NULL)
3162 return -ENOBUFS;
3163
3164 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3165 if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 ||
3166 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
3167 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0)
3168 return nlmsg_cancel(skb, nlh);
3169
3170 return nlmsg_end(skb, nlh);
2996} 3171}
2997 3172
2998enum addr_type_t 3173enum addr_type_t
@@ -3103,23 +3278,74 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
3103 return inet6_dump_addr(skb, cb, type); 3278 return inet6_dump_addr(skb, cb, type);
3104} 3279}
3105 3280
3106static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) 3281static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3282 void *arg)
3107{ 3283{
3284 struct ifaddrmsg *ifm;
3285 struct nlattr *tb[IFA_MAX+1];
3286 struct in6_addr *addr = NULL;
3287 struct net_device *dev = NULL;
3288 struct inet6_ifaddr *ifa;
3108 struct sk_buff *skb; 3289 struct sk_buff *skb;
3109 int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE); 3290 int err;
3110 3291
3111 skb = alloc_skb(size, GFP_ATOMIC); 3292 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
3112 if (!skb) { 3293 if (err < 0)
3113 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFADDR, ENOBUFS); 3294 goto errout;
3114 return; 3295
3296 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]);
3297 if (addr == NULL) {
3298 err = -EINVAL;
3299 goto errout;
3300 }
3301
3302 ifm = nlmsg_data(nlh);
3303 if (ifm->ifa_index)
3304 dev = __dev_get_by_index(ifm->ifa_index);
3305
3306 if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
3307 err = -EADDRNOTAVAIL;
3308 goto errout;
3115 } 3309 }
3116 if (inet6_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) { 3310
3311 if ((skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL)) == NULL) {
3312 err = -ENOBUFS;
3313 goto errout_ifa;
3314 }
3315
3316 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3317 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3318 if (err < 0) {
3117 kfree_skb(skb); 3319 kfree_skb(skb);
3118 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFADDR, EINVAL); 3320 goto errout_ifa;
3119 return; 3321 }
3322
3323 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
3324errout_ifa:
3325 in6_ifa_put(ifa);
3326errout:
3327 return err;
3328}
3329
3330static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3331{
3332 struct sk_buff *skb;
3333 int err = -ENOBUFS;
3334
3335 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
3336 if (skb == NULL)
3337 goto errout;
3338
3339 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3340 if (err < 0) {
3341 kfree_skb(skb);
3342 goto errout;
3120 } 3343 }
3121 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_IFADDR; 3344
3122 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFADDR, GFP_ATOMIC); 3345 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3346errout:
3347 if (err < 0)
3348 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
3123} 3349}
3124 3350
3125static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, 3351static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
@@ -3154,6 +3380,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
3154 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; 3380 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
3155#endif 3381#endif
3156#endif 3382#endif
3383 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
3157} 3384}
3158 3385
3159/* Maximum length of ifinfomsg attributes */ 3386/* Maximum length of ifinfomsg attributes */
@@ -3260,20 +3487,23 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3260void inet6_ifinfo_notify(int event, struct inet6_dev *idev) 3487void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3261{ 3488{
3262 struct sk_buff *skb; 3489 struct sk_buff *skb;
3263 int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE); 3490 int payload = sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE;
3491 int err = -ENOBUFS;
3264 3492
3265 skb = alloc_skb(size, GFP_ATOMIC); 3493 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC);
3266 if (!skb) { 3494 if (skb == NULL)
3267 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFINFO, ENOBUFS); 3495 goto errout;
3268 return; 3496
3269 } 3497 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3270 if (inet6_fill_ifinfo(skb, idev, current->pid, 0, event, 0) < 0) { 3498 if (err < 0) {
3271 kfree_skb(skb); 3499 kfree_skb(skb);
3272 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_IFINFO, EINVAL); 3500 goto errout;
3273 return;
3274 } 3501 }
3275 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_IFINFO; 3502
3276 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_IFINFO, GFP_ATOMIC); 3503 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3504errout:
3505 if (err < 0)
3506 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
3277} 3507}
3278 3508
3279/* Maximum length of prefix_cacheinfo attributes */ 3509/* Maximum length of prefix_cacheinfo attributes */
@@ -3325,33 +3555,40 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3325 struct prefix_info *pinfo) 3555 struct prefix_info *pinfo)
3326{ 3556{
3327 struct sk_buff *skb; 3557 struct sk_buff *skb;
3328 int size = NLMSG_SPACE(sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE); 3558 int payload = sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE;
3559 int err = -ENOBUFS;
3329 3560
3330 skb = alloc_skb(size, GFP_ATOMIC); 3561 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC);
3331 if (!skb) { 3562 if (skb == NULL)
3332 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_PREFIX, ENOBUFS); 3563 goto errout;
3333 return; 3564
3334 } 3565 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3335 if (inet6_fill_prefix(skb, idev, pinfo, current->pid, 0, event, 0) < 0) { 3566 if (err < 0) {
3336 kfree_skb(skb); 3567 kfree_skb(skb);
3337 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_PREFIX, EINVAL); 3568 goto errout;
3338 return;
3339 } 3569 }
3340 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_PREFIX; 3570
3341 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_PREFIX, GFP_ATOMIC); 3571 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3572errout:
3573 if (err < 0)
3574 rtnl_set_sk_err(RTNLGRP_IPV6_PREFIX, err);
3342} 3575}
3343 3576
3344static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { 3577static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = {
3345 [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, 3578 [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, },
3346 [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, 3579 [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, },
3347 [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, 3580 [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, },
3348 [RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, }, 3581 [RTM_GETADDR - RTM_BASE] = { .doit = inet6_rtm_getaddr,
3582 .dumpit = inet6_dump_ifaddr, },
3349 [RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, }, 3583 [RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
3350 [RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, }, 3584 [RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, },
3351 [RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, }, 3585 [RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, },
3352 [RTM_DELROUTE - RTM_BASE] = { .doit = inet6_rtm_delroute, }, 3586 [RTM_DELROUTE - RTM_BASE] = { .doit = inet6_rtm_delroute, },
3353 [RTM_GETROUTE - RTM_BASE] = { .doit = inet6_rtm_getroute, 3587 [RTM_GETROUTE - RTM_BASE] = { .doit = inet6_rtm_getroute,
3354 .dumpit = inet6_dump_fib, }, 3588 .dumpit = inet6_dump_fib, },
3589#ifdef CONFIG_IPV6_MULTIPLE_TABLES
3590 [RTM_GETRULE - RTM_BASE] = { .dumpit = fib6_rules_dump, },
3591#endif
3355}; 3592};
3356 3593
3357static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) 3594static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
@@ -3360,7 +3597,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3360 3597
3361 switch (event) { 3598 switch (event) {
3362 case RTM_NEWADDR: 3599 case RTM_NEWADDR:
3363 ip6_ins_rt(ifp->rt, NULL, NULL, NULL); 3600 ip6_ins_rt(ifp->rt);
3364 if (ifp->idev->cnf.forwarding) 3601 if (ifp->idev->cnf.forwarding)
3365 addrconf_join_anycast(ifp); 3602 addrconf_join_anycast(ifp);
3366 break; 3603 break;
@@ -3369,7 +3606,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3369 addrconf_leave_anycast(ifp); 3606 addrconf_leave_anycast(ifp);
3370 addrconf_leave_solict(ifp->idev, &ifp->addr); 3607 addrconf_leave_solict(ifp->idev, &ifp->addr);
3371 dst_hold(&ifp->rt->u.dst); 3608 dst_hold(&ifp->rt->u.dst);
3372 if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) 3609 if (ip6_del_rt(ifp->rt))
3373 dst_free(&ifp->rt->u.dst); 3610 dst_free(&ifp->rt->u.dst);
3374 break; 3611 break;
3375 } 3612 }
@@ -3377,10 +3614,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3377 3614
3378static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) 3615static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3379{ 3616{
3380 read_lock_bh(&addrconf_lock); 3617 rcu_read_lock_bh();
3381 if (likely(ifp->idev->dead == 0)) 3618 if (likely(ifp->idev->dead == 0))
3382 __ipv6_ifa_notify(event, ifp); 3619 __ipv6_ifa_notify(event, ifp);
3383 read_unlock_bh(&addrconf_lock); 3620 rcu_read_unlock_bh();
3384} 3621}
3385 3622
3386#ifdef CONFIG_SYSCTL 3623#ifdef CONFIG_SYSCTL
@@ -3477,7 +3714,7 @@ static struct addrconf_sysctl_table
3477 ctl_table addrconf_conf_dir[2]; 3714 ctl_table addrconf_conf_dir[2];
3478 ctl_table addrconf_proto_dir[2]; 3715 ctl_table addrconf_proto_dir[2];
3479 ctl_table addrconf_root_dir[2]; 3716 ctl_table addrconf_root_dir[2];
3480} addrconf_sysctl = { 3717} addrconf_sysctl __read_mostly = {
3481 .sysctl_header = NULL, 3718 .sysctl_header = NULL,
3482 .addrconf_vars = { 3719 .addrconf_vars = {
3483 { 3720 {
@@ -3667,6 +3904,14 @@ static struct addrconf_sysctl_table
3667#endif 3904#endif
3668#endif 3905#endif
3669 { 3906 {
3907 .ctl_name = NET_IPV6_PROXY_NDP,
3908 .procname = "proxy_ndp",
3909 .data = &ipv6_devconf.proxy_ndp,
3910 .maxlen = sizeof(int),
3911 .mode = 0644,
3912 .proc_handler = &proc_dointvec,
3913 },
3914 {
3670 .ctl_name = 0, /* sentinel */ 3915 .ctl_name = 0, /* sentinel */
3671 } 3916 }
3672 }, 3917 },
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e19457fe4f6e..e94eccb99707 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -23,7 +23,6 @@
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/capability.h> 25#include <linux/capability.h>
26#include <linux/config.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/types.h> 27#include <linux/types.h>
29#include <linux/socket.h> 28#include <linux/socket.h>
@@ -60,6 +59,9 @@
60#ifdef CONFIG_IPV6_TUNNEL 59#ifdef CONFIG_IPV6_TUNNEL
61#include <net/ip6_tunnel.h> 60#include <net/ip6_tunnel.h>
62#endif 61#endif
62#ifdef CONFIG_IPV6_MIP6
63#include <net/mip6.h>
64#endif
63 65
64#include <asm/uaccess.h> 66#include <asm/uaccess.h>
65#include <asm/system.h> 67#include <asm/system.h>
@@ -68,7 +70,7 @@ MODULE_AUTHOR("Cast of dozens");
68MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); 70MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
69MODULE_LICENSE("GPL"); 71MODULE_LICENSE("GPL");
70 72
71int sysctl_ipv6_bindv6only; 73int sysctl_ipv6_bindv6only __read_mostly;
72 74
73/* The inetsw table contains everything that inet_create needs to 75/* The inetsw table contains everything that inet_create needs to
74 * build a new socket. 76 * build a new socket.
@@ -244,7 +246,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
244 struct sock *sk = sock->sk; 246 struct sock *sk = sock->sk;
245 struct inet_sock *inet = inet_sk(sk); 247 struct inet_sock *inet = inet_sk(sk);
246 struct ipv6_pinfo *np = inet6_sk(sk); 248 struct ipv6_pinfo *np = inet6_sk(sk);
247 __u32 v4addr = 0; 249 __be32 v4addr = 0;
248 unsigned short snum; 250 unsigned short snum;
249 int addr_type = 0; 251 int addr_type = 0;
250 int err = 0; 252 int err = 0;
@@ -638,6 +640,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
638 fl.oif = sk->sk_bound_dev_if; 640 fl.oif = sk->sk_bound_dev_if;
639 fl.fl_ip_dport = inet->dport; 641 fl.fl_ip_dport = inet->dport;
640 fl.fl_ip_sport = inet->sport; 642 fl.fl_ip_sport = inet->sport;
643 security_sk_classify_flow(sk, &fl);
641 644
642 if (np->opt && np->opt->srcrt) { 645 if (np->opt && np->opt->srcrt) {
643 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; 646 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
@@ -659,9 +662,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
659 return err; 662 return err;
660 } 663 }
661 664
662 ip6_dst_store(sk, dst, NULL); 665 __ip6_dst_store(sk, dst, NULL, NULL);
663 sk->sk_route_caps = dst->dev->features &
664 ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
665 } 666 }
666 667
667 return 0; 668 return 0;
@@ -760,6 +761,8 @@ static int __init inet6_init(void)
760 struct list_head *r; 761 struct list_head *r;
761 int err; 762 int err;
762 763
764 BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb));
765
763#ifdef MODULE 766#ifdef MODULE
764#if 0 /* FIXME --RR */ 767#if 0 /* FIXME --RR */
765 if (!mod_member_present(&__this_module, can_unload)) 768 if (!mod_member_present(&__this_module, can_unload))
@@ -769,11 +772,6 @@ static int __init inet6_init(void)
769#endif 772#endif
770#endif 773#endif
771 774
772 if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)) {
773 printk(KERN_CRIT "inet6_proto_init: size fault\n");
774 return -EINVAL;
775 }
776
777 err = proto_register(&tcpv6_prot, 1); 775 err = proto_register(&tcpv6_prot, 1);
778 if (err) 776 if (err)
779 goto out; 777 goto out;
@@ -859,6 +857,9 @@ static int __init inet6_init(void)
859 ipv6_frag_init(); 857 ipv6_frag_init();
860 ipv6_nodata_init(); 858 ipv6_nodata_init();
861 ipv6_destopt_init(); 859 ipv6_destopt_init();
860#ifdef CONFIG_IPV6_MIP6
861 mip6_init();
862#endif
862 863
863 /* Init v6 transport protocols. */ 864 /* Init v6 transport protocols. */
864 udpv6_init(); 865 udpv6_init();
@@ -922,6 +923,9 @@ static void __exit inet6_exit(void)
922 tcp6_proc_exit(); 923 tcp6_proc_exit();
923 raw6_proc_exit(); 924 raw6_proc_exit();
924#endif 925#endif
926#ifdef CONFIG_IPV6_MIP6
927 mip6_fini();
928#endif
925 /* Cleanup code parts. */ 929 /* Cleanup code parts. */
926 sit_cleanup(); 930 sit_cleanup();
927 ip6_flowlabel_cleanup(); 931 ip6_flowlabel_cleanup();
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index d31c0d6c0448..b0d83e8e4252 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -24,7 +24,6 @@
24 * This file is derived from net/ipv4/ah.c. 24 * This file is derived from net/ipv4/ah.c.
25 */ 25 */
26 26
27#include <linux/config.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <net/ip.h> 28#include <net/ip.h>
30#include <net/ah.h> 29#include <net/ah.h>
@@ -75,6 +74,66 @@ bad:
75 return 0; 74 return 0;
76} 75}
77 76
77#ifdef CONFIG_IPV6_MIP6
78/**
79 * ipv6_rearrange_destopt - rearrange IPv6 destination options header
80 * @iph: IPv6 header
81 * @destopt: destionation options header
82 */
83static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt)
84{
85 u8 *opt = (u8 *)destopt;
86 int len = ipv6_optlen(destopt);
87 int off = 0;
88 int optlen = 0;
89
90 off += 2;
91 len -= 2;
92
93 while (len > 0) {
94
95 switch (opt[off]) {
96
97 case IPV6_TLV_PAD0:
98 optlen = 1;
99 break;
100 default:
101 if (len < 2)
102 goto bad;
103 optlen = opt[off+1]+2;
104 if (len < optlen)
105 goto bad;
106
107 /* Rearrange the source address in @iph and the
108 * addresses in home address option for final source.
109 * See 11.3.2 of RFC 3775 for details.
110 */
111 if (opt[off] == IPV6_TLV_HAO) {
112 struct in6_addr final_addr;
113 struct ipv6_destopt_hao *hao;
114
115 hao = (struct ipv6_destopt_hao *)&opt[off];
116 if (hao->length != sizeof(hao->addr)) {
117 if (net_ratelimit())
118 printk(KERN_WARNING "destopt hao: invalid header length: %u\n", hao->length);
119 goto bad;
120 }
121 ipv6_addr_copy(&final_addr, &hao->addr);
122 ipv6_addr_copy(&hao->addr, &iph->saddr);
123 ipv6_addr_copy(&iph->saddr, &final_addr);
124 }
125 break;
126 }
127
128 off += optlen;
129 len -= optlen;
130 }
131 /* Note: ok if len == 0 */
132bad:
133 return;
134}
135#endif
136
78/** 137/**
79 * ipv6_rearrange_rthdr - rearrange IPv6 routing header 138 * ipv6_rearrange_rthdr - rearrange IPv6 routing header
80 * @iph: IPv6 header 139 * @iph: IPv6 header
@@ -114,7 +173,7 @@ static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
114 ipv6_addr_copy(&iph->daddr, &final_addr); 173 ipv6_addr_copy(&iph->daddr, &final_addr);
115} 174}
116 175
117static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len) 176static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
118{ 177{
119 union { 178 union {
120 struct ipv6hdr *iph; 179 struct ipv6hdr *iph;
@@ -129,8 +188,12 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len)
129 188
130 while (exthdr.raw < end) { 189 while (exthdr.raw < end) {
131 switch (nexthdr) { 190 switch (nexthdr) {
132 case NEXTHDR_HOP:
133 case NEXTHDR_DEST: 191 case NEXTHDR_DEST:
192#ifdef CONFIG_IPV6_MIP6
193 if (dir == XFRM_POLICY_OUT)
194 ipv6_rearrange_destopt(iph, exthdr.opth);
195#endif
196 case NEXTHDR_HOP:
134 if (!zero_out_mutable_opts(exthdr.opth)) { 197 if (!zero_out_mutable_opts(exthdr.opth)) {
135 LIMIT_NETDEBUG( 198 LIMIT_NETDEBUG(
136 KERN_WARNING "overrun %sopts\n", 199 KERN_WARNING "overrun %sopts\n",
@@ -165,6 +228,9 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
165 u8 nexthdr; 228 u8 nexthdr;
166 char tmp_base[8]; 229 char tmp_base[8];
167 struct { 230 struct {
231#ifdef CONFIG_IPV6_MIP6
232 struct in6_addr saddr;
233#endif
168 struct in6_addr daddr; 234 struct in6_addr daddr;
169 char hdrs[0]; 235 char hdrs[0];
170 } *tmp_ext; 236 } *tmp_ext;
@@ -189,10 +255,15 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
189 err = -ENOMEM; 255 err = -ENOMEM;
190 goto error; 256 goto error;
191 } 257 }
258#ifdef CONFIG_IPV6_MIP6
259 memcpy(tmp_ext, &top_iph->saddr, extlen);
260#else
192 memcpy(tmp_ext, &top_iph->daddr, extlen); 261 memcpy(tmp_ext, &top_iph->daddr, extlen);
262#endif
193 err = ipv6_clear_mutable_options(top_iph, 263 err = ipv6_clear_mutable_options(top_iph,
194 extlen - sizeof(*tmp_ext) + 264 extlen - sizeof(*tmp_ext) +
195 sizeof(*top_iph)); 265 sizeof(*top_iph),
266 XFRM_POLICY_OUT);
196 if (err) 267 if (err)
197 goto error_free_iph; 268 goto error_free_iph;
198 } 269 }
@@ -214,13 +285,20 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
214 ah->spi = x->id.spi; 285 ah->spi = x->id.spi;
215 ah->seq_no = htonl(++x->replay.oseq); 286 ah->seq_no = htonl(++x->replay.oseq);
216 xfrm_aevent_doreplay(x); 287 xfrm_aevent_doreplay(x);
217 ahp->icv(ahp, skb, ah->auth_data); 288 err = ah_mac_digest(ahp, skb, ah->auth_data);
289 if (err)
290 goto error_free_iph;
291 memcpy(ah->auth_data, ahp->work_icv, ahp->icv_trunc_len);
218 292
219 err = 0; 293 err = 0;
220 294
221 memcpy(top_iph, tmp_base, sizeof(tmp_base)); 295 memcpy(top_iph, tmp_base, sizeof(tmp_base));
222 if (tmp_ext) { 296 if (tmp_ext) {
297#ifdef CONFIG_IPV6_MIP6
298 memcpy(&top_iph->saddr, tmp_ext, extlen);
299#else
223 memcpy(&top_iph->daddr, tmp_ext, extlen); 300 memcpy(&top_iph->daddr, tmp_ext, extlen);
301#endif
224error_free_iph: 302error_free_iph:
225 kfree(tmp_ext); 303 kfree(tmp_ext);
226 } 304 }
@@ -252,6 +330,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
252 u16 hdr_len; 330 u16 hdr_len;
253 u16 ah_hlen; 331 u16 ah_hlen;
254 int nexthdr; 332 int nexthdr;
333 int err = -EINVAL;
255 334
256 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) 335 if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
257 goto out; 336 goto out;
@@ -279,7 +358,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
279 if (!tmp_hdr) 358 if (!tmp_hdr)
280 goto out; 359 goto out;
281 memcpy(tmp_hdr, skb->nh.raw, hdr_len); 360 memcpy(tmp_hdr, skb->nh.raw, hdr_len);
282 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len)) 361 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
283 goto free_out; 362 goto free_out;
284 skb->nh.ipv6h->priority = 0; 363 skb->nh.ipv6h->priority = 0;
285 skb->nh.ipv6h->flow_lbl[0] = 0; 364 skb->nh.ipv6h->flow_lbl[0] = 0;
@@ -293,8 +372,11 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
293 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len); 372 memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
294 memset(ah->auth_data, 0, ahp->icv_trunc_len); 373 memset(ah->auth_data, 0, ahp->icv_trunc_len);
295 skb_push(skb, hdr_len); 374 skb_push(skb, hdr_len);
296 ahp->icv(ahp, skb, ah->auth_data); 375 err = ah_mac_digest(ahp, skb, ah->auth_data);
297 if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { 376 if (err)
377 goto free_out;
378 err = -EINVAL;
379 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
298 LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n"); 380 LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
299 x->stats.integrity_failed++; 381 x->stats.integrity_failed++;
300 goto free_out; 382 goto free_out;
@@ -311,7 +393,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
311free_out: 393free_out:
312 kfree(tmp_hdr); 394 kfree(tmp_hdr);
313out: 395out:
314 return -EINVAL; 396 return err;
315} 397}
316 398
317static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 399static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
@@ -339,6 +421,7 @@ static int ah6_init_state(struct xfrm_state *x)
339{ 421{
340 struct ah_data *ahp = NULL; 422 struct ah_data *ahp = NULL;
341 struct xfrm_algo_desc *aalg_desc; 423 struct xfrm_algo_desc *aalg_desc;
424 struct crypto_hash *tfm;
342 425
343 if (!x->aalg) 426 if (!x->aalg)
344 goto error; 427 goto error;
@@ -356,24 +439,27 @@ static int ah6_init_state(struct xfrm_state *x)
356 439
357 ahp->key = x->aalg->alg_key; 440 ahp->key = x->aalg->alg_key;
358 ahp->key_len = (x->aalg->alg_key_len+7)/8; 441 ahp->key_len = (x->aalg->alg_key_len+7)/8;
359 ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 442 tfm = crypto_alloc_hash(x->aalg->alg_name, 0, CRYPTO_ALG_ASYNC);
360 if (!ahp->tfm) 443 if (IS_ERR(tfm))
444 goto error;
445
446 ahp->tfm = tfm;
447 if (crypto_hash_setkey(tfm, ahp->key, ahp->key_len))
361 goto error; 448 goto error;
362 ahp->icv = ah_hmac_digest;
363 449
364 /* 450 /*
365 * Lookup the algorithm description maintained by xfrm_algo, 451 * Lookup the algorithm description maintained by xfrm_algo,
366 * verify crypto transform properties, and store information 452 * verify crypto transform properties, and store information
367 * we need for AH processing. This lookup cannot fail here 453 * we need for AH processing. This lookup cannot fail here
368 * after a successful crypto_alloc_tfm(). 454 * after a successful crypto_alloc_hash().
369 */ 455 */
370 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 456 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
371 BUG_ON(!aalg_desc); 457 BUG_ON(!aalg_desc);
372 458
373 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 459 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
374 crypto_tfm_alg_digestsize(ahp->tfm)) { 460 crypto_hash_digestsize(tfm)) {
375 printk(KERN_INFO "AH: %s digestsize %u != %hu\n", 461 printk(KERN_INFO "AH: %s digestsize %u != %hu\n",
376 x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm), 462 x->aalg->alg_name, crypto_hash_digestsize(tfm),
377 aalg_desc->uinfo.auth.icv_fullbits/8); 463 aalg_desc->uinfo.auth.icv_fullbits/8);
378 goto error; 464 goto error;
379 } 465 }
@@ -388,7 +474,7 @@ static int ah6_init_state(struct xfrm_state *x)
388 goto error; 474 goto error;
389 475
390 x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len); 476 x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len);
391 if (x->props.mode) 477 if (x->props.mode == XFRM_MODE_TUNNEL)
392 x->props.header_len += sizeof(struct ipv6hdr); 478 x->props.header_len += sizeof(struct ipv6hdr);
393 x->data = ahp; 479 x->data = ahp;
394 480
@@ -397,7 +483,7 @@ static int ah6_init_state(struct xfrm_state *x)
397error: 483error:
398 if (ahp) { 484 if (ahp) {
399 kfree(ahp->work_icv); 485 kfree(ahp->work_icv);
400 crypto_free_tfm(ahp->tfm); 486 crypto_free_hash(ahp->tfm);
401 kfree(ahp); 487 kfree(ahp);
402 } 488 }
403 return -EINVAL; 489 return -EINVAL;
@@ -412,7 +498,7 @@ static void ah6_destroy(struct xfrm_state *x)
412 498
413 kfree(ahp->work_icv); 499 kfree(ahp->work_icv);
414 ahp->work_icv = NULL; 500 ahp->work_icv = NULL;
415 crypto_free_tfm(ahp->tfm); 501 crypto_free_hash(ahp->tfm);
416 ahp->tfm = NULL; 502 ahp->tfm = NULL;
417 kfree(ahp); 503 kfree(ahp);
418} 504}
@@ -425,7 +511,8 @@ static struct xfrm_type ah6_type =
425 .init_state = ah6_init_state, 511 .init_state = ah6_init_state,
426 .destructor = ah6_destroy, 512 .destructor = ah6_destroy,
427 .input = ah6_input, 513 .input = ah6_input,
428 .output = ah6_output 514 .output = ah6_output,
515 .hdr_offset = xfrm6_find_1stfragopt,
429}; 516};
430 517
431static struct inet6_protocol ah6_protocol = { 518static struct inet6_protocol ah6_protocol = {
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 39ec528923f6..a9604764e015 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/capability.h> 16#include <linux/capability.h>
17#include <linux/config.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/errno.h> 18#include <linux/errno.h>
20#include <linux/types.h> 19#include <linux/types.h>
@@ -57,7 +56,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)
57 int onlink; 56 int onlink;
58 57
59 onlink = 0; 58 onlink = 0;
60 read_lock(&addrconf_lock); 59 rcu_read_lock();
61 idev = __in6_dev_get(dev); 60 idev = __in6_dev_get(dev);
62 if (idev) { 61 if (idev) {
63 read_lock_bh(&idev->lock); 62 read_lock_bh(&idev->lock);
@@ -69,7 +68,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)
69 } 68 }
70 read_unlock_bh(&idev->lock); 69 read_unlock_bh(&idev->lock);
71 } 70 }
72 read_unlock(&addrconf_lock); 71 rcu_read_unlock();
73 return onlink; 72 return onlink;
74} 73}
75 74
@@ -336,7 +335,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
336 write_unlock_bh(&idev->lock); 335 write_unlock_bh(&idev->lock);
337 336
338 dst_hold(&rt->u.dst); 337 dst_hold(&rt->u.dst);
339 if (ip6_ins_rt(rt, NULL, NULL, NULL)) 338 if (ip6_ins_rt(rt))
340 dst_release(&rt->u.dst); 339 dst_release(&rt->u.dst);
341 340
342 addrconf_join_solict(dev, &aca->aca_addr); 341 addrconf_join_solict(dev, &aca->aca_addr);
@@ -379,7 +378,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr)
379 addrconf_leave_solict(idev, &aca->aca_addr); 378 addrconf_leave_solict(idev, &aca->aca_addr);
380 379
381 dst_hold(&aca->aca_rt->u.dst); 380 dst_hold(&aca->aca_rt->u.dst);
382 if (ip6_del_rt(aca->aca_rt, NULL, NULL, NULL)) 381 if (ip6_del_rt(aca->aca_rt))
383 dst_free(&aca->aca_rt->u.dst); 382 dst_free(&aca->aca_rt->u.dst);
384 else 383 else
385 dst_release(&aca->aca_rt->u.dst); 384 dst_release(&aca->aca_rt->u.dst);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 99a6eb23378b..7206747022fc 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -156,6 +156,8 @@ ipv4_connected:
156 if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST)) 156 if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST))
157 fl.oif = np->mcast_oif; 157 fl.oif = np->mcast_oif;
158 158
159 security_sk_classify_flow(sk, &fl);
160
159 if (flowlabel) { 161 if (flowlabel) {
160 if (flowlabel->opt && flowlabel->opt->srcrt) { 162 if (flowlabel->opt && flowlabel->opt->srcrt) {
161 struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt; 163 struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
@@ -191,7 +193,12 @@ ipv4_connected:
191 193
192 ip6_dst_store(sk, dst, 194 ip6_dst_store(sk, dst,
193 ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? 195 ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
194 &np->daddr : NULL); 196 &np->daddr : NULL,
197#ifdef CONFIG_IPV6_SUBTREES
198 ipv6_addr_equal(&fl.fl6_src, &np->saddr) ?
199 &np->saddr :
200#endif
201 NULL);
195 202
196 sk->sk_state = TCP_ESTABLISHED; 203 sk->sk_state = TCP_ESTABLISHED;
197out: 204out:
@@ -641,10 +648,13 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
641 648
642 rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); 649 rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
643 650
644 /* 651 switch (rthdr->type) {
645 * TYPE 0 652 case IPV6_SRCRT_TYPE_0:
646 */ 653#ifdef CONFIG_IPV6_MIP6
647 if (rthdr->type) { 654 case IPV6_SRCRT_TYPE_2:
655#endif
656 break;
657 default:
648 err = -EINVAL; 658 err = -EINVAL;
649 goto exit_f; 659 goto exit_f;
650 } 660 }
@@ -696,7 +706,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
696 } 706 }
697 707
698 tc = *(int *)CMSG_DATA(cmsg); 708 tc = *(int *)CMSG_DATA(cmsg);
699 if (tc < 0 || tc > 0xff) 709 if (tc < -1 || tc > 0xff)
700 goto exit_f; 710 goto exit_f;
701 711
702 err = 0; 712 err = 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index a15a6f320f70..e78680a9985b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -24,7 +24,7 @@
24 * This file is derived from net/ipv4/esp.c 24 * This file is derived from net/ipv4/esp.c
25 */ 25 */
26 26
27#include <linux/config.h> 27#include <linux/err.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <net/ip.h> 29#include <net/ip.h>
30#include <net/xfrm.h> 30#include <net/xfrm.h>
@@ -45,7 +45,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
45 int hdr_len; 45 int hdr_len;
46 struct ipv6hdr *top_iph; 46 struct ipv6hdr *top_iph;
47 struct ipv6_esp_hdr *esph; 47 struct ipv6_esp_hdr *esph;
48 struct crypto_tfm *tfm; 48 struct crypto_blkcipher *tfm;
49 struct blkcipher_desc desc;
49 struct esp_data *esp; 50 struct esp_data *esp;
50 struct sk_buff *trailer; 51 struct sk_buff *trailer;
51 int blksize; 52 int blksize;
@@ -68,7 +69,9 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
68 69
69 alen = esp->auth.icv_trunc_len; 70 alen = esp->auth.icv_trunc_len;
70 tfm = esp->conf.tfm; 71 tfm = esp->conf.tfm;
71 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4); 72 desc.tfm = tfm;
73 desc.flags = 0;
74 blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
72 clen = ALIGN(clen + 2, blksize); 75 clen = ALIGN(clen + 2, blksize);
73 if (esp->conf.padlen) 76 if (esp->conf.padlen)
74 clen = ALIGN(clen, esp->conf.padlen); 77 clen = ALIGN(clen, esp->conf.padlen);
@@ -96,8 +99,13 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
96 esph->seq_no = htonl(++x->replay.oseq); 99 esph->seq_no = htonl(++x->replay.oseq);
97 xfrm_aevent_doreplay(x); 100 xfrm_aevent_doreplay(x);
98 101
99 if (esp->conf.ivlen) 102 if (esp->conf.ivlen) {
100 crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 103 if (unlikely(!esp->conf.ivinitted)) {
104 get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
105 esp->conf.ivinitted = 1;
106 }
107 crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
108 }
101 109
102 do { 110 do {
103 struct scatterlist *sg = &esp->sgbuf[0]; 111 struct scatterlist *sg = &esp->sgbuf[0];
@@ -108,24 +116,25 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
108 goto error; 116 goto error;
109 } 117 }
110 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); 118 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
111 crypto_cipher_encrypt(tfm, sg, sg, clen); 119 err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
112 if (unlikely(sg != &esp->sgbuf[0])) 120 if (unlikely(sg != &esp->sgbuf[0]))
113 kfree(sg); 121 kfree(sg);
114 } while (0); 122 } while (0);
115 123
124 if (unlikely(err))
125 goto error;
126
116 if (esp->conf.ivlen) { 127 if (esp->conf.ivlen) {
117 memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 128 memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
118 crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 129 crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
119 } 130 }
120 131
121 if (esp->auth.icv_full_len) { 132 if (esp->auth.icv_full_len) {
122 esp->auth.icv(esp, skb, (u8*)esph-skb->data, 133 err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data,
123 sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail); 134 sizeof(*esph) + esp->conf.ivlen + clen);
124 pskb_put(skb, trailer, alen); 135 memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen);
125 } 136 }
126 137
127 err = 0;
128
129error: 138error:
130 return err; 139 return err;
131} 140}
@@ -135,8 +144,10 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
135 struct ipv6hdr *iph; 144 struct ipv6hdr *iph;
136 struct ipv6_esp_hdr *esph; 145 struct ipv6_esp_hdr *esph;
137 struct esp_data *esp = x->data; 146 struct esp_data *esp = x->data;
147 struct crypto_blkcipher *tfm = esp->conf.tfm;
148 struct blkcipher_desc desc = { .tfm = tfm };
138 struct sk_buff *trailer; 149 struct sk_buff *trailer;
139 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 150 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
140 int alen = esp->auth.icv_trunc_len; 151 int alen = esp->auth.icv_trunc_len;
141 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; 152 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen;
142 153
@@ -156,15 +167,16 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
156 167
157 /* If integrity check is required, do this. */ 168 /* If integrity check is required, do this. */
158 if (esp->auth.icv_full_len) { 169 if (esp->auth.icv_full_len) {
159 u8 sum[esp->auth.icv_full_len]; 170 u8 sum[alen];
160 u8 sum1[alen];
161 171
162 esp->auth.icv(esp, skb, 0, skb->len-alen, sum); 172 ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
173 if (ret)
174 goto out;
163 175
164 if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) 176 if (skb_copy_bits(skb, skb->len - alen, sum, alen))
165 BUG(); 177 BUG();
166 178
167 if (unlikely(memcmp(sum, sum1, alen))) { 179 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
168 x->stats.integrity_failed++; 180 x->stats.integrity_failed++;
169 ret = -EINVAL; 181 ret = -EINVAL;
170 goto out; 182 goto out;
@@ -183,7 +195,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
183 195
184 /* Get ivec. This can be wrong, check against another impls. */ 196 /* Get ivec. This can be wrong, check against another impls. */
185 if (esp->conf.ivlen) 197 if (esp->conf.ivlen)
186 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); 198 crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
187 199
188 { 200 {
189 u8 nexthdr[2]; 201 u8 nexthdr[2];
@@ -198,9 +210,11 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
198 } 210 }
199 } 211 }
200 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); 212 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen);
201 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); 213 ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
202 if (unlikely(sg != &esp->sgbuf[0])) 214 if (unlikely(sg != &esp->sgbuf[0]))
203 kfree(sg); 215 kfree(sg);
216 if (unlikely(ret))
217 goto out;
204 218
205 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) 219 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
206 BUG(); 220 BUG();
@@ -226,9 +240,9 @@ out:
226static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) 240static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
227{ 241{
228 struct esp_data *esp = x->data; 242 struct esp_data *esp = x->data;
229 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 243 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
230 244
231 if (x->props.mode) { 245 if (x->props.mode == XFRM_MODE_TUNNEL) {
232 mtu = ALIGN(mtu + 2, blksize); 246 mtu = ALIGN(mtu + 2, blksize);
233 } else { 247 } else {
234 /* The worst case. */ 248 /* The worst case. */
@@ -267,11 +281,11 @@ static void esp6_destroy(struct xfrm_state *x)
267 if (!esp) 281 if (!esp)
268 return; 282 return;
269 283
270 crypto_free_tfm(esp->conf.tfm); 284 crypto_free_blkcipher(esp->conf.tfm);
271 esp->conf.tfm = NULL; 285 esp->conf.tfm = NULL;
272 kfree(esp->conf.ivec); 286 kfree(esp->conf.ivec);
273 esp->conf.ivec = NULL; 287 esp->conf.ivec = NULL;
274 crypto_free_tfm(esp->auth.tfm); 288 crypto_free_hash(esp->auth.tfm);
275 esp->auth.tfm = NULL; 289 esp->auth.tfm = NULL;
276 kfree(esp->auth.work_icv); 290 kfree(esp->auth.work_icv);
277 esp->auth.work_icv = NULL; 291 esp->auth.work_icv = NULL;
@@ -281,6 +295,7 @@ static void esp6_destroy(struct xfrm_state *x)
281static int esp6_init_state(struct xfrm_state *x) 295static int esp6_init_state(struct xfrm_state *x)
282{ 296{
283 struct esp_data *esp = NULL; 297 struct esp_data *esp = NULL;
298 struct crypto_blkcipher *tfm;
284 299
285 /* null auth and encryption can have zero length keys */ 300 /* null auth and encryption can have zero length keys */
286 if (x->aalg) { 301 if (x->aalg) {
@@ -299,24 +314,29 @@ static int esp6_init_state(struct xfrm_state *x)
299 314
300 if (x->aalg) { 315 if (x->aalg) {
301 struct xfrm_algo_desc *aalg_desc; 316 struct xfrm_algo_desc *aalg_desc;
317 struct crypto_hash *hash;
302 318
303 esp->auth.key = x->aalg->alg_key; 319 esp->auth.key = x->aalg->alg_key;
304 esp->auth.key_len = (x->aalg->alg_key_len+7)/8; 320 esp->auth.key_len = (x->aalg->alg_key_len+7)/8;
305 esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); 321 hash = crypto_alloc_hash(x->aalg->alg_name, 0,
306 if (esp->auth.tfm == NULL) 322 CRYPTO_ALG_ASYNC);
323 if (IS_ERR(hash))
324 goto error;
325
326 esp->auth.tfm = hash;
327 if (crypto_hash_setkey(hash, esp->auth.key, esp->auth.key_len))
307 goto error; 328 goto error;
308 esp->auth.icv = esp_hmac_digest;
309 329
310 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 330 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
311 BUG_ON(!aalg_desc); 331 BUG_ON(!aalg_desc);
312 332
313 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 333 if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
314 crypto_tfm_alg_digestsize(esp->auth.tfm)) { 334 crypto_hash_digestsize(hash)) {
315 printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", 335 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n",
316 x->aalg->alg_name, 336 x->aalg->alg_name,
317 crypto_tfm_alg_digestsize(esp->auth.tfm), 337 crypto_hash_digestsize(hash),
318 aalg_desc->uinfo.auth.icv_fullbits/8); 338 aalg_desc->uinfo.auth.icv_fullbits/8);
319 goto error; 339 goto error;
320 } 340 }
321 341
322 esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 342 esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;
@@ -328,24 +348,22 @@ static int esp6_init_state(struct xfrm_state *x)
328 } 348 }
329 esp->conf.key = x->ealg->alg_key; 349 esp->conf.key = x->ealg->alg_key;
330 esp->conf.key_len = (x->ealg->alg_key_len+7)/8; 350 esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
331 if (x->props.ealgo == SADB_EALG_NULL) 351 tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
332 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); 352 if (IS_ERR(tfm))
333 else
334 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
335 if (esp->conf.tfm == NULL)
336 goto error; 353 goto error;
337 esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); 354 esp->conf.tfm = tfm;
355 esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
338 esp->conf.padlen = 0; 356 esp->conf.padlen = 0;
339 if (esp->conf.ivlen) { 357 if (esp->conf.ivlen) {
340 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 358 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
341 if (unlikely(esp->conf.ivec == NULL)) 359 if (unlikely(esp->conf.ivec == NULL))
342 goto error; 360 goto error;
343 get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 361 esp->conf.ivinitted = 0;
344 } 362 }
345 if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) 363 if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len))
346 goto error; 364 goto error;
347 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; 365 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
348 if (x->props.mode) 366 if (x->props.mode == XFRM_MODE_TUNNEL)
349 x->props.header_len += sizeof(struct ipv6hdr); 367 x->props.header_len += sizeof(struct ipv6hdr);
350 x->data = esp; 368 x->data = esp;
351 return 0; 369 return 0;
@@ -366,7 +384,8 @@ static struct xfrm_type esp6_type =
366 .destructor = esp6_destroy, 384 .destructor = esp6_destroy,
367 .get_max_size = esp6_get_max_size, 385 .get_max_size = esp6_get_max_size,
368 .input = esp6_input, 386 .input = esp6_input,
369 .output = esp6_output 387 .output = esp6_output,
388 .hdr_offset = xfrm6_find_1stfragopt,
370}; 389};
371 390
372static struct inet6_protocol esp6_protocol = { 391static struct inet6_protocol esp6_protocol = {
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index a18d4256372c..88c96b10684c 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -43,9 +43,54 @@
43#include <net/ndisc.h> 43#include <net/ndisc.h>
44#include <net/ip6_route.h> 44#include <net/ip6_route.h>
45#include <net/addrconf.h> 45#include <net/addrconf.h>
46#ifdef CONFIG_IPV6_MIP6
47#include <net/xfrm.h>
48#endif
46 49
47#include <asm/uaccess.h> 50#include <asm/uaccess.h>
48 51
52int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
53{
54 int packet_len = skb->tail - skb->nh.raw;
55 struct ipv6_opt_hdr *hdr;
56 int len;
57
58 if (offset + 2 > packet_len)
59 goto bad;
60 hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
61 len = ((hdr->hdrlen + 1) << 3);
62
63 if (offset + len > packet_len)
64 goto bad;
65
66 offset += 2;
67 len -= 2;
68
69 while (len > 0) {
70 int opttype = skb->nh.raw[offset];
71 int optlen;
72
73 if (opttype == type)
74 return offset;
75
76 switch (opttype) {
77 case IPV6_TLV_PAD0:
78 optlen = 1;
79 break;
80 default:
81 optlen = skb->nh.raw[offset + 1] + 2;
82 if (optlen > len)
83 goto bad;
84 break;
85 }
86 offset += optlen;
87 len -= optlen;
88 }
89 /* not_found */
90 bad:
91 return -1;
92}
93
49/* 94/*
50 * Parsing tlv encoded headers. 95 * Parsing tlv encoded headers.
51 * 96 *
@@ -56,7 +101,7 @@
56 101
57struct tlvtype_proc { 102struct tlvtype_proc {
58 int type; 103 int type;
59 int (*func)(struct sk_buff *skb, int offset); 104 int (*func)(struct sk_buff **skbp, int offset);
60}; 105};
61 106
62/********************* 107/*********************
@@ -65,8 +110,10 @@ struct tlvtype_proc {
65 110
66/* An unknown option is detected, decide what to do */ 111/* An unknown option is detected, decide what to do */
67 112
68static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) 113static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
69{ 114{
115 struct sk_buff *skb = *skbp;
116
70 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) { 117 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
71 case 0: /* ignore */ 118 case 0: /* ignore */
72 return 1; 119 return 1;
@@ -91,8 +138,9 @@ static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff)
91 138
92/* Parse tlv encoded option header (hop-by-hop or destination) */ 139/* Parse tlv encoded option header (hop-by-hop or destination) */
93 140
94static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb) 141static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
95{ 142{
143 struct sk_buff *skb = *skbp;
96 struct tlvtype_proc *curr; 144 struct tlvtype_proc *curr;
97 int off = skb->h.raw - skb->nh.raw; 145 int off = skb->h.raw - skb->nh.raw;
98 int len = ((skb->h.raw[1]+1)<<3); 146 int len = ((skb->h.raw[1]+1)<<3);
@@ -122,13 +170,13 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb)
122 /* type specific length/alignment 170 /* type specific length/alignment
123 checks will be performed in the 171 checks will be performed in the
124 func(). */ 172 func(). */
125 if (curr->func(skb, off) == 0) 173 if (curr->func(skbp, off) == 0)
126 return 0; 174 return 0;
127 break; 175 break;
128 } 176 }
129 } 177 }
130 if (curr->type < 0) { 178 if (curr->type < 0) {
131 if (ip6_tlvopt_unknown(skb, off) == 0) 179 if (ip6_tlvopt_unknown(skbp, off) == 0)
132 return 0; 180 return 0;
133 } 181 }
134 break; 182 break;
@@ -147,8 +195,85 @@ bad:
147 Destination options header. 195 Destination options header.
148 *****************************/ 196 *****************************/
149 197
198#ifdef CONFIG_IPV6_MIP6
199static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
200{
201 struct sk_buff *skb = *skbp;
202 struct ipv6_destopt_hao *hao;
203 struct inet6_skb_parm *opt = IP6CB(skb);
204 struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb->nh.raw;
205 struct in6_addr tmp_addr;
206 int ret;
207
208 if (opt->dsthao) {
209 LIMIT_NETDEBUG(KERN_DEBUG "hao duplicated\n");
210 goto discard;
211 }
212 opt->dsthao = opt->dst1;
213 opt->dst1 = 0;
214
215 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + optoff);
216
217 if (hao->length != 16) {
218 LIMIT_NETDEBUG(
219 KERN_DEBUG "hao invalid option length = %d\n", hao->length);
220 goto discard;
221 }
222
223 if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
224 LIMIT_NETDEBUG(
225 KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr));
226 goto discard;
227 }
228
229 ret = xfrm6_input_addr(skb, (xfrm_address_t *)&ipv6h->daddr,
230 (xfrm_address_t *)&hao->addr, IPPROTO_DSTOPTS);
231 if (unlikely(ret < 0))
232 goto discard;
233
234 if (skb_cloned(skb)) {
235 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
236 struct inet6_skb_parm *opt2;
237
238 if (skb2 == NULL)
239 goto discard;
240
241 opt2 = IP6CB(skb2);
242 memcpy(opt2, opt, sizeof(*opt2));
243
244 kfree_skb(skb);
245
246 /* update all variable using below by copied skbuff */
247 *skbp = skb = skb2;
248 hao = (struct ipv6_destopt_hao *)(skb2->nh.raw + optoff);
249 ipv6h = (struct ipv6hdr *)skb2->nh.raw;
250 }
251
252 if (skb->ip_summed == CHECKSUM_COMPLETE)
253 skb->ip_summed = CHECKSUM_NONE;
254
255 ipv6_addr_copy(&tmp_addr, &ipv6h->saddr);
256 ipv6_addr_copy(&ipv6h->saddr, &hao->addr);
257 ipv6_addr_copy(&hao->addr, &tmp_addr);
258
259 if (skb->tstamp.off_sec == 0)
260 __net_timestamp(skb);
261
262 return 1;
263
264 discard:
265 kfree_skb(skb);
266 return 0;
267}
268#endif
269
150static struct tlvtype_proc tlvprocdestopt_lst[] = { 270static struct tlvtype_proc tlvprocdestopt_lst[] = {
151 /* No destination options are defined now */ 271#ifdef CONFIG_IPV6_MIP6
272 {
273 .type = IPV6_TLV_HAO,
274 .func = ipv6_dest_hao,
275 },
276#endif
152 {-1, NULL} 277 {-1, NULL}
153}; 278};
154 279
@@ -156,6 +281,9 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
156{ 281{
157 struct sk_buff *skb = *skbp; 282 struct sk_buff *skb = *skbp;
158 struct inet6_skb_parm *opt = IP6CB(skb); 283 struct inet6_skb_parm *opt = IP6CB(skb);
284#ifdef CONFIG_IPV6_MIP6
285 __u16 dstbuf;
286#endif
159 287
160 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 288 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
161 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 289 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
@@ -166,10 +294,19 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
166 294
167 opt->lastopt = skb->h.raw - skb->nh.raw; 295 opt->lastopt = skb->h.raw - skb->nh.raw;
168 opt->dst1 = skb->h.raw - skb->nh.raw; 296 opt->dst1 = skb->h.raw - skb->nh.raw;
297#ifdef CONFIG_IPV6_MIP6
298 dstbuf = opt->dst1;
299#endif
169 300
170 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { 301 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
302 skb = *skbp;
171 skb->h.raw += ((skb->h.raw[1]+1)<<3); 303 skb->h.raw += ((skb->h.raw[1]+1)<<3);
304 opt = IP6CB(skb);
305#ifdef CONFIG_IPV6_MIP6
306 opt->nhoff = dstbuf;
307#else
172 opt->nhoff = opt->dst1; 308 opt->nhoff = opt->dst1;
309#endif
173 return 1; 310 return 1;
174 } 311 }
175 312
@@ -179,7 +316,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
179 316
180static struct inet6_protocol destopt_protocol = { 317static struct inet6_protocol destopt_protocol = {
181 .handler = ipv6_destopt_rcv, 318 .handler = ipv6_destopt_rcv,
182 .flags = INET6_PROTO_NOPOLICY, 319 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
183}; 320};
184 321
185void __init ipv6_destopt_init(void) 322void __init ipv6_destopt_init(void)
@@ -219,7 +356,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
219{ 356{
220 struct sk_buff *skb = *skbp; 357 struct sk_buff *skb = *skbp;
221 struct inet6_skb_parm *opt = IP6CB(skb); 358 struct inet6_skb_parm *opt = IP6CB(skb);
222 struct in6_addr *addr; 359 struct in6_addr *addr = NULL;
223 struct in6_addr daddr; 360 struct in6_addr daddr;
224 int n, i; 361 int n, i;
225 362
@@ -244,6 +381,23 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
244 381
245looped_back: 382looped_back:
246 if (hdr->segments_left == 0) { 383 if (hdr->segments_left == 0) {
384 switch (hdr->type) {
385#ifdef CONFIG_IPV6_MIP6
386 case IPV6_SRCRT_TYPE_2:
387 /* Silently discard type 2 header unless it was
388 * processed by own
389 */
390 if (!addr) {
391 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
392 kfree_skb(skb);
393 return -1;
394 }
395 break;
396#endif
397 default:
398 break;
399 }
400
247 opt->lastopt = skb->h.raw - skb->nh.raw; 401 opt->lastopt = skb->h.raw - skb->nh.raw;
248 opt->srcrt = skb->h.raw - skb->nh.raw; 402 opt->srcrt = skb->h.raw - skb->nh.raw;
249 skb->h.raw += (hdr->hdrlen + 1) << 3; 403 skb->h.raw += (hdr->hdrlen + 1) << 3;
@@ -253,17 +407,29 @@ looped_back:
253 return 1; 407 return 1;
254 } 408 }
255 409
256 if (hdr->type != IPV6_SRCRT_TYPE_0) { 410 switch (hdr->type) {
411 case IPV6_SRCRT_TYPE_0:
412 if (hdr->hdrlen & 0x01) {
413 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
414 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
415 return -1;
416 }
417 break;
418#ifdef CONFIG_IPV6_MIP6
419 case IPV6_SRCRT_TYPE_2:
420 /* Silently discard invalid RTH type 2 */
421 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
422 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
423 kfree_skb(skb);
424 return -1;
425 }
426 break;
427#endif
428 default:
257 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 429 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
258 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); 430 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
259 return -1; 431 return -1;
260 } 432 }
261
262 if (hdr->hdrlen & 0x01) {
263 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
264 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
265 return -1;
266 }
267 433
268 /* 434 /*
269 * This is the routing header forwarding algorithm from 435 * This is the routing header forwarding algorithm from
@@ -294,7 +460,7 @@ looped_back:
294 hdr = (struct ipv6_rt_hdr *) skb2->h.raw; 460 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
295 } 461 }
296 462
297 if (skb->ip_summed == CHECKSUM_HW) 463 if (skb->ip_summed == CHECKSUM_COMPLETE)
298 skb->ip_summed = CHECKSUM_NONE; 464 skb->ip_summed = CHECKSUM_NONE;
299 465
300 i = n - --hdr->segments_left; 466 i = n - --hdr->segments_left;
@@ -303,6 +469,27 @@ looped_back:
303 addr = rthdr->addr; 469 addr = rthdr->addr;
304 addr += i - 1; 470 addr += i - 1;
305 471
472 switch (hdr->type) {
473#ifdef CONFIG_IPV6_MIP6
474 case IPV6_SRCRT_TYPE_2:
475 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
476 (xfrm_address_t *)&skb->nh.ipv6h->saddr,
477 IPPROTO_ROUTING) < 0) {
478 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
479 kfree_skb(skb);
480 return -1;
481 }
482 if (!ipv6_chk_home_addr(addr)) {
483 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
484 kfree_skb(skb);
485 return -1;
486 }
487 break;
488#endif
489 default:
490 break;
491 }
492
306 if (ipv6_addr_is_multicast(addr)) { 493 if (ipv6_addr_is_multicast(addr)) {
307 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 494 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
308 kfree_skb(skb); 495 kfree_skb(skb);
@@ -340,7 +527,7 @@ looped_back:
340 527
341static struct inet6_protocol rthdr_protocol = { 528static struct inet6_protocol rthdr_protocol = {
342 .handler = ipv6_rthdr_rcv, 529 .handler = ipv6_rthdr_rcv,
343 .flags = INET6_PROTO_NOPOLICY, 530 .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
344}; 531};
345 532
346void __init ipv6_rthdr_init(void) 533void __init ipv6_rthdr_init(void)
@@ -421,8 +608,10 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
421 608
422/* Router Alert as of RFC 2711 */ 609/* Router Alert as of RFC 2711 */
423 610
424static int ipv6_hop_ra(struct sk_buff *skb, int optoff) 611static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
425{ 612{
613 struct sk_buff *skb = *skbp;
614
426 if (skb->nh.raw[optoff+1] == 2) { 615 if (skb->nh.raw[optoff+1] == 2) {
427 IP6CB(skb)->ra = optoff; 616 IP6CB(skb)->ra = optoff;
428 return 1; 617 return 1;
@@ -435,8 +624,9 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
435 624
436/* Jumbo payload */ 625/* Jumbo payload */
437 626
438static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) 627static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
439{ 628{
629 struct sk_buff *skb = *skbp;
440 u32 pkt_len; 630 u32 pkt_len;
441 631
442 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { 632 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
@@ -485,8 +675,9 @@ static struct tlvtype_proc tlvprochopopt_lst[] = {
485 { -1, } 675 { -1, }
486}; 676};
487 677
488int ipv6_parse_hopopts(struct sk_buff *skb) 678int ipv6_parse_hopopts(struct sk_buff **skbp)
489{ 679{
680 struct sk_buff *skb = *skbp;
490 struct inet6_skb_parm *opt = IP6CB(skb); 681 struct inet6_skb_parm *opt = IP6CB(skb);
491 682
492 /* 683 /*
@@ -502,8 +693,10 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
502 } 693 }
503 694
504 opt->hop = sizeof(struct ipv6hdr); 695 opt->hop = sizeof(struct ipv6hdr);
505 if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { 696 if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
697 skb = *skbp;
506 skb->h.raw += (skb->h.raw[1]+1)<<3; 698 skb->h.raw += (skb->h.raw[1]+1)<<3;
699 opt = IP6CB(skb);
507 opt->nhoff = sizeof(struct ipv6hdr); 700 opt->nhoff = sizeof(struct ipv6hdr);
508 return 1; 701 return 1;
509 } 702 }
@@ -635,14 +828,17 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
635 struct ipv6_txoptions *opt2; 828 struct ipv6_txoptions *opt2;
636 int err; 829 int err;
637 830
638 if (newtype != IPV6_HOPOPTS && opt->hopopt) 831 if (opt) {
639 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt)); 832 if (newtype != IPV6_HOPOPTS && opt->hopopt)
640 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt) 833 tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
641 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt)); 834 if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
642 if (newtype != IPV6_RTHDR && opt->srcrt) 835 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
643 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt)); 836 if (newtype != IPV6_RTHDR && opt->srcrt)
644 if (newtype != IPV6_DSTOPTS && opt->dst1opt) 837 tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
645 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt)); 838 if (newtype != IPV6_DSTOPTS && opt->dst1opt)
839 tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
840 }
841
646 if (newopt && newoptlen) 842 if (newopt && newoptlen)
647 tot_len += CMSG_ALIGN(newoptlen); 843 tot_len += CMSG_ALIGN(newoptlen);
648 844
@@ -659,25 +855,25 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
659 opt2->tot_len = tot_len; 855 opt2->tot_len = tot_len;
660 p = (char *)(opt2 + 1); 856 p = (char *)(opt2 + 1);
661 857
662 err = ipv6_renew_option(opt->hopopt, newopt, newoptlen, 858 err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
663 newtype != IPV6_HOPOPTS, 859 newtype != IPV6_HOPOPTS,
664 &opt2->hopopt, &p); 860 &opt2->hopopt, &p);
665 if (err) 861 if (err)
666 goto out; 862 goto out;
667 863
668 err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen, 864 err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
669 newtype != IPV6_RTHDRDSTOPTS, 865 newtype != IPV6_RTHDRDSTOPTS,
670 &opt2->dst0opt, &p); 866 &opt2->dst0opt, &p);
671 if (err) 867 if (err)
672 goto out; 868 goto out;
673 869
674 err = ipv6_renew_option(opt->srcrt, newopt, newoptlen, 870 err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
675 newtype != IPV6_RTHDR, 871 newtype != IPV6_RTHDR,
676 (struct ipv6_opt_hdr **)opt2->srcrt, &p); 872 (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
677 if (err) 873 if (err)
678 goto out; 874 goto out;
679 875
680 err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen, 876 err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
681 newtype != IPV6_DSTOPTS, 877 newtype != IPV6_DSTOPTS,
682 &opt2->dst1opt, &p); 878 &opt2->dst1opt, &p);
683 if (err) 879 if (err)
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
new file mode 100644
index 000000000000..34f5bfaddfc2
--- /dev/null
+++ b/net/ipv6/fib6_rules.c
@@ -0,0 +1,305 @@
1/*
2 * net/ipv6/fib6_rules.c IPv6 Routing Policy Rules
3 *
4 * Copyright (C)2003-2006 Helsinki University of Technology
5 * Copyright (C)2003-2006 USAGI/WIDE Project
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
10 *
11 * Authors
12 * Thomas Graf <tgraf@suug.ch>
13 * Ville Nuorvala <vnuorval@tcs.hut.fi>
14 */
15
16#include <linux/config.h>
17#include <linux/netdevice.h>
18
19#include <net/fib_rules.h>
20#include <net/ipv6.h>
21#include <net/ip6_route.h>
22#include <net/netlink.h>
23
24struct fib6_rule
25{
26 struct fib_rule common;
27 struct rt6key src;
28 struct rt6key dst;
29#ifdef CONFIG_IPV6_ROUTE_FWMARK
30 u32 fwmark;
31 u32 fwmask;
32#endif
33 u8 tclass;
34};
35
36static struct fib_rules_ops fib6_rules_ops;
37
38static struct fib6_rule main_rule = {
39 .common = {
40 .refcnt = ATOMIC_INIT(2),
41 .pref = 0x7FFE,
42 .action = FR_ACT_TO_TBL,
43 .table = RT6_TABLE_MAIN,
44 },
45};
46
47static struct fib6_rule local_rule = {
48 .common = {
49 .refcnt = ATOMIC_INIT(2),
50 .pref = 0,
51 .action = FR_ACT_TO_TBL,
52 .table = RT6_TABLE_LOCAL,
53 .flags = FIB_RULE_PERMANENT,
54 },
55};
56
57static LIST_HEAD(fib6_rules);
58
59struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
60 pol_lookup_t lookup)
61{
62 struct fib_lookup_arg arg = {
63 .lookup_ptr = lookup,
64 };
65
66 fib_rules_lookup(&fib6_rules_ops, fl, flags, &arg);
67 if (arg.rule)
68 fib_rule_put(arg.rule);
69
70 if (arg.result)
71 return (struct dst_entry *) arg.result;
72
73 dst_hold(&ip6_null_entry.u.dst);
74 return &ip6_null_entry.u.dst;
75}
76
77static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
78 int flags, struct fib_lookup_arg *arg)
79{
80 struct rt6_info *rt = NULL;
81 struct fib6_table *table;
82 pol_lookup_t lookup = arg->lookup_ptr;
83
84 switch (rule->action) {
85 case FR_ACT_TO_TBL:
86 break;
87 case FR_ACT_UNREACHABLE:
88 rt = &ip6_null_entry;
89 goto discard_pkt;
90 default:
91 case FR_ACT_BLACKHOLE:
92 rt = &ip6_blk_hole_entry;
93 goto discard_pkt;
94 case FR_ACT_PROHIBIT:
95 rt = &ip6_prohibit_entry;
96 goto discard_pkt;
97 }
98
99 table = fib6_get_table(rule->table);
100 if (table)
101 rt = lookup(table, flp, flags);
102
103 if (rt != &ip6_null_entry)
104 goto out;
105 dst_release(&rt->u.dst);
106 rt = NULL;
107 goto out;
108
109discard_pkt:
110 dst_hold(&rt->u.dst);
111out:
112 arg->result = rt;
113 return rt == NULL ? -EAGAIN : 0;
114}
115
116
117static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
118{
119 struct fib6_rule *r = (struct fib6_rule *) rule;
120
121 if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
122 return 0;
123
124 if ((flags & RT6_LOOKUP_F_HAS_SADDR) &&
125 !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
126 return 0;
127
128 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
129 return 0;
130
131#ifdef CONFIG_IPV6_ROUTE_FWMARK
132 if ((r->fwmark ^ fl->fl6_fwmark) & r->fwmask)
133 return 0;
134#endif
135
136 return 1;
137}
138
139static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
140 [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
141 [FRA_PRIORITY] = { .type = NLA_U32 },
142 [FRA_SRC] = { .len = sizeof(struct in6_addr) },
143 [FRA_DST] = { .len = sizeof(struct in6_addr) },
144 [FRA_FWMARK] = { .type = NLA_U32 },
145 [FRA_FWMASK] = { .type = NLA_U32 },
146 [FRA_TABLE] = { .type = NLA_U32 },
147};
148
149static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
150 struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
151 struct nlattr **tb)
152{
153 int err = -EINVAL;
154 struct fib6_rule *rule6 = (struct fib6_rule *) rule;
155
156 if (frh->src_len > 128 || frh->dst_len > 128 ||
157 (frh->tos & ~IPV6_FLOWINFO_MASK))
158 goto errout;
159
160 if (rule->action == FR_ACT_TO_TBL) {
161 if (rule->table == RT6_TABLE_UNSPEC)
162 goto errout;
163
164 if (fib6_new_table(rule->table) == NULL) {
165 err = -ENOBUFS;
166 goto errout;
167 }
168 }
169
170 if (tb[FRA_SRC])
171 nla_memcpy(&rule6->src.addr, tb[FRA_SRC],
172 sizeof(struct in6_addr));
173
174 if (tb[FRA_DST])
175 nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
176 sizeof(struct in6_addr));
177
178#ifdef CONFIG_IPV6_ROUTE_FWMARK
179 if (tb[FRA_FWMARK]) {
180 rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
181 if (rule6->fwmark) {
182 /*
183 * if the mark value is non-zero,
184 * all bits are compared by default
185 * unless a mask is explicitly specified.
186 */
187 rule6->fwmask = 0xFFFFFFFF;
188 }
189 }
190
191 if (tb[FRA_FWMASK])
192 rule6->fwmask = nla_get_u32(tb[FRA_FWMASK]);
193#endif
194
195 rule6->src.plen = frh->src_len;
196 rule6->dst.plen = frh->dst_len;
197 rule6->tclass = frh->tos;
198
199 err = 0;
200errout:
201 return err;
202}
203
204static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
205 struct nlattr **tb)
206{
207 struct fib6_rule *rule6 = (struct fib6_rule *) rule;
208
209 if (frh->src_len && (rule6->src.plen != frh->src_len))
210 return 0;
211
212 if (frh->dst_len && (rule6->dst.plen != frh->dst_len))
213 return 0;
214
215 if (frh->tos && (rule6->tclass != frh->tos))
216 return 0;
217
218 if (tb[FRA_SRC] &&
219 nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr)))
220 return 0;
221
222 if (tb[FRA_DST] &&
223 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
224 return 0;
225
226#ifdef CONFIG_IPV6_ROUTE_FWMARK
227 if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
228 return 0;
229
230 if (tb[FRA_FWMASK] && (rule6->fwmask != nla_get_u32(tb[FRA_FWMASK])))
231 return 0;
232#endif
233
234 return 1;
235}
236
237static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
238 struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
239{
240 struct fib6_rule *rule6 = (struct fib6_rule *) rule;
241
242 frh->family = AF_INET6;
243 frh->dst_len = rule6->dst.plen;
244 frh->src_len = rule6->src.plen;
245 frh->tos = rule6->tclass;
246
247 if (rule6->dst.plen)
248 NLA_PUT(skb, FRA_DST, sizeof(struct in6_addr),
249 &rule6->dst.addr);
250
251 if (rule6->src.plen)
252 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
253 &rule6->src.addr);
254
255#ifdef CONFIG_IPV6_ROUTE_FWMARK
256 if (rule6->fwmark)
257 NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);
258
259 if (rule6->fwmask || rule6->fwmark)
260 NLA_PUT_U32(skb, FRA_FWMASK, rule6->fwmask);
261#endif
262
263 return 0;
264
265nla_put_failure:
266 return -ENOBUFS;
267}
268
269int fib6_rules_dump(struct sk_buff *skb, struct netlink_callback *cb)
270{
271 return fib_rules_dump(skb, cb, AF_INET6);
272}
273
274static u32 fib6_rule_default_pref(void)
275{
276 return 0x3FFF;
277}
278
279static struct fib_rules_ops fib6_rules_ops = {
280 .family = AF_INET6,
281 .rule_size = sizeof(struct fib6_rule),
282 .action = fib6_rule_action,
283 .match = fib6_rule_match,
284 .configure = fib6_rule_configure,
285 .compare = fib6_rule_compare,
286 .fill = fib6_rule_fill,
287 .default_pref = fib6_rule_default_pref,
288 .nlgroup = RTNLGRP_IPV6_RULE,
289 .policy = fib6_rule_policy,
290 .rules_list = &fib6_rules,
291 .owner = THIS_MODULE,
292};
293
294void __init fib6_rules_init(void)
295{
296 list_add_tail(&local_rule.common.list, &fib6_rules);
297 list_add_tail(&main_rule.common.list, &fib6_rules);
298
299 fib_rules_register(&fib6_rules_ops);
300}
301
302void fib6_rules_cleanup(void)
303{
304 fib_rules_unregister(&fib6_rules_ops);
305}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 1044b6fce0d5..4ec876066b3f 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -151,7 +151,7 @@ static int is_ineligible(struct sk_buff *skb)
151 return 0; 151 return 0;
152} 152}
153 153
154static int sysctl_icmpv6_time = 1*HZ; 154static int sysctl_icmpv6_time __read_mostly = 1*HZ;
155 155
156/* 156/*
157 * Check the ICMP output rate limit 157 * Check the ICMP output rate limit
@@ -273,6 +273,29 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
273 return 0; 273 return 0;
274} 274}
275 275
276#ifdef CONFIG_IPV6_MIP6
277static void mip6_addr_swap(struct sk_buff *skb)
278{
279 struct ipv6hdr *iph = skb->nh.ipv6h;
280 struct inet6_skb_parm *opt = IP6CB(skb);
281 struct ipv6_destopt_hao *hao;
282 struct in6_addr tmp;
283 int off;
284
285 if (opt->dsthao) {
286 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
287 if (likely(off >= 0)) {
288 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + off);
289 ipv6_addr_copy(&tmp, &iph->saddr);
290 ipv6_addr_copy(&iph->saddr, &hao->addr);
291 ipv6_addr_copy(&hao->addr, &tmp);
292 }
293 }
294}
295#else
296static inline void mip6_addr_swap(struct sk_buff *skb) {}
297#endif
298
276/* 299/*
277 * Send an ICMP message in response to a packet in error 300 * Send an ICMP message in response to a packet in error
278 */ 301 */
@@ -350,6 +373,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
350 return; 373 return;
351 } 374 }
352 375
376 mip6_addr_swap(skb);
377
353 memset(&fl, 0, sizeof(fl)); 378 memset(&fl, 0, sizeof(fl));
354 fl.proto = IPPROTO_ICMPV6; 379 fl.proto = IPPROTO_ICMPV6;
355 ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr); 380 ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
@@ -358,6 +383,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
358 fl.oif = iif; 383 fl.oif = iif;
359 fl.fl_icmp_type = type; 384 fl.fl_icmp_type = type;
360 fl.fl_icmp_code = code; 385 fl.fl_icmp_code = code;
386 security_skb_classify_flow(skb, &fl);
361 387
362 if (icmpv6_xmit_lock()) 388 if (icmpv6_xmit_lock())
363 return; 389 return;
@@ -401,7 +427,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
401 if (hlimit < 0) 427 if (hlimit < 0)
402 hlimit = ipv6_get_hoplimit(dst->dev); 428 hlimit = ipv6_get_hoplimit(dst->dev);
403 429
404 tclass = np->cork.tclass; 430 tclass = np->tclass;
405 if (tclass < 0) 431 if (tclass < 0)
406 tclass = 0; 432 tclass = 0;
407 433
@@ -472,6 +498,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
472 ipv6_addr_copy(&fl.fl6_src, saddr); 498 ipv6_addr_copy(&fl.fl6_src, saddr);
473 fl.oif = skb->dev->ifindex; 499 fl.oif = skb->dev->ifindex;
474 fl.fl_icmp_type = ICMPV6_ECHO_REPLY; 500 fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
501 security_skb_classify_flow(skb, &fl);
475 502
476 if (icmpv6_xmit_lock()) 503 if (icmpv6_xmit_lock())
477 return; 504 return;
@@ -497,7 +524,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
497 if (hlimit < 0) 524 if (hlimit < 0)
498 hlimit = ipv6_get_hoplimit(dst->dev); 525 hlimit = ipv6_get_hoplimit(dst->dev);
499 526
500 tclass = np->cork.tclass; 527 tclass = np->tclass;
501 if (tclass < 0) 528 if (tclass < 0)
502 tclass = 0; 529 tclass = 0;
503 530
@@ -604,7 +631,7 @@ static int icmpv6_rcv(struct sk_buff **pskb)
604 631
605 /* Perform checksum. */ 632 /* Perform checksum. */
606 switch (skb->ip_summed) { 633 switch (skb->ip_summed) {
607 case CHECKSUM_HW: 634 case CHECKSUM_COMPLETE:
608 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 635 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
609 skb->csum)) 636 skb->csum))
610 break; 637 break;
@@ -712,6 +739,11 @@ discard_it:
712 return 0; 739 return 0;
713} 740}
714 741
742/*
743 * Special lock-class for __icmpv6_socket:
744 */
745static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
746
715int __init icmpv6_init(struct net_proto_family *ops) 747int __init icmpv6_init(struct net_proto_family *ops)
716{ 748{
717 struct sock *sk; 749 struct sock *sk;
@@ -730,6 +762,14 @@ int __init icmpv6_init(struct net_proto_family *ops)
730 762
731 sk = per_cpu(__icmpv6_socket, i)->sk; 763 sk = per_cpu(__icmpv6_socket, i)->sk;
732 sk->sk_allocation = GFP_ATOMIC; 764 sk->sk_allocation = GFP_ATOMIC;
765 /*
766 * Split off their lock-class, because sk->sk_dst_lock
767 * gets used from softirqs, which is safe for
768 * __icmpv6_socket (because those never get directly used
769 * via userspace syscalls), but unsafe for normal sockets.
770 */
771 lockdep_set_class(&sk->sk_dst_lock,
772 &icmpv6_socket_sk_dst_lock_key);
733 773
734 /* Enough space for 2 64K ICMP packets, including 774 /* Enough space for 2 64K ICMP packets, including
735 * sk_buff struct overhead. 775 * sk_buff struct overhead.
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index eb2865d5ae28..827f41d1478b 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -13,7 +13,6 @@
13 * 2 of the License, or(at your option) any later version. 13 * 2 of the License, or(at your option) any later version.
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/in6.h> 17#include <linux/in6.h>
19#include <linux/ipv6.h> 18#include <linux/ipv6.h>
@@ -158,6 +157,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
158 fl.oif = sk->sk_bound_dev_if; 157 fl.oif = sk->sk_bound_dev_if;
159 fl.fl_ip_sport = inet->sport; 158 fl.fl_ip_sport = inet->sport;
160 fl.fl_ip_dport = inet->dport; 159 fl.fl_ip_dport = inet->dport;
160 security_sk_classify_flow(sk, &fl);
161 161
162 if (np->opt && np->opt->srcrt) { 162 if (np->opt && np->opt->srcrt) {
163 struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; 163 struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
@@ -186,9 +186,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
186 return err; 186 return err;
187 } 187 }
188 188
189 ip6_dst_store(sk, dst, NULL); 189 __ip6_dst_store(sk, dst, NULL, NULL);
190 sk->sk_route_caps = dst->dev->features &
191 ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
192 } 190 }
193 191
194 skb->dst = dst_clone(dst); 192 skb->dst = dst_clone(dst);
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 2ae84c961678..8accd1fbeeda 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -14,7 +14,6 @@
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 */ 15 */
16 16
17#include <linux/config.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/random.h> 18#include <linux/random.h>
20 19
@@ -65,7 +64,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
65{ 64{
66 struct sock *sk; 65 struct sock *sk;
67 const struct hlist_node *node; 66 const struct hlist_node *node;
68 const __u32 ports = INET_COMBINED_PORTS(sport, hnum); 67 const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
69 /* Optimize here for direct hit, only listening connections can 68 /* Optimize here for direct hit, only listening connections can
70 * have wildcards anyways. 69 * have wildcards anyways.
71 */ 70 */
@@ -83,7 +82,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
83 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { 82 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
84 const struct inet_timewait_sock *tw = inet_twsk(sk); 83 const struct inet_timewait_sock *tw = inet_twsk(sk);
85 84
86 if(*((__u32 *)&(tw->tw_dport)) == ports && 85 if(*((__portpair *)&(tw->tw_dport)) == ports &&
87 sk->sk_family == PF_INET6) { 86 sk->sk_family == PF_INET6) {
88 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); 87 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
89 88
@@ -172,7 +171,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
172 const struct in6_addr *daddr = &np->rcv_saddr; 171 const struct in6_addr *daddr = &np->rcv_saddr;
173 const struct in6_addr *saddr = &np->daddr; 172 const struct in6_addr *saddr = &np->daddr;
174 const int dif = sk->sk_bound_dev_if; 173 const int dif = sk->sk_bound_dev_if;
175 const u32 ports = INET_COMBINED_PORTS(inet->dport, lport); 174 const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
176 const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, 175 const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
177 inet->dport); 176 inet->dport);
178 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); 177 struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
@@ -189,7 +188,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
189 188
190 tw = inet_twsk(sk2); 189 tw = inet_twsk(sk2);
191 190
192 if(*((__u32 *)&(tw->tw_dport)) == ports && 191 if(*((__portpair *)&(tw->tw_dport)) == ports &&
193 sk2->sk_family == PF_INET6 && 192 sk2->sk_family == PF_INET6 &&
194 ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && 193 ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
195 ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && 194 ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 2cb6149349bf..8fcae7a6510b 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -18,8 +18,8 @@
18 * Yuji SEKIYA @USAGI: Support default route on router node; 18 * Yuji SEKIYA @USAGI: Support default route on router node;
19 * remove ip6_null_entry from the top of 19 * remove ip6_null_entry from the top of
20 * routing table. 20 * routing table.
21 * Ville Nuorvala: Fixed routing subtrees.
21 */ 22 */
22#include <linux/config.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/net.h> 25#include <linux/net.h>
@@ -27,6 +27,7 @@
27#include <linux/netdevice.h> 27#include <linux/netdevice.h>
28#include <linux/in6.h> 28#include <linux/in6.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/list.h>
30 31
31#ifdef CONFIG_PROC_FS 32#ifdef CONFIG_PROC_FS
32#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
@@ -69,19 +70,19 @@ struct fib6_cleaner_t
69 void *arg; 70 void *arg;
70}; 71};
71 72
72DEFINE_RWLOCK(fib6_walker_lock); 73static DEFINE_RWLOCK(fib6_walker_lock);
73
74 74
75#ifdef CONFIG_IPV6_SUBTREES 75#ifdef CONFIG_IPV6_SUBTREES
76#define FWS_INIT FWS_S 76#define FWS_INIT FWS_S
77#define SUBTREE(fn) ((fn)->subtree)
78#else 77#else
79#define FWS_INIT FWS_L 78#define FWS_INIT FWS_L
80#define SUBTREE(fn) NULL
81#endif 79#endif
82 80
83static void fib6_prune_clones(struct fib6_node *fn, struct rt6_info *rt); 81static void fib6_prune_clones(struct fib6_node *fn, struct rt6_info *rt);
82static struct rt6_info * fib6_find_prefix(struct fib6_node *fn);
84static struct fib6_node * fib6_repair_tree(struct fib6_node *fn); 83static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
84static int fib6_walk(struct fib6_walker_t *w);
85static int fib6_walk_continue(struct fib6_walker_t *w);
85 86
86/* 87/*
87 * A routing update causes an increase of the serial number on the 88 * A routing update causes an increase of the serial number on the
@@ -94,13 +95,31 @@ static __u32 rt_sernum;
94 95
95static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0); 96static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0);
96 97
97struct fib6_walker_t fib6_walker_list = { 98static struct fib6_walker_t fib6_walker_list = {
98 .prev = &fib6_walker_list, 99 .prev = &fib6_walker_list,
99 .next = &fib6_walker_list, 100 .next = &fib6_walker_list,
100}; 101};
101 102
102#define FOR_WALKERS(w) for ((w)=fib6_walker_list.next; (w) != &fib6_walker_list; (w)=(w)->next) 103#define FOR_WALKERS(w) for ((w)=fib6_walker_list.next; (w) != &fib6_walker_list; (w)=(w)->next)
103 104
105static inline void fib6_walker_link(struct fib6_walker_t *w)
106{
107 write_lock_bh(&fib6_walker_lock);
108 w->next = fib6_walker_list.next;
109 w->prev = &fib6_walker_list;
110 w->next->prev = w;
111 w->prev->next = w;
112 write_unlock_bh(&fib6_walker_lock);
113}
114
115static inline void fib6_walker_unlink(struct fib6_walker_t *w)
116{
117 write_lock_bh(&fib6_walker_lock);
118 w->next->prev = w->prev;
119 w->prev->next = w->next;
120 w->prev = w->next = w;
121 write_unlock_bh(&fib6_walker_lock);
122}
104static __inline__ u32 fib6_new_sernum(void) 123static __inline__ u32 fib6_new_sernum(void)
105{ 124{
106 u32 n = ++rt_sernum; 125 u32 n = ++rt_sernum;
@@ -148,6 +167,253 @@ static __inline__ void rt6_release(struct rt6_info *rt)
148 dst_free(&rt->u.dst); 167 dst_free(&rt->u.dst);
149} 168}
150 169
170static struct fib6_table fib6_main_tbl = {
171 .tb6_id = RT6_TABLE_MAIN,
172 .tb6_lock = RW_LOCK_UNLOCKED,
173 .tb6_root = {
174 .leaf = &ip6_null_entry,
175 .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
176 },
177};
178
179#ifdef CONFIG_IPV6_MULTIPLE_TABLES
180#define FIB_TABLE_HASHSZ 256
181#else
182#define FIB_TABLE_HASHSZ 1
183#endif
184static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
185
186static void fib6_link_table(struct fib6_table *tb)
187{
188 unsigned int h;
189
190 h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1);
191
192 /*
193 * No protection necessary, this is the only list mutatation
194 * operation, tables never disappear once they exist.
195 */
196 hlist_add_head_rcu(&tb->tb6_hlist, &fib_table_hash[h]);
197}
198
199#ifdef CONFIG_IPV6_MULTIPLE_TABLES
200static struct fib6_table fib6_local_tbl = {
201 .tb6_id = RT6_TABLE_LOCAL,
202 .tb6_lock = RW_LOCK_UNLOCKED,
203 .tb6_root = {
204 .leaf = &ip6_null_entry,
205 .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
206 },
207};
208
209static struct fib6_table *fib6_alloc_table(u32 id)
210{
211 struct fib6_table *table;
212
213 table = kzalloc(sizeof(*table), GFP_ATOMIC);
214 if (table != NULL) {
215 table->tb6_id = id;
216 table->tb6_lock = RW_LOCK_UNLOCKED;
217 table->tb6_root.leaf = &ip6_null_entry;
218 table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
219 }
220
221 return table;
222}
223
224struct fib6_table *fib6_new_table(u32 id)
225{
226 struct fib6_table *tb;
227
228 if (id == 0)
229 id = RT6_TABLE_MAIN;
230 tb = fib6_get_table(id);
231 if (tb)
232 return tb;
233
234 tb = fib6_alloc_table(id);
235 if (tb != NULL)
236 fib6_link_table(tb);
237
238 return tb;
239}
240
241struct fib6_table *fib6_get_table(u32 id)
242{
243 struct fib6_table *tb;
244 struct hlist_node *node;
245 unsigned int h;
246
247 if (id == 0)
248 id = RT6_TABLE_MAIN;
249 h = id & (FIB_TABLE_HASHSZ - 1);
250 rcu_read_lock();
251 hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb6_hlist) {
252 if (tb->tb6_id == id) {
253 rcu_read_unlock();
254 return tb;
255 }
256 }
257 rcu_read_unlock();
258
259 return NULL;
260}
261
262static void __init fib6_tables_init(void)
263{
264 fib6_link_table(&fib6_main_tbl);
265 fib6_link_table(&fib6_local_tbl);
266}
267
268#else
269
270struct fib6_table *fib6_new_table(u32 id)
271{
272 return fib6_get_table(id);
273}
274
275struct fib6_table *fib6_get_table(u32 id)
276{
277 return &fib6_main_tbl;
278}
279
280struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
281 pol_lookup_t lookup)
282{
283 return (struct dst_entry *) lookup(&fib6_main_tbl, fl, flags);
284}
285
286static void __init fib6_tables_init(void)
287{
288 fib6_link_table(&fib6_main_tbl);
289}
290
291#endif
292
293static int fib6_dump_node(struct fib6_walker_t *w)
294{
295 int res;
296 struct rt6_info *rt;
297
298 for (rt = w->leaf; rt; rt = rt->u.next) {
299 res = rt6_dump_route(rt, w->args);
300 if (res < 0) {
301 /* Frame is full, suspend walking */
302 w->leaf = rt;
303 return 1;
304 }
305 BUG_TRAP(res!=0);
306 }
307 w->leaf = NULL;
308 return 0;
309}
310
311static void fib6_dump_end(struct netlink_callback *cb)
312{
313 struct fib6_walker_t *w = (void*)cb->args[2];
314
315 if (w) {
316 cb->args[2] = 0;
317 kfree(w);
318 }
319 cb->done = (void*)cb->args[3];
320 cb->args[1] = 3;
321}
322
323static int fib6_dump_done(struct netlink_callback *cb)
324{
325 fib6_dump_end(cb);
326 return cb->done ? cb->done(cb) : 0;
327}
328
329static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb,
330 struct netlink_callback *cb)
331{
332 struct fib6_walker_t *w;
333 int res;
334
335 w = (void *)cb->args[2];
336 w->root = &table->tb6_root;
337
338 if (cb->args[4] == 0) {
339 read_lock_bh(&table->tb6_lock);
340 res = fib6_walk(w);
341 read_unlock_bh(&table->tb6_lock);
342 if (res > 0)
343 cb->args[4] = 1;
344 } else {
345 read_lock_bh(&table->tb6_lock);
346 res = fib6_walk_continue(w);
347 read_unlock_bh(&table->tb6_lock);
348 if (res != 0) {
349 if (res < 0)
350 fib6_walker_unlink(w);
351 goto end;
352 }
353 fib6_walker_unlink(w);
354 cb->args[4] = 0;
355 }
356end:
357 return res;
358}
359
360int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
361{
362 unsigned int h, s_h;
363 unsigned int e = 0, s_e;
364 struct rt6_rtnl_dump_arg arg;
365 struct fib6_walker_t *w;
366 struct fib6_table *tb;
367 struct hlist_node *node;
368 int res = 0;
369
370 s_h = cb->args[0];
371 s_e = cb->args[1];
372
373 w = (void *)cb->args[2];
374 if (w == NULL) {
375 /* New dump:
376 *
377 * 1. hook callback destructor.
378 */
379 cb->args[3] = (long)cb->done;
380 cb->done = fib6_dump_done;
381
382 /*
383 * 2. allocate and initialize walker.
384 */
385 w = kzalloc(sizeof(*w), GFP_ATOMIC);
386 if (w == NULL)
387 return -ENOMEM;
388 w->func = fib6_dump_node;
389 cb->args[2] = (long)w;
390 }
391
392 arg.skb = skb;
393 arg.cb = cb;
394 w->args = &arg;
395
396 for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
397 e = 0;
398 hlist_for_each_entry(tb, node, &fib_table_hash[h], tb6_hlist) {
399 if (e < s_e)
400 goto next;
401 res = fib6_dump_table(tb, skb, cb);
402 if (res != 0)
403 goto out;
404next:
405 e++;
406 }
407 }
408out:
409 cb->args[1] = e;
410 cb->args[0] = h;
411
412 res = res < 0 ? res : skb->len;
413 if (res <= 0)
414 fib6_dump_end(cb);
415 return res;
416}
151 417
152/* 418/*
153 * Routing Table 419 * Routing Table
@@ -344,7 +610,7 @@ insert_above:
344 */ 610 */
345 611
346static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, 612static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
347 struct nlmsghdr *nlh, struct netlink_skb_parms *req) 613 struct nl_info *info)
348{ 614{
349 struct rt6_info *iter = NULL; 615 struct rt6_info *iter = NULL;
350 struct rt6_info **ins; 616 struct rt6_info **ins;
@@ -399,7 +665,7 @@ out:
399 *ins = rt; 665 *ins = rt;
400 rt->rt6i_node = fn; 666 rt->rt6i_node = fn;
401 atomic_inc(&rt->rt6i_ref); 667 atomic_inc(&rt->rt6i_ref);
402 inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req); 668 inet6_rt_notify(RTM_NEWROUTE, rt, info);
403 rt6_stats.fib_rt_entries++; 669 rt6_stats.fib_rt_entries++;
404 670
405 if ((fn->fn_flags & RTN_RTINFO) == 0) { 671 if ((fn->fn_flags & RTN_RTINFO) == 0) {
@@ -429,10 +695,9 @@ void fib6_force_start_gc(void)
429 * with source addr info in sub-trees 695 * with source addr info in sub-trees
430 */ 696 */
431 697
432int fib6_add(struct fib6_node *root, struct rt6_info *rt, 698int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
433 struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
434{ 699{
435 struct fib6_node *fn; 700 struct fib6_node *fn, *pn = NULL;
436 int err = -ENOMEM; 701 int err = -ENOMEM;
437 702
438 fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr), 703 fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
@@ -441,6 +706,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
441 if (fn == NULL) 706 if (fn == NULL)
442 goto out; 707 goto out;
443 708
709 pn = fn;
710
444#ifdef CONFIG_IPV6_SUBTREES 711#ifdef CONFIG_IPV6_SUBTREES
445 if (rt->rt6i_src.plen) { 712 if (rt->rt6i_src.plen) {
446 struct fib6_node *sn; 713 struct fib6_node *sn;
@@ -486,10 +753,6 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
486 /* Now link new subtree to main tree */ 753 /* Now link new subtree to main tree */
487 sfn->parent = fn; 754 sfn->parent = fn;
488 fn->subtree = sfn; 755 fn->subtree = sfn;
489 if (fn->leaf == NULL) {
490 fn->leaf = rt;
491 atomic_inc(&rt->rt6i_ref);
492 }
493 } else { 756 } else {
494 sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr, 757 sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr,
495 sizeof(struct in6_addr), rt->rt6i_src.plen, 758 sizeof(struct in6_addr), rt->rt6i_src.plen,
@@ -499,21 +762,42 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
499 goto st_failure; 762 goto st_failure;
500 } 763 }
501 764
765 if (fn->leaf == NULL) {
766 fn->leaf = rt;
767 atomic_inc(&rt->rt6i_ref);
768 }
502 fn = sn; 769 fn = sn;
503 } 770 }
504#endif 771#endif
505 772
506 err = fib6_add_rt2node(fn, rt, nlh, req); 773 err = fib6_add_rt2node(fn, rt, info);
507 774
508 if (err == 0) { 775 if (err == 0) {
509 fib6_start_gc(rt); 776 fib6_start_gc(rt);
510 if (!(rt->rt6i_flags&RTF_CACHE)) 777 if (!(rt->rt6i_flags&RTF_CACHE))
511 fib6_prune_clones(fn, rt); 778 fib6_prune_clones(pn, rt);
512 } 779 }
513 780
514out: 781out:
515 if (err) 782 if (err) {
783#ifdef CONFIG_IPV6_SUBTREES
784 /*
785 * If fib6_add_1 has cleared the old leaf pointer in the
786 * super-tree leaf node we have to find a new one for it.
787 */
788 if (pn != fn && !pn->leaf && !(pn->fn_flags & RTN_RTINFO)) {
789 pn->leaf = fib6_find_prefix(pn);
790#if RT6_DEBUG >= 2
791 if (!pn->leaf) {
792 BUG_TRAP(pn->leaf != NULL);
793 pn->leaf = &ip6_null_entry;
794 }
795#endif
796 atomic_inc(&pn->leaf->rt6i_ref);
797 }
798#endif
516 dst_free(&rt->u.dst); 799 dst_free(&rt->u.dst);
800 }
517 return err; 801 return err;
518 802
519#ifdef CONFIG_IPV6_SUBTREES 803#ifdef CONFIG_IPV6_SUBTREES
@@ -544,6 +828,9 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
544 struct fib6_node *fn; 828 struct fib6_node *fn;
545 int dir; 829 int dir;
546 830
831 if (unlikely(args->offset == 0))
832 return NULL;
833
547 /* 834 /*
548 * Descend on a tree 835 * Descend on a tree
549 */ 836 */
@@ -565,33 +852,26 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
565 break; 852 break;
566 } 853 }
567 854
568 while ((fn->fn_flags & RTN_ROOT) == 0) { 855 while(fn) {
569#ifdef CONFIG_IPV6_SUBTREES 856 if (FIB6_SUBTREE(fn) || fn->fn_flags & RTN_RTINFO) {
570 if (fn->subtree) {
571 struct fib6_node *st;
572 struct lookup_args *narg;
573
574 narg = args + 1;
575
576 if (narg->addr) {
577 st = fib6_lookup_1(fn->subtree, narg);
578
579 if (st && !(st->fn_flags & RTN_ROOT))
580 return st;
581 }
582 }
583#endif
584
585 if (fn->fn_flags & RTN_RTINFO) {
586 struct rt6key *key; 857 struct rt6key *key;
587 858
588 key = (struct rt6key *) ((u8 *) fn->leaf + 859 key = (struct rt6key *) ((u8 *) fn->leaf +
589 args->offset); 860 args->offset);
590 861
591 if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) 862 if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) {
592 return fn; 863#ifdef CONFIG_IPV6_SUBTREES
864 if (fn->subtree)
865 fn = fib6_lookup_1(fn->subtree, args + 1);
866#endif
867 if (!fn || fn->fn_flags & RTN_RTINFO)
868 return fn;
869 }
593 } 870 }
594 871
872 if (fn->fn_flags & RTN_ROOT)
873 break;
874
595 fn = fn->parent; 875 fn = fn->parent;
596 } 876 }
597 877
@@ -601,18 +881,24 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
601struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr, 881struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr,
602 struct in6_addr *saddr) 882 struct in6_addr *saddr)
603{ 883{
604 struct lookup_args args[2];
605 struct fib6_node *fn; 884 struct fib6_node *fn;
606 885 struct lookup_args args[] = {
607 args[0].offset = offsetof(struct rt6_info, rt6i_dst); 886 {
608 args[0].addr = daddr; 887 .offset = offsetof(struct rt6_info, rt6i_dst),
609 888 .addr = daddr,
889 },
610#ifdef CONFIG_IPV6_SUBTREES 890#ifdef CONFIG_IPV6_SUBTREES
611 args[1].offset = offsetof(struct rt6_info, rt6i_src); 891 {
612 args[1].addr = saddr; 892 .offset = offsetof(struct rt6_info, rt6i_src),
893 .addr = saddr,
894 },
613#endif 895#endif
896 {
897 .offset = 0, /* sentinel */
898 }
899 };
614 900
615 fn = fib6_lookup_1(root, args); 901 fn = fib6_lookup_1(root, daddr ? args : args + 1);
616 902
617 if (fn == NULL || fn->fn_flags & RTN_TL_ROOT) 903 if (fn == NULL || fn->fn_flags & RTN_TL_ROOT)
618 fn = root; 904 fn = root;
@@ -668,10 +954,8 @@ struct fib6_node * fib6_locate(struct fib6_node *root,
668#ifdef CONFIG_IPV6_SUBTREES 954#ifdef CONFIG_IPV6_SUBTREES
669 if (src_len) { 955 if (src_len) {
670 BUG_TRAP(saddr!=NULL); 956 BUG_TRAP(saddr!=NULL);
671 if (fn == NULL) 957 if (fn && fn->subtree)
672 fn = fn->subtree; 958 fn = fib6_locate_1(fn->subtree, saddr, src_len,
673 if (fn)
674 fn = fib6_locate_1(fn, saddr, src_len,
675 offsetof(struct rt6_info, rt6i_src)); 959 offsetof(struct rt6_info, rt6i_src));
676 } 960 }
677#endif 961#endif
@@ -700,7 +984,7 @@ static struct rt6_info * fib6_find_prefix(struct fib6_node *fn)
700 if(fn->right) 984 if(fn->right)
701 return fn->right->leaf; 985 return fn->right->leaf;
702 986
703 fn = SUBTREE(fn); 987 fn = FIB6_SUBTREE(fn);
704 } 988 }
705 return NULL; 989 return NULL;
706} 990}
@@ -731,7 +1015,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
731 if (fn->right) child = fn->right, children |= 1; 1015 if (fn->right) child = fn->right, children |= 1;
732 if (fn->left) child = fn->left, children |= 2; 1016 if (fn->left) child = fn->left, children |= 2;
733 1017
734 if (children == 3 || SUBTREE(fn) 1018 if (children == 3 || FIB6_SUBTREE(fn)
735#ifdef CONFIG_IPV6_SUBTREES 1019#ifdef CONFIG_IPV6_SUBTREES
736 /* Subtree root (i.e. fn) may have one child */ 1020 /* Subtree root (i.e. fn) may have one child */
737 || (children && fn->fn_flags&RTN_ROOT) 1021 || (children && fn->fn_flags&RTN_ROOT)
@@ -750,9 +1034,9 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
750 1034
751 pn = fn->parent; 1035 pn = fn->parent;
752#ifdef CONFIG_IPV6_SUBTREES 1036#ifdef CONFIG_IPV6_SUBTREES
753 if (SUBTREE(pn) == fn) { 1037 if (FIB6_SUBTREE(pn) == fn) {
754 BUG_TRAP(fn->fn_flags&RTN_ROOT); 1038 BUG_TRAP(fn->fn_flags&RTN_ROOT);
755 SUBTREE(pn) = NULL; 1039 FIB6_SUBTREE(pn) = NULL;
756 nstate = FWS_L; 1040 nstate = FWS_L;
757 } else { 1041 } else {
758 BUG_TRAP(!(fn->fn_flags&RTN_ROOT)); 1042 BUG_TRAP(!(fn->fn_flags&RTN_ROOT));
@@ -800,7 +1084,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
800 read_unlock(&fib6_walker_lock); 1084 read_unlock(&fib6_walker_lock);
801 1085
802 node_free(fn); 1086 node_free(fn);
803 if (pn->fn_flags&RTN_RTINFO || SUBTREE(pn)) 1087 if (pn->fn_flags&RTN_RTINFO || FIB6_SUBTREE(pn))
804 return pn; 1088 return pn;
805 1089
806 rt6_release(pn->leaf); 1090 rt6_release(pn->leaf);
@@ -810,7 +1094,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn)
810} 1094}
811 1095
812static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, 1096static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
813 struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) 1097 struct nl_info *info)
814{ 1098{
815 struct fib6_walker_t *w; 1099 struct fib6_walker_t *w;
816 struct rt6_info *rt = *rtp; 1100 struct rt6_info *rt = *rtp;
@@ -866,11 +1150,11 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
866 if (atomic_read(&rt->rt6i_ref) != 1) BUG(); 1150 if (atomic_read(&rt->rt6i_ref) != 1) BUG();
867 } 1151 }
868 1152
869 inet6_rt_notify(RTM_DELROUTE, rt, nlh, req); 1153 inet6_rt_notify(RTM_DELROUTE, rt, info);
870 rt6_release(rt); 1154 rt6_release(rt);
871} 1155}
872 1156
873int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) 1157int fib6_del(struct rt6_info *rt, struct nl_info *info)
874{ 1158{
875 struct fib6_node *fn = rt->rt6i_node; 1159 struct fib6_node *fn = rt->rt6i_node;
876 struct rt6_info **rtp; 1160 struct rt6_info **rtp;
@@ -886,8 +1170,18 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct ne
886 1170
887 BUG_TRAP(fn->fn_flags&RTN_RTINFO); 1171 BUG_TRAP(fn->fn_flags&RTN_RTINFO);
888 1172
889 if (!(rt->rt6i_flags&RTF_CACHE)) 1173 if (!(rt->rt6i_flags&RTF_CACHE)) {
890 fib6_prune_clones(fn, rt); 1174 struct fib6_node *pn = fn;
1175#ifdef CONFIG_IPV6_SUBTREES
1176 /* clones of this route might be in another subtree */
1177 if (rt->rt6i_src.plen) {
1178 while (!(pn->fn_flags&RTN_ROOT))
1179 pn = pn->parent;
1180 pn = pn->parent;
1181 }
1182#endif
1183 fib6_prune_clones(pn, rt);
1184 }
891 1185
892 /* 1186 /*
893 * Walk the leaf entries looking for ourself 1187 * Walk the leaf entries looking for ourself
@@ -895,7 +1189,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct ne
895 1189
896 for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) { 1190 for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
897 if (*rtp == rt) { 1191 if (*rtp == rt) {
898 fib6_del_route(fn, rtp, nlh, _rtattr, req); 1192 fib6_del_route(fn, rtp, info);
899 return 0; 1193 return 0;
900 } 1194 }
901 } 1195 }
@@ -926,7 +1220,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct ne
926 * <0 -> walk is terminated by an error. 1220 * <0 -> walk is terminated by an error.
927 */ 1221 */
928 1222
929int fib6_walk_continue(struct fib6_walker_t *w) 1223static int fib6_walk_continue(struct fib6_walker_t *w)
930{ 1224{
931 struct fib6_node *fn, *pn; 1225 struct fib6_node *fn, *pn;
932 1226
@@ -943,8 +1237,8 @@ int fib6_walk_continue(struct fib6_walker_t *w)
943 switch (w->state) { 1237 switch (w->state) {
944#ifdef CONFIG_IPV6_SUBTREES 1238#ifdef CONFIG_IPV6_SUBTREES
945 case FWS_S: 1239 case FWS_S:
946 if (SUBTREE(fn)) { 1240 if (FIB6_SUBTREE(fn)) {
947 w->node = SUBTREE(fn); 1241 w->node = FIB6_SUBTREE(fn);
948 continue; 1242 continue;
949 } 1243 }
950 w->state = FWS_L; 1244 w->state = FWS_L;
@@ -978,7 +1272,7 @@ int fib6_walk_continue(struct fib6_walker_t *w)
978 pn = fn->parent; 1272 pn = fn->parent;
979 w->node = pn; 1273 w->node = pn;
980#ifdef CONFIG_IPV6_SUBTREES 1274#ifdef CONFIG_IPV6_SUBTREES
981 if (SUBTREE(pn) == fn) { 1275 if (FIB6_SUBTREE(pn) == fn) {
982 BUG_TRAP(fn->fn_flags&RTN_ROOT); 1276 BUG_TRAP(fn->fn_flags&RTN_ROOT);
983 w->state = FWS_L; 1277 w->state = FWS_L;
984 continue; 1278 continue;
@@ -1000,7 +1294,7 @@ int fib6_walk_continue(struct fib6_walker_t *w)
1000 } 1294 }
1001} 1295}
1002 1296
1003int fib6_walk(struct fib6_walker_t *w) 1297static int fib6_walk(struct fib6_walker_t *w)
1004{ 1298{
1005 int res; 1299 int res;
1006 1300
@@ -1024,7 +1318,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
1024 res = c->func(rt, c->arg); 1318 res = c->func(rt, c->arg);
1025 if (res < 0) { 1319 if (res < 0) {
1026 w->leaf = rt; 1320 w->leaf = rt;
1027 res = fib6_del(rt, NULL, NULL, NULL); 1321 res = fib6_del(rt, NULL);
1028 if (res) { 1322 if (res) {
1029#if RT6_DEBUG >= 2 1323#if RT6_DEBUG >= 2
1030 printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res); 1324 printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
@@ -1050,9 +1344,9 @@ static int fib6_clean_node(struct fib6_walker_t *w)
1050 * ignoring pure split nodes) will be scanned. 1344 * ignoring pure split nodes) will be scanned.
1051 */ 1345 */
1052 1346
1053void fib6_clean_tree(struct fib6_node *root, 1347static void fib6_clean_tree(struct fib6_node *root,
1054 int (*func)(struct rt6_info *, void *arg), 1348 int (*func)(struct rt6_info *, void *arg),
1055 int prune, void *arg) 1349 int prune, void *arg)
1056{ 1350{
1057 struct fib6_cleaner_t c; 1351 struct fib6_cleaner_t c;
1058 1352
@@ -1065,6 +1359,25 @@ void fib6_clean_tree(struct fib6_node *root,
1065 fib6_walk(&c.w); 1359 fib6_walk(&c.w);
1066} 1360}
1067 1361
1362void fib6_clean_all(int (*func)(struct rt6_info *, void *arg),
1363 int prune, void *arg)
1364{
1365 struct fib6_table *table;
1366 struct hlist_node *node;
1367 unsigned int h;
1368
1369 rcu_read_lock();
1370 for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
1371 hlist_for_each_entry_rcu(table, node, &fib_table_hash[h],
1372 tb6_hlist) {
1373 write_lock_bh(&table->tb6_lock);
1374 fib6_clean_tree(&table->tb6_root, func, prune, arg);
1375 write_unlock_bh(&table->tb6_lock);
1376 }
1377 }
1378 rcu_read_unlock();
1379}
1380
1068static int fib6_prune_clone(struct rt6_info *rt, void *arg) 1381static int fib6_prune_clone(struct rt6_info *rt, void *arg)
1069{ 1382{
1070 if (rt->rt6i_flags & RTF_CACHE) { 1383 if (rt->rt6i_flags & RTF_CACHE) {
@@ -1143,11 +1456,8 @@ void fib6_run_gc(unsigned long dummy)
1143 } 1456 }
1144 gc_args.more = 0; 1457 gc_args.more = 0;
1145 1458
1146
1147 write_lock_bh(&rt6_lock);
1148 ndisc_dst_gc(&gc_args.more); 1459 ndisc_dst_gc(&gc_args.more);
1149 fib6_clean_tree(&ip6_routing_table, fib6_age, 0, NULL); 1460 fib6_clean_all(fib6_age, 0, NULL);
1150 write_unlock_bh(&rt6_lock);
1151 1461
1152 if (gc_args.more) 1462 if (gc_args.more)
1153 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); 1463 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
@@ -1162,10 +1472,10 @@ void __init fib6_init(void)
1162{ 1472{
1163 fib6_node_kmem = kmem_cache_create("fib6_nodes", 1473 fib6_node_kmem = kmem_cache_create("fib6_nodes",
1164 sizeof(struct fib6_node), 1474 sizeof(struct fib6_node),
1165 0, SLAB_HWCACHE_ALIGN, 1475 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
1166 NULL, NULL); 1476 NULL, NULL);
1167 if (!fib6_node_kmem) 1477
1168 panic("cannot create fib6_nodes cache"); 1478 fib6_tables_init();
1169} 1479}
1170 1480
1171void fib6_gc_cleanup(void) 1481void fib6_gc_cleanup(void)
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index f9ca63912fbf..1d672b0547f2 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/capability.h> 12#include <linux/capability.h>
13#include <linux/config.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
15#include <linux/types.h> 14#include <linux/types.h>
16#include <linux/socket.h> 15#include <linux/socket.h>
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index aceee252503d..6b8e6d76a58b 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -71,6 +71,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
71 goto out; 71 goto out;
72 } 72 }
73 73
74 memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
75
74 /* 76 /*
75 * Store incoming device index. When the packet will 77 * Store incoming device index. When the packet will
76 * be queued, we cannot refer to skb->dev anymore. 78 * be queued, we cannot refer to skb->dev anymore.
@@ -84,14 +86,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
84 */ 86 */
85 IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex; 87 IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex;
86 88
87 if (skb->len < sizeof(struct ipv6hdr)) 89 if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
88 goto err; 90 goto err;
89 91
90 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
91 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
92 goto drop;
93 }
94
95 hdr = skb->nh.ipv6h; 92 hdr = skb->nh.ipv6h;
96 93
97 if (hdr->version != 6) 94 if (hdr->version != 6)
@@ -114,7 +111,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
114 } 111 }
115 112
116 if (hdr->nexthdr == NEXTHDR_HOP) { 113 if (hdr->nexthdr == NEXTHDR_HOP) {
117 if (ipv6_parse_hopopts(skb) < 0) { 114 if (ipv6_parse_hopopts(&skb) < 0) {
118 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 115 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
119 return 0; 116 return 0;
120 } 117 }
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index abb94de33768..66716911962e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -28,7 +28,6 @@
28 * for datagram xmit 28 * for datagram xmit
29 */ 29 */
30 30
31#include <linux/config.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/string.h> 33#include <linux/string.h>
@@ -148,7 +147,7 @@ static int ip6_output2(struct sk_buff *skb)
148 147
149int ip6_output(struct sk_buff *skb) 148int ip6_output(struct sk_buff *skb)
150{ 149{
151 if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) || 150 if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) ||
152 dst_allfrag(skb->dst)) 151 dst_allfrag(skb->dst))
153 return ip6_fragment(skb, ip6_output2); 152 return ip6_fragment(skb, ip6_output2);
154 else 153 else
@@ -230,7 +229,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
230 skb->priority = sk->sk_priority; 229 skb->priority = sk->sk_priority;
231 230
232 mtu = dst_mtu(dst); 231 mtu = dst_mtu(dst);
233 if ((skb->len <= mtu) || ipfragok) { 232 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
234 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 233 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
235 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, 234 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
236 dst_output); 235 dst_output);
@@ -309,6 +308,56 @@ static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
309 return 0; 308 return 0;
310} 309}
311 310
311static int ip6_forward_proxy_check(struct sk_buff *skb)
312{
313 struct ipv6hdr *hdr = skb->nh.ipv6h;
314 u8 nexthdr = hdr->nexthdr;
315 int offset;
316
317 if (ipv6_ext_hdr(nexthdr)) {
318 offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr);
319 if (offset < 0)
320 return 0;
321 } else
322 offset = sizeof(struct ipv6hdr);
323
324 if (nexthdr == IPPROTO_ICMPV6) {
325 struct icmp6hdr *icmp6;
326
327 if (!pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data))
328 return 0;
329
330 icmp6 = (struct icmp6hdr *)(skb->nh.raw + offset);
331
332 switch (icmp6->icmp6_type) {
333 case NDISC_ROUTER_SOLICITATION:
334 case NDISC_ROUTER_ADVERTISEMENT:
335 case NDISC_NEIGHBOUR_SOLICITATION:
336 case NDISC_NEIGHBOUR_ADVERTISEMENT:
337 case NDISC_REDIRECT:
338 /* For reaction involving unicast neighbor discovery
339 * message destined to the proxied address, pass it to
340 * input function.
341 */
342 return 1;
343 default:
344 break;
345 }
346 }
347
348 /*
349 * The proxying router can't forward traffic sent to a link-local
350 * address, so signal the sender and discard the packet. This
351 * behavior is clarified by the MIPv6 specification.
352 */
353 if (ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) {
354 dst_link_failure(skb);
355 return -1;
356 }
357
358 return 0;
359}
360
312static inline int ip6_forward_finish(struct sk_buff *skb) 361static inline int ip6_forward_finish(struct sk_buff *skb)
313{ 362{
314 return dst_output(skb); 363 return dst_output(skb);
@@ -357,11 +406,24 @@ int ip6_forward(struct sk_buff *skb)
357 skb->dev = dst->dev; 406 skb->dev = dst->dev;
358 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 407 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
359 0, skb->dev); 408 0, skb->dev);
409 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
360 410
361 kfree_skb(skb); 411 kfree_skb(skb);
362 return -ETIMEDOUT; 412 return -ETIMEDOUT;
363 } 413 }
364 414
415 /* XXX: idev->cnf.proxy_ndp? */
416 if (ipv6_devconf.proxy_ndp &&
417 pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
418 int proxied = ip6_forward_proxy_check(skb);
419 if (proxied > 0)
420 return ip6_input(skb);
421 else if (proxied < 0) {
422 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS);
423 goto drop;
424 }
425 }
426
365 if (!xfrm6_route_forward(skb)) { 427 if (!xfrm6_route_forward(skb)) {
366 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 428 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS);
367 goto drop; 429 goto drop;
@@ -475,17 +537,25 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
475 switch (**nexthdr) { 537 switch (**nexthdr) {
476 538
477 case NEXTHDR_HOP: 539 case NEXTHDR_HOP:
540 break;
478 case NEXTHDR_ROUTING: 541 case NEXTHDR_ROUTING:
542 found_rhdr = 1;
543 break;
479 case NEXTHDR_DEST: 544 case NEXTHDR_DEST:
480 if (**nexthdr == NEXTHDR_ROUTING) found_rhdr = 1; 545#ifdef CONFIG_IPV6_MIP6
481 if (**nexthdr == NEXTHDR_DEST && found_rhdr) return offset; 546 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
482 offset += ipv6_optlen(exthdr); 547 break;
483 *nexthdr = &exthdr->nexthdr; 548#endif
484 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); 549 if (found_rhdr)
550 return offset;
485 break; 551 break;
486 default : 552 default :
487 return offset; 553 return offset;
488 } 554 }
555
556 offset += ipv6_optlen(exthdr);
557 *nexthdr = &exthdr->nexthdr;
558 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
489 } 559 }
490 560
491 return offset; 561 return offset;
@@ -596,6 +666,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
596 } 666 }
597 667
598 err = output(skb); 668 err = output(skb);
669 if(!err)
670 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
671
599 if (err || !frag) 672 if (err || !frag)
600 break; 673 break;
601 674
@@ -707,12 +780,11 @@ slow_path:
707 /* 780 /*
708 * Put this fragment into the sending queue. 781 * Put this fragment into the sending queue.
709 */ 782 */
710
711 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
712
713 err = output(frag); 783 err = output(frag);
714 if (err) 784 if (err)
715 goto fail; 785 goto fail;
786
787 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
716 } 788 }
717 kfree_skb(skb); 789 kfree_skb(skb);
718 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); 790 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
@@ -724,48 +796,59 @@ fail:
724 return err; 796 return err;
725} 797}
726 798
727int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) 799static inline int ip6_rt_check(struct rt6key *rt_key,
800 struct in6_addr *fl_addr,
801 struct in6_addr *addr_cache)
728{ 802{
729 int err = 0; 803 return ((rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
804 (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache)));
805}
730 806
731 *dst = NULL; 807static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
732 if (sk) { 808 struct dst_entry *dst,
733 struct ipv6_pinfo *np = inet6_sk(sk); 809 struct flowi *fl)
734 810{
735 *dst = sk_dst_check(sk, np->dst_cookie); 811 struct ipv6_pinfo *np = inet6_sk(sk);
736 if (*dst) { 812 struct rt6_info *rt = (struct rt6_info *)dst;
737 struct rt6_info *rt = (struct rt6_info*)*dst; 813
738 814 if (!dst)
739 /* Yes, checking route validity in not connected 815 goto out;
740 * case is not very simple. Take into account, 816
741 * that we do not support routing by source, TOS, 817 /* Yes, checking route validity in not connected
742 * and MSG_DONTROUTE --ANK (980726) 818 * case is not very simple. Take into account,
743 * 819 * that we do not support routing by source, TOS,
744 * 1. If route was host route, check that 820 * and MSG_DONTROUTE --ANK (980726)
745 * cached destination is current. 821 *
746 * If it is network route, we still may 822 * 1. ip6_rt_check(): If route was host route,
747 * check its validity using saved pointer 823 * check that cached destination is current.
748 * to the last used address: daddr_cache. 824 * If it is network route, we still may
749 * We do not want to save whole address now, 825 * check its validity using saved pointer
750 * (because main consumer of this service 826 * to the last used address: daddr_cache.
751 * is tcp, which has not this problem), 827 * We do not want to save whole address now,
752 * so that the last trick works only on connected 828 * (because main consumer of this service
753 * sockets. 829 * is tcp, which has not this problem),
754 * 2. oif also should be the same. 830 * so that the last trick works only on connected
755 */ 831 * sockets.
756 if (((rt->rt6i_dst.plen != 128 || 832 * 2. oif also should be the same.
757 !ipv6_addr_equal(&fl->fl6_dst, 833 */
758 &rt->rt6i_dst.addr)) 834 if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) ||
759 && (np->daddr_cache == NULL || 835#ifdef CONFIG_IPV6_SUBTREES
760 !ipv6_addr_equal(&fl->fl6_dst, 836 ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) ||
761 np->daddr_cache))) 837#endif
762 || (fl->oif && fl->oif != (*dst)->dev->ifindex)) { 838 (fl->oif && fl->oif != dst->dev->ifindex)) {
763 dst_release(*dst); 839 dst_release(dst);
764 *dst = NULL; 840 dst = NULL;
765 }
766 }
767 } 841 }
768 842
843out:
844 return dst;
845}
846
847static int ip6_dst_lookup_tail(struct sock *sk,
848 struct dst_entry **dst, struct flowi *fl)
849{
850 int err;
851
769 if (*dst == NULL) 852 if (*dst == NULL)
770 *dst = ip6_route_output(sk, fl); 853 *dst = ip6_route_output(sk, fl);
771 854
@@ -774,7 +857,6 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
774 857
775 if (ipv6_addr_any(&fl->fl6_src)) { 858 if (ipv6_addr_any(&fl->fl6_src)) {
776 err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); 859 err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
777
778 if (err) 860 if (err)
779 goto out_err_release; 861 goto out_err_release;
780 } 862 }
@@ -787,8 +869,48 @@ out_err_release:
787 return err; 869 return err;
788} 870}
789 871
872/**
873 * ip6_dst_lookup - perform route lookup on flow
874 * @sk: socket which provides route info
875 * @dst: pointer to dst_entry * for result
876 * @fl: flow to lookup
877 *
878 * This function performs a route lookup on the given flow.
879 *
880 * It returns zero on success, or a standard errno code on error.
881 */
882int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
883{
884 *dst = NULL;
885 return ip6_dst_lookup_tail(sk, dst, fl);
886}
790EXPORT_SYMBOL_GPL(ip6_dst_lookup); 887EXPORT_SYMBOL_GPL(ip6_dst_lookup);
791 888
889/**
890 * ip6_sk_dst_lookup - perform socket cached route lookup on flow
891 * @sk: socket which provides the dst cache and route info
892 * @dst: pointer to dst_entry * for result
893 * @fl: flow to lookup
894 *
895 * This function performs a route lookup on the given flow with the
896 * possibility of using the cached route in the socket if it is valid.
897 * It will take the socket dst lock when operating on the dst cache.
898 * As a result, this function can only be used in process context.
899 *
900 * It returns zero on success, or a standard errno code on error.
901 */
902int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
903{
904 *dst = NULL;
905 if (sk) {
906 *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
907 *dst = ip6_sk_dst_check(sk, *dst, fl);
908 }
909
910 return ip6_dst_lookup_tail(sk, dst, fl);
911}
912EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup);
913
792static inline int ip6_ufo_append_data(struct sock *sk, 914static inline int ip6_ufo_append_data(struct sock *sk,
793 int getfrag(void *from, char *to, int offset, int len, 915 int getfrag(void *from, char *to, int offset, int len,
794 int odd, struct sk_buff *skb), 916 int odd, struct sk_buff *skb),
@@ -822,7 +944,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
822 /* initialize protocol header pointer */ 944 /* initialize protocol header pointer */
823 skb->h.raw = skb->data + fragheaderlen; 945 skb->h.raw = skb->data + fragheaderlen;
824 946
825 skb->ip_summed = CHECKSUM_HW; 947 skb->ip_summed = CHECKSUM_PARTIAL;
826 skb->csum = 0; 948 skb->csum = 0;
827 sk->sk_sndmsg_off = 0; 949 sk->sk_sndmsg_off = 0;
828 } 950 }
@@ -835,7 +957,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
835 /* specify the length of each IP datagram fragment*/ 957 /* specify the length of each IP datagram fragment*/
836 skb_shinfo(skb)->gso_size = mtu - fragheaderlen - 958 skb_shinfo(skb)->gso_size = mtu - fragheaderlen -
837 sizeof(struct frag_hdr); 959 sizeof(struct frag_hdr);
838 skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4; 960 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
839 ipv6_select_ident(skb, &fhdr); 961 ipv6_select_ident(skb, &fhdr);
840 skb_shinfo(skb)->ip6_frag_id = fhdr.identification; 962 skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
841 __skb_queue_tail(&sk->sk_write_queue, skb); 963 __skb_queue_tail(&sk->sk_write_queue, skb);
@@ -919,7 +1041,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
919 1041
920 hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); 1042 hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
921 1043
922 fragheaderlen = sizeof(struct ipv6hdr) + (opt ? opt->opt_nflen : 0); 1044 fragheaderlen = sizeof(struct ipv6hdr) + rt->u.dst.nfheader_len + (opt ? opt->opt_nflen : 0);
923 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); 1045 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
924 1046
925 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { 1047 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
@@ -1051,7 +1173,7 @@ alloc_new_skb:
1051 skb_prev->csum = csum_sub(skb_prev->csum, 1173 skb_prev->csum = csum_sub(skb_prev->csum,
1052 skb->csum); 1174 skb->csum);
1053 data += fraggap; 1175 data += fraggap;
1054 skb_trim(skb_prev, maxfraglen); 1176 pskb_trim_unique(skb_prev, maxfraglen);
1055 } 1177 }
1056 copy = datalen - transhdrlen - fraggap; 1178 copy = datalen - transhdrlen - fraggap;
1057 if (copy < 0) { 1179 if (copy < 0) {
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a995796b5a57..84d7ebdb9d21 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/config.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/capability.h> 23#include <linux/capability.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
@@ -568,10 +567,9 @@ static inline struct ipv6_txoptions *create_tel(__u8 encap_limit)
568 567
569 int opt_len = sizeof(*opt) + 8; 568 int opt_len = sizeof(*opt) + 8;
570 569
571 if (!(opt = kmalloc(opt_len, GFP_ATOMIC))) { 570 if (!(opt = kzalloc(opt_len, GFP_ATOMIC))) {
572 return NULL; 571 return NULL;
573 } 572 }
574 memset(opt, 0, opt_len);
575 opt->tot_len = opt_len; 573 opt->tot_len = opt_len;
576 opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1); 574 opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1);
577 opt->opt_nflen = 8; 575 opt->opt_nflen = 8;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index f28cd37feed3..a2860e35efd7 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -30,7 +30,6 @@
30 * The decompression of IP datagram MUST be done after the reassembly, 30 * The decompression of IP datagram MUST be done after the reassembly,
31 * AH/ESP processing. 31 * AH/ESP processing.
32 */ 32 */
33#include <linux/config.h>
34#include <linux/module.h> 33#include <linux/module.h>
35#include <net/ip.h> 34#include <net/ip.h>
36#include <net/xfrm.h> 35#include <net/xfrm.h>
@@ -54,7 +53,7 @@
54 53
55struct ipcomp6_tfms { 54struct ipcomp6_tfms {
56 struct list_head list; 55 struct list_head list;
57 struct crypto_tfm **tfms; 56 struct crypto_comp **tfms;
58 int users; 57 int users;
59}; 58};
60 59
@@ -71,7 +70,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
71 int plen, dlen; 70 int plen, dlen;
72 struct ipcomp_data *ipcd = x->data; 71 struct ipcomp_data *ipcd = x->data;
73 u8 *start, *scratch; 72 u8 *start, *scratch;
74 struct crypto_tfm *tfm; 73 struct crypto_comp *tfm;
75 int cpu; 74 int cpu;
76 75
77 if (skb_linearize_cow(skb)) 76 if (skb_linearize_cow(skb))
@@ -110,7 +109,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
110 goto out_put_cpu; 109 goto out_put_cpu;
111 } 110 }
112 111
113 skb_put(skb, dlen - plen); 112 skb->truesize += dlen - plen;
113 __skb_put(skb, dlen - plen);
114 memcpy(skb->data, scratch, dlen); 114 memcpy(skb->data, scratch, dlen);
115 err = ipch->nexthdr; 115 err = ipch->nexthdr;
116 116
@@ -129,7 +129,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
129 struct ipcomp_data *ipcd = x->data; 129 struct ipcomp_data *ipcd = x->data;
130 int plen, dlen; 130 int plen, dlen;
131 u8 *start, *scratch; 131 u8 *start, *scratch;
132 struct crypto_tfm *tfm; 132 struct crypto_comp *tfm;
133 int cpu; 133 int cpu;
134 134
135 hdr_len = skb->h.raw - skb->data; 135 hdr_len = skb->h.raw - skb->data;
@@ -178,7 +178,7 @@ out_ok:
178static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 178static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
179 int type, int code, int offset, __u32 info) 179 int type, int code, int offset, __u32 info)
180{ 180{
181 u32 spi; 181 __be32 spi;
182 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 182 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
183 struct ipv6_comp_hdr *ipcomph = (struct ipv6_comp_hdr*)(skb->data+offset); 183 struct ipv6_comp_hdr *ipcomph = (struct ipv6_comp_hdr*)(skb->data+offset);
184 struct xfrm_state *x; 184 struct xfrm_state *x;
@@ -212,7 +212,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
212 memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr)); 212 memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
213 memcpy(&t->sel, &x->sel, sizeof(t->sel)); 213 memcpy(&t->sel, &x->sel, sizeof(t->sel));
214 t->props.family = AF_INET6; 214 t->props.family = AF_INET6;
215 t->props.mode = 1; 215 t->props.mode = XFRM_MODE_TUNNEL;
216 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); 216 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
217 217
218 if (xfrm_init_state(t)) 218 if (xfrm_init_state(t))
@@ -234,7 +234,7 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
234{ 234{
235 int err = 0; 235 int err = 0;
236 struct xfrm_state *t = NULL; 236 struct xfrm_state *t = NULL;
237 u32 spi; 237 __be32 spi;
238 238
239 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr); 239 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&x->props.saddr);
240 if (spi) 240 if (spi)
@@ -301,7 +301,7 @@ static void **ipcomp6_alloc_scratches(void)
301 return scratches; 301 return scratches;
302} 302}
303 303
304static void ipcomp6_free_tfms(struct crypto_tfm **tfms) 304static void ipcomp6_free_tfms(struct crypto_comp **tfms)
305{ 305{
306 struct ipcomp6_tfms *pos; 306 struct ipcomp6_tfms *pos;
307 int cpu; 307 int cpu;
@@ -323,28 +323,28 @@ static void ipcomp6_free_tfms(struct crypto_tfm **tfms)
323 return; 323 return;
324 324
325 for_each_possible_cpu(cpu) { 325 for_each_possible_cpu(cpu) {
326 struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); 326 struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu);
327 crypto_free_tfm(tfm); 327 crypto_free_comp(tfm);
328 } 328 }
329 free_percpu(tfms); 329 free_percpu(tfms);
330} 330}
331 331
332static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name) 332static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name)
333{ 333{
334 struct ipcomp6_tfms *pos; 334 struct ipcomp6_tfms *pos;
335 struct crypto_tfm **tfms; 335 struct crypto_comp **tfms;
336 int cpu; 336 int cpu;
337 337
338 /* This can be any valid CPU ID so we don't need locking. */ 338 /* This can be any valid CPU ID so we don't need locking. */
339 cpu = raw_smp_processor_id(); 339 cpu = raw_smp_processor_id();
340 340
341 list_for_each_entry(pos, &ipcomp6_tfms_list, list) { 341 list_for_each_entry(pos, &ipcomp6_tfms_list, list) {
342 struct crypto_tfm *tfm; 342 struct crypto_comp *tfm;
343 343
344 tfms = pos->tfms; 344 tfms = pos->tfms;
345 tfm = *per_cpu_ptr(tfms, cpu); 345 tfm = *per_cpu_ptr(tfms, cpu);
346 346
347 if (!strcmp(crypto_tfm_alg_name(tfm), alg_name)) { 347 if (!strcmp(crypto_comp_name(tfm), alg_name)) {
348 pos->users++; 348 pos->users++;
349 return tfms; 349 return tfms;
350 } 350 }
@@ -358,12 +358,13 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name)
358 INIT_LIST_HEAD(&pos->list); 358 INIT_LIST_HEAD(&pos->list);
359 list_add(&pos->list, &ipcomp6_tfms_list); 359 list_add(&pos->list, &ipcomp6_tfms_list);
360 360
361 pos->tfms = tfms = alloc_percpu(struct crypto_tfm *); 361 pos->tfms = tfms = alloc_percpu(struct crypto_comp *);
362 if (!tfms) 362 if (!tfms)
363 goto error; 363 goto error;
364 364
365 for_each_possible_cpu(cpu) { 365 for_each_possible_cpu(cpu) {
366 struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); 366 struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
367 CRYPTO_ALG_ASYNC);
367 if (!tfm) 368 if (!tfm)
368 goto error; 369 goto error;
369 *per_cpu_ptr(tfms, cpu) = tfm; 370 *per_cpu_ptr(tfms, cpu) = tfm;
@@ -416,7 +417,7 @@ static int ipcomp6_init_state(struct xfrm_state *x)
416 goto out; 417 goto out;
417 418
418 x->props.header_len = 0; 419 x->props.header_len = 0;
419 if (x->props.mode) 420 if (x->props.mode == XFRM_MODE_TUNNEL)
420 x->props.header_len += sizeof(struct ipv6hdr); 421 x->props.header_len += sizeof(struct ipv6hdr);
421 422
422 mutex_lock(&ipcomp6_resource_mutex); 423 mutex_lock(&ipcomp6_resource_mutex);
@@ -428,7 +429,7 @@ static int ipcomp6_init_state(struct xfrm_state *x)
428 goto error; 429 goto error;
429 mutex_unlock(&ipcomp6_resource_mutex); 430 mutex_unlock(&ipcomp6_resource_mutex);
430 431
431 if (x->props.mode) { 432 if (x->props.mode == XFRM_MODE_TUNNEL) {
432 err = ipcomp6_tunnel_attach(x); 433 err = ipcomp6_tunnel_attach(x);
433 if (err) 434 if (err)
434 goto error_tunnel; 435 goto error_tunnel;
@@ -460,6 +461,7 @@ static struct xfrm_type ipcomp6_type =
460 .destructor = ipcomp6_destroy, 461 .destructor = ipcomp6_destroy,
461 .input = ipcomp6_input, 462 .input = ipcomp6_input,
462 .output = ipcomp6_output, 463 .output = ipcomp6_output,
464 .hdr_offset = xfrm6_find_1stfragopt,
463}; 465};
464 466
465static struct inet6_protocol ipcomp6_protocol = 467static struct inet6_protocol ipcomp6_protocol =
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 4c20eeb3d568..de6b91981b30 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -27,7 +27,6 @@
27 27
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/capability.h> 29#include <linux/capability.h>
30#include <linux/config.h>
31#include <linux/errno.h> 30#include <linux/errno.h>
32#include <linux/types.h> 31#include <linux/types.h>
33#include <linux/socket.h> 32#include <linux/socket.h>
@@ -58,9 +57,116 @@
58 57
59DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly; 58DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly;
60 59
60static struct inet6_protocol *ipv6_gso_pull_exthdrs(struct sk_buff *skb,
61 int proto)
62{
63 struct inet6_protocol *ops = NULL;
64
65 for (;;) {
66 struct ipv6_opt_hdr *opth;
67 int len;
68
69 if (proto != NEXTHDR_HOP) {
70 ops = rcu_dereference(inet6_protos[proto]);
71
72 if (unlikely(!ops))
73 break;
74
75 if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
76 break;
77 }
78
79 if (unlikely(!pskb_may_pull(skb, 8)))
80 break;
81
82 opth = (void *)skb->data;
83 len = opth->hdrlen * 8 + 8;
84
85 if (unlikely(!pskb_may_pull(skb, len)))
86 break;
87
88 proto = opth->nexthdr;
89 __skb_pull(skb, len);
90 }
91
92 return ops;
93}
94
95static int ipv6_gso_send_check(struct sk_buff *skb)
96{
97 struct ipv6hdr *ipv6h;
98 struct inet6_protocol *ops;
99 int err = -EINVAL;
100
101 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
102 goto out;
103
104 ipv6h = skb->nh.ipv6h;
105 __skb_pull(skb, sizeof(*ipv6h));
106 err = -EPROTONOSUPPORT;
107
108 rcu_read_lock();
109 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
110 if (likely(ops && ops->gso_send_check)) {
111 skb->h.raw = skb->data;
112 err = ops->gso_send_check(skb);
113 }
114 rcu_read_unlock();
115
116out:
117 return err;
118}
119
120static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
121{
122 struct sk_buff *segs = ERR_PTR(-EINVAL);
123 struct ipv6hdr *ipv6h;
124 struct inet6_protocol *ops;
125
126 if (!(features & NETIF_F_HW_CSUM))
127 features &= ~NETIF_F_SG;
128
129 if (unlikely(skb_shinfo(skb)->gso_type &
130 ~(SKB_GSO_UDP |
131 SKB_GSO_DODGY |
132 SKB_GSO_TCP_ECN |
133 SKB_GSO_TCPV6 |
134 0)))
135 goto out;
136
137 if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
138 goto out;
139
140 ipv6h = skb->nh.ipv6h;
141 __skb_pull(skb, sizeof(*ipv6h));
142 segs = ERR_PTR(-EPROTONOSUPPORT);
143
144 rcu_read_lock();
145 ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
146 if (likely(ops && ops->gso_segment)) {
147 skb->h.raw = skb->data;
148 segs = ops->gso_segment(skb, features);
149 }
150 rcu_read_unlock();
151
152 if (unlikely(IS_ERR(segs)))
153 goto out;
154
155 for (skb = segs; skb; skb = skb->next) {
156 ipv6h = skb->nh.ipv6h;
157 ipv6h->payload_len = htons(skb->len - skb->mac_len -
158 sizeof(*ipv6h));
159 }
160
161out:
162 return segs;
163}
164
61static struct packet_type ipv6_packet_type = { 165static struct packet_type ipv6_packet_type = {
62 .type = __constant_htons(ETH_P_IPV6), 166 .type = __constant_htons(ETH_P_IPV6),
63 .func = ipv6_rcv, 167 .func = ipv6_rcv,
168 .gso_send_check = ipv6_gso_send_check,
169 .gso_segment = ipv6_gso_segment,
64}; 170};
65 171
66struct ip6_ra_chain *ip6_ra_chain; 172struct ip6_ra_chain *ip6_ra_chain;
@@ -259,7 +365,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
259 break; 365 break;
260 366
261 case IPV6_TCLASS: 367 case IPV6_TCLASS:
262 if (val < 0 || val > 0xff) 368 if (val < -1 || val > 0xff)
263 goto e_inval; 369 goto e_inval;
264 np->tclass = val; 370 np->tclass = val;
265 retv = 0; 371 retv = 0;
@@ -304,8 +410,16 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
304 /* routing header option needs extra check */ 410 /* routing header option needs extra check */
305 if (optname == IPV6_RTHDR && opt->srcrt) { 411 if (optname == IPV6_RTHDR && opt->srcrt) {
306 struct ipv6_rt_hdr *rthdr = opt->srcrt; 412 struct ipv6_rt_hdr *rthdr = opt->srcrt;
307 if (rthdr->type) 413 switch (rthdr->type) {
414 case IPV6_SRCRT_TYPE_0:
415#ifdef CONFIG_IPV6_MIP6
416 case IPV6_SRCRT_TYPE_2:
417#endif
418 break;
419 default:
308 goto sticky_done; 420 goto sticky_done;
421 }
422
309 if ((rthdr->hdrlen & 1) || 423 if ((rthdr->hdrlen & 1) ||
310 (rthdr->hdrlen >> 1) != rthdr->segments_left) 424 (rthdr->hdrlen >> 1) != rthdr->segments_left)
311 goto sticky_done; 425 goto sticky_done;
@@ -844,6 +958,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
844 958
845 case IPV6_TCLASS: 959 case IPV6_TCLASS:
846 val = np->tclass; 960 val = np->tclass;
961 if (val < 0)
962 val = 0;
847 break; 963 break;
848 964
849 case IPV6_RECVTCLASS: 965 case IPV6_RECVTCLASS:
diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
index 16482785bdfd..0e8e0676a033 100644
--- a/net/ipv6/ipv6_syms.c
+++ b/net/ipv6/ipv6_syms.c
@@ -1,5 +1,4 @@
1 1
2#include <linux/config.h>
3#include <linux/module.h> 2#include <linux/module.h>
4#include <net/protocol.h> 3#include <net/protocol.h>
5#include <net/ipv6.h> 4#include <net/ipv6.h>
@@ -15,7 +14,6 @@ EXPORT_SYMBOL(ndisc_mc_map);
15EXPORT_SYMBOL(register_inet6addr_notifier); 14EXPORT_SYMBOL(register_inet6addr_notifier);
16EXPORT_SYMBOL(unregister_inet6addr_notifier); 15EXPORT_SYMBOL(unregister_inet6addr_notifier);
17EXPORT_SYMBOL(ip6_route_output); 16EXPORT_SYMBOL(ip6_route_output);
18EXPORT_SYMBOL(addrconf_lock);
19EXPORT_SYMBOL(ipv6_setsockopt); 17EXPORT_SYMBOL(ipv6_setsockopt);
20EXPORT_SYMBOL(ipv6_getsockopt); 18EXPORT_SYMBOL(ipv6_getsockopt);
21EXPORT_SYMBOL(inet6_register_protosw); 19EXPORT_SYMBOL(inet6_register_protosw);
@@ -32,6 +30,8 @@ EXPORT_SYMBOL(ipv6_chk_addr);
32EXPORT_SYMBOL(in6_dev_finish_destroy); 30EXPORT_SYMBOL(in6_dev_finish_destroy);
33#ifdef CONFIG_XFRM 31#ifdef CONFIG_XFRM
34EXPORT_SYMBOL(xfrm6_rcv); 32EXPORT_SYMBOL(xfrm6_rcv);
33EXPORT_SYMBOL(xfrm6_input_addr);
34EXPORT_SYMBOL(xfrm6_find_1stfragopt);
35#endif 35#endif
36EXPORT_SYMBOL(rt6_lookup); 36EXPORT_SYMBOL(rt6_lookup);
37EXPORT_SYMBOL(ipv6_push_nfrag_opts); 37EXPORT_SYMBOL(ipv6_push_nfrag_opts);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 6e871afbb2c7..3b114e3fa2f8 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -28,7 +28,6 @@
28 * - MLDv2 support 28 * - MLDv2 support
29 */ 29 */
30 30
31#include <linux/config.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/types.h> 33#include <linux/types.h>
@@ -172,7 +171,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
172 171
173#define IPV6_MLD_MAX_MSF 64 172#define IPV6_MLD_MAX_MSF 64
174 173
175int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF; 174int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
176 175
177/* 176/*
178 * socket join on multicast group 177 * socket join on multicast group
@@ -269,13 +268,14 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
269 if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) { 268 if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) {
270 struct inet6_dev *idev = in6_dev_get(dev); 269 struct inet6_dev *idev = in6_dev_get(dev);
271 270
271 (void) ip6_mc_leave_src(sk, mc_lst, idev);
272 if (idev) { 272 if (idev) {
273 (void) ip6_mc_leave_src(sk,mc_lst,idev);
274 __ipv6_dev_mc_dec(idev, &mc_lst->addr); 273 __ipv6_dev_mc_dec(idev, &mc_lst->addr);
275 in6_dev_put(idev); 274 in6_dev_put(idev);
276 } 275 }
277 dev_put(dev); 276 dev_put(dev);
278 } 277 } else
278 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
279 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 279 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
280 return 0; 280 return 0;
281 } 281 }
@@ -335,13 +335,14 @@ void ipv6_sock_mc_close(struct sock *sk)
335 if (dev) { 335 if (dev) {
336 struct inet6_dev *idev = in6_dev_get(dev); 336 struct inet6_dev *idev = in6_dev_get(dev);
337 337
338 (void) ip6_mc_leave_src(sk, mc_lst, idev);
338 if (idev) { 339 if (idev) {
339 (void) ip6_mc_leave_src(sk, mc_lst, idev);
340 __ipv6_dev_mc_dec(idev, &mc_lst->addr); 340 __ipv6_dev_mc_dec(idev, &mc_lst->addr);
341 in6_dev_put(idev); 341 in6_dev_put(idev);
342 } 342 }
343 dev_put(dev); 343 dev_put(dev);
344 } 344 } else
345 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
345 346
346 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 347 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
347 348
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
new file mode 100644
index 000000000000..99d116caecda
--- /dev/null
+++ b/net/ipv6/mip6.c
@@ -0,0 +1,519 @@
1/*
2 * Copyright (C)2003-2006 Helsinki University of Technology
3 * Copyright (C)2003-2006 USAGI/WIDE Project
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19/*
20 * Authors:
21 * Noriaki TAKAMIYA @USAGI
22 * Masahide NAKAMURA @USAGI
23 */
24
25#include <linux/config.h>
26#include <linux/module.h>
27#include <linux/skbuff.h>
28#include <linux/time.h>
29#include <linux/ipv6.h>
30#include <linux/icmpv6.h>
31#include <net/sock.h>
32#include <net/ipv6.h>
33#include <net/ip6_checksum.h>
34#include <net/xfrm.h>
35#include <net/mip6.h>
36
37static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, xfrm_address_t *addr)
38{
39 return x->coaddr;
40}
41
42static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
43{
44 return (n - len + 16) & 0x7;
45}
46
47static inline void *mip6_padn(__u8 *data, __u8 padlen)
48{
49 if (!data)
50 return NULL;
51 if (padlen == 1) {
52 data[0] = MIP6_OPT_PAD_1;
53 } else if (padlen > 1) {
54 data[0] = MIP6_OPT_PAD_N;
55 data[1] = padlen - 2;
56 if (padlen > 2)
57 memset(data+2, 0, data[1]);
58 }
59 return data + padlen;
60}
61
62static inline void mip6_param_prob(struct sk_buff *skb, int code, int pos)
63{
64 icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev);
65}
66
67static int mip6_mh_len(int type)
68{
69 int len = 0;
70
71 switch (type) {
72 case IP6_MH_TYPE_BRR:
73 len = 0;
74 break;
75 case IP6_MH_TYPE_HOTI:
76 case IP6_MH_TYPE_COTI:
77 case IP6_MH_TYPE_BU:
78 case IP6_MH_TYPE_BACK:
79 len = 1;
80 break;
81 case IP6_MH_TYPE_HOT:
82 case IP6_MH_TYPE_COT:
83 case IP6_MH_TYPE_BERROR:
84 len = 2;
85 break;
86 }
87 return len;
88}
89
90int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
91{
92 struct ip6_mh *mh;
93 int mhlen;
94
95 if (!pskb_may_pull(skb, (skb->h.raw - skb->data) + 8) ||
96 !pskb_may_pull(skb, (skb->h.raw - skb->data) + ((skb->h.raw[1] + 1) << 3)))
97 return -1;
98
99 mh = (struct ip6_mh *)skb->h.raw;
100
101 if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
102 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
103 mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
104 mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw);
105 return -1;
106 }
107 mhlen = (mh->ip6mh_hdrlen + 1) << 3;
108
109 if (skb->ip_summed == CHECKSUM_COMPLETE) {
110 skb->ip_summed = CHECKSUM_UNNECESSARY;
111 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
112 &skb->nh.ipv6h->daddr,
113 mhlen, IPPROTO_MH,
114 skb->csum)) {
115 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH hw checksum failed\n");
116 skb->ip_summed = CHECKSUM_NONE;
117 }
118 }
119 if (skb->ip_summed == CHECKSUM_NONE) {
120 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
121 &skb->nh.ipv6h->daddr,
122 mhlen, IPPROTO_MH,
123 skb_checksum(skb, 0, mhlen, 0))) {
124 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH checksum failed "
125 "[" NIP6_FMT " > " NIP6_FMT "]\n",
126 NIP6(skb->nh.ipv6h->saddr),
127 NIP6(skb->nh.ipv6h->daddr));
128 return -1;
129 }
130 skb->ip_summed = CHECKSUM_UNNECESSARY;
131 }
132
133 if (mh->ip6mh_proto != IPPROTO_NONE) {
134 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
135 mh->ip6mh_proto);
136 mip6_param_prob(skb, 0, (&mh->ip6mh_proto) - skb->nh.raw);
137 return -1;
138 }
139
140 return 0;
141}
142
143struct mip6_report_rate_limiter {
144 spinlock_t lock;
145 struct timeval stamp;
146 int iif;
147 struct in6_addr src;
148 struct in6_addr dst;
149};
150
151static struct mip6_report_rate_limiter mip6_report_rl = {
152 .lock = SPIN_LOCK_UNLOCKED
153};
154
155static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
156{
157 struct ipv6hdr *iph = skb->nh.ipv6h;
158 struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
159
160 if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
161 !ipv6_addr_any((struct in6_addr *)x->coaddr))
162 return -ENOENT;
163
164 return destopt->nexthdr;
165}
166
167/* Destination Option Header is inserted.
168 * IP Header's src address is replaced with Home Address Option in
169 * Destination Option Header.
170 */
171static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb)
172{
173 struct ipv6hdr *iph;
174 struct ipv6_destopt_hdr *dstopt;
175 struct ipv6_destopt_hao *hao;
176 u8 nexthdr;
177 int len;
178
179 iph = (struct ipv6hdr *)skb->data;
180 iph->payload_len = htons(skb->len - sizeof(*iph));
181
182 nexthdr = *skb->nh.raw;
183 *skb->nh.raw = IPPROTO_DSTOPTS;
184
185 dstopt = (struct ipv6_destopt_hdr *)skb->h.raw;
186 dstopt->nexthdr = nexthdr;
187
188 hao = mip6_padn((char *)(dstopt + 1),
189 calc_padlen(sizeof(*dstopt), 6));
190
191 hao->type = IPV6_TLV_HAO;
192 hao->length = sizeof(*hao) - 2;
193 BUG_TRAP(hao->length == 16);
194
195 len = ((char *)hao - (char *)dstopt) + sizeof(*hao);
196
197 memcpy(&hao->addr, &iph->saddr, sizeof(hao->addr));
198 memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr));
199
200 BUG_TRAP(len == x->props.header_len);
201 dstopt->hdrlen = (x->props.header_len >> 3) - 1;
202
203 return 0;
204}
205
206static inline int mip6_report_rl_allow(struct timeval *stamp,
207 struct in6_addr *dst,
208 struct in6_addr *src, int iif)
209{
210 int allow = 0;
211
212 spin_lock_bh(&mip6_report_rl.lock);
213 if (mip6_report_rl.stamp.tv_sec != stamp->tv_sec ||
214 mip6_report_rl.stamp.tv_usec != stamp->tv_usec ||
215 mip6_report_rl.iif != iif ||
216 !ipv6_addr_equal(&mip6_report_rl.src, src) ||
217 !ipv6_addr_equal(&mip6_report_rl.dst, dst)) {
218 mip6_report_rl.stamp.tv_sec = stamp->tv_sec;
219 mip6_report_rl.stamp.tv_usec = stamp->tv_usec;
220 mip6_report_rl.iif = iif;
221 ipv6_addr_copy(&mip6_report_rl.src, src);
222 ipv6_addr_copy(&mip6_report_rl.dst, dst);
223 allow = 1;
224 }
225 spin_unlock_bh(&mip6_report_rl.lock);
226 return allow;
227}
228
229static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl)
230{
231 struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
232 struct ipv6_destopt_hao *hao = NULL;
233 struct xfrm_selector sel;
234 int offset;
235 struct timeval stamp;
236 int err = 0;
237
238 if (unlikely(fl->proto == IPPROTO_MH &&
239 fl->fl_mh_type <= IP6_MH_TYPE_MAX))
240 goto out;
241
242 if (likely(opt->dsthao)) {
243 offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
244 if (likely(offset >= 0))
245 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + offset);
246 }
247
248 skb_get_timestamp(skb, &stamp);
249
250 if (!mip6_report_rl_allow(&stamp, &skb->nh.ipv6h->daddr,
251 hao ? &hao->addr : &skb->nh.ipv6h->saddr,
252 opt->iif))
253 goto out;
254
255 memset(&sel, 0, sizeof(sel));
256 memcpy(&sel.daddr, (xfrm_address_t *)&skb->nh.ipv6h->daddr,
257 sizeof(sel.daddr));
258 sel.prefixlen_d = 128;
259 memcpy(&sel.saddr, (xfrm_address_t *)&skb->nh.ipv6h->saddr,
260 sizeof(sel.saddr));
261 sel.prefixlen_s = 128;
262 sel.family = AF_INET6;
263 sel.proto = fl->proto;
264 sel.dport = xfrm_flowi_dport(fl);
265 if (sel.dport)
266 sel.dport_mask = ~((__u16)0);
267 sel.sport = xfrm_flowi_sport(fl);
268 if (sel.sport)
269 sel.sport_mask = ~((__u16)0);
270 sel.ifindex = fl->oif;
271
272 err = km_report(IPPROTO_DSTOPTS, &sel,
273 (hao ? (xfrm_address_t *)&hao->addr : NULL));
274
275 out:
276 return err;
277}
278
279static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
280 u8 **nexthdr)
281{
282 u16 offset = sizeof(struct ipv6hdr);
283 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
284 unsigned int packet_len = skb->tail - skb->nh.raw;
285 int found_rhdr = 0;
286
287 *nexthdr = &skb->nh.ipv6h->nexthdr;
288
289 while (offset + 1 <= packet_len) {
290
291 switch (**nexthdr) {
292 case NEXTHDR_HOP:
293 break;
294 case NEXTHDR_ROUTING:
295 found_rhdr = 1;
296 break;
297 case NEXTHDR_DEST:
298 /*
299 * HAO MUST NOT appear more than once.
300 * XXX: It is better to try to find by the end of
301 * XXX: packet if HAO exists.
302 */
303 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) {
304 LIMIT_NETDEBUG(KERN_WARNING "mip6: hao exists already, override\n");
305 return offset;
306 }
307
308 if (found_rhdr)
309 return offset;
310
311 break;
312 default:
313 return offset;
314 }
315
316 offset += ipv6_optlen(exthdr);
317 *nexthdr = &exthdr->nexthdr;
318 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
319 }
320
321 return offset;
322}
323
324static int mip6_destopt_init_state(struct xfrm_state *x)
325{
326 if (x->id.spi) {
327 printk(KERN_INFO "%s: spi is not 0: %u\n", __FUNCTION__,
328 x->id.spi);
329 return -EINVAL;
330 }
331 if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
332 printk(KERN_INFO "%s: state's mode is not %u: %u\n",
333 __FUNCTION__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
334 return -EINVAL;
335 }
336
337 x->props.header_len = sizeof(struct ipv6_destopt_hdr) +
338 calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) +
339 sizeof(struct ipv6_destopt_hao);
340 BUG_TRAP(x->props.header_len == 24);
341
342 return 0;
343}
344
345/*
346 * Do nothing about destroying since it has no specific operation for
347 * destination options header unlike IPsec protocols.
348 */
349static void mip6_destopt_destroy(struct xfrm_state *x)
350{
351}
352
353static struct xfrm_type mip6_destopt_type =
354{
355 .description = "MIP6DESTOPT",
356 .owner = THIS_MODULE,
357 .proto = IPPROTO_DSTOPTS,
358 .flags = XFRM_TYPE_NON_FRAGMENT,
359 .init_state = mip6_destopt_init_state,
360 .destructor = mip6_destopt_destroy,
361 .input = mip6_destopt_input,
362 .output = mip6_destopt_output,
363 .reject = mip6_destopt_reject,
364 .hdr_offset = mip6_destopt_offset,
365 .local_addr = mip6_xfrm_addr,
366};
367
368static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
369{
370 struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
371
372 if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) &&
373 !ipv6_addr_any((struct in6_addr *)x->coaddr))
374 return -ENOENT;
375
376 return rt2->rt_hdr.nexthdr;
377}
378
379/* Routing Header type 2 is inserted.
380 * IP Header's dst address is replaced with Routing Header's Home Address.
381 */
382static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
383{
384 struct ipv6hdr *iph;
385 struct rt2_hdr *rt2;
386 u8 nexthdr;
387
388 iph = (struct ipv6hdr *)skb->data;
389 iph->payload_len = htons(skb->len - sizeof(*iph));
390
391 nexthdr = *skb->nh.raw;
392 *skb->nh.raw = IPPROTO_ROUTING;
393
394 rt2 = (struct rt2_hdr *)skb->h.raw;
395 rt2->rt_hdr.nexthdr = nexthdr;
396 rt2->rt_hdr.hdrlen = (x->props.header_len >> 3) - 1;
397 rt2->rt_hdr.type = IPV6_SRCRT_TYPE_2;
398 rt2->rt_hdr.segments_left = 1;
399 memset(&rt2->reserved, 0, sizeof(rt2->reserved));
400
401 BUG_TRAP(rt2->rt_hdr.hdrlen == 2);
402
403 memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr));
404 memcpy(&iph->daddr, x->coaddr, sizeof(iph->daddr));
405
406 return 0;
407}
408
409static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
410 u8 **nexthdr)
411{
412 u16 offset = sizeof(struct ipv6hdr);
413 struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1);
414 unsigned int packet_len = skb->tail - skb->nh.raw;
415 int found_rhdr = 0;
416
417 *nexthdr = &skb->nh.ipv6h->nexthdr;
418
419 while (offset + 1 <= packet_len) {
420
421 switch (**nexthdr) {
422 case NEXTHDR_HOP:
423 break;
424 case NEXTHDR_ROUTING:
425 if (offset + 3 <= packet_len) {
426 struct ipv6_rt_hdr *rt;
427 rt = (struct ipv6_rt_hdr *)(skb->nh.raw + offset);
428 if (rt->type != 0)
429 return offset;
430 }
431 found_rhdr = 1;
432 break;
433 case NEXTHDR_DEST:
434 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
435 return offset;
436
437 if (found_rhdr)
438 return offset;
439
440 break;
441 default:
442 return offset;
443 }
444
445 offset += ipv6_optlen(exthdr);
446 *nexthdr = &exthdr->nexthdr;
447 exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
448 }
449
450 return offset;
451}
452
453static int mip6_rthdr_init_state(struct xfrm_state *x)
454{
455 if (x->id.spi) {
456 printk(KERN_INFO "%s: spi is not 0: %u\n", __FUNCTION__,
457 x->id.spi);
458 return -EINVAL;
459 }
460 if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
461 printk(KERN_INFO "%s: state's mode is not %u: %u\n",
462 __FUNCTION__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
463 return -EINVAL;
464 }
465
466 x->props.header_len = sizeof(struct rt2_hdr);
467
468 return 0;
469}
470
471/*
472 * Do nothing about destroying since it has no specific operation for routing
473 * header type 2 unlike IPsec protocols.
474 */
475static void mip6_rthdr_destroy(struct xfrm_state *x)
476{
477}
478
479static struct xfrm_type mip6_rthdr_type =
480{
481 .description = "MIP6RT",
482 .owner = THIS_MODULE,
483 .proto = IPPROTO_ROUTING,
484 .flags = XFRM_TYPE_NON_FRAGMENT,
485 .init_state = mip6_rthdr_init_state,
486 .destructor = mip6_rthdr_destroy,
487 .input = mip6_rthdr_input,
488 .output = mip6_rthdr_output,
489 .hdr_offset = mip6_rthdr_offset,
490 .remote_addr = mip6_xfrm_addr,
491};
492
493int __init mip6_init(void)
494{
495 printk(KERN_INFO "Mobile IPv6\n");
496
497 if (xfrm_register_type(&mip6_destopt_type, AF_INET6) < 0) {
498 printk(KERN_INFO "%s: can't add xfrm type(destopt)\n", __FUNCTION__);
499 goto mip6_destopt_xfrm_fail;
500 }
501 if (xfrm_register_type(&mip6_rthdr_type, AF_INET6) < 0) {
502 printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
503 goto mip6_rthdr_xfrm_fail;
504 }
505 return 0;
506
507 mip6_rthdr_xfrm_fail:
508 xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
509 mip6_destopt_xfrm_fail:
510 return -EAGAIN;
511}
512
513void __exit mip6_fini(void)
514{
515 if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
516 printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
517 if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
518 printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
519}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index dfa20d3be9b6..0304b5fe8d6a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -48,7 +48,6 @@
48#endif 48#endif
49 49
50#include <linux/module.h> 50#include <linux/module.h>
51#include <linux/config.h>
52#include <linux/errno.h> 51#include <linux/errno.h>
53#include <linux/types.h> 52#include <linux/types.h>
54#include <linux/socket.h> 53#include <linux/socket.h>
@@ -63,6 +62,7 @@
63#include <linux/sysctl.h> 62#include <linux/sysctl.h>
64#endif 63#endif
65 64
65#include <linux/if_addr.h>
66#include <linux/if_arp.h> 66#include <linux/if_arp.h>
67#include <linux/ipv6.h> 67#include <linux/ipv6.h>
68#include <linux/icmpv6.h> 68#include <linux/icmpv6.h>
@@ -412,7 +412,8 @@ static void pndisc_destructor(struct pneigh_entry *n)
412 */ 412 */
413 413
414static inline void ndisc_flow_init(struct flowi *fl, u8 type, 414static inline void ndisc_flow_init(struct flowi *fl, u8 type,
415 struct in6_addr *saddr, struct in6_addr *daddr) 415 struct in6_addr *saddr, struct in6_addr *daddr,
416 int oif)
416{ 417{
417 memset(fl, 0, sizeof(*fl)); 418 memset(fl, 0, sizeof(*fl));
418 ipv6_addr_copy(&fl->fl6_src, saddr); 419 ipv6_addr_copy(&fl->fl6_src, saddr);
@@ -420,6 +421,8 @@ static inline void ndisc_flow_init(struct flowi *fl, u8 type,
420 fl->proto = IPPROTO_ICMPV6; 421 fl->proto = IPPROTO_ICMPV6;
421 fl->fl_icmp_type = type; 422 fl->fl_icmp_type = type;
422 fl->fl_icmp_code = 0; 423 fl->fl_icmp_code = 0;
424 fl->oif = oif;
425 security_sk_classify_flow(ndisc_socket->sk, fl);
423} 426}
424 427
425static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, 428static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
@@ -451,7 +454,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
451 src_addr = &tmpaddr; 454 src_addr = &tmpaddr;
452 } 455 }
453 456
454 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr); 457 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr,
458 dev->ifindex);
455 459
456 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); 460 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
457 if (!dst) 461 if (!dst)
@@ -492,7 +496,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
492 msg->icmph.icmp6_unused = 0; 496 msg->icmph.icmp6_unused = 0;
493 msg->icmph.icmp6_router = router; 497 msg->icmph.icmp6_router = router;
494 msg->icmph.icmp6_solicited = solicited; 498 msg->icmph.icmp6_solicited = solicited;
495 msg->icmph.icmp6_override = !!override; 499 msg->icmph.icmp6_override = override;
496 500
497 /* Set the target address. */ 501 /* Set the target address. */
498 ipv6_addr_copy(&msg->target, solicited_addr); 502 ipv6_addr_copy(&msg->target, solicited_addr);
@@ -541,7 +545,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
541 saddr = &addr_buf; 545 saddr = &addr_buf;
542 } 546 }
543 547
544 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr); 548 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr,
549 dev->ifindex);
545 550
546 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); 551 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
547 if (!dst) 552 if (!dst)
@@ -616,7 +621,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
616 int len; 621 int len;
617 int err; 622 int err;
618 623
619 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr); 624 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr,
625 dev->ifindex);
620 626
621 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output); 627 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
622 if (!dst) 628 if (!dst)
@@ -730,8 +736,10 @@ static void ndisc_recv_ns(struct sk_buff *skb)
730 struct inet6_ifaddr *ifp; 736 struct inet6_ifaddr *ifp;
731 struct inet6_dev *idev = NULL; 737 struct inet6_dev *idev = NULL;
732 struct neighbour *neigh; 738 struct neighbour *neigh;
739 struct pneigh_entry *pneigh = NULL;
733 int dad = ipv6_addr_any(saddr); 740 int dad = ipv6_addr_any(saddr);
734 int inc; 741 int inc;
742 int is_router;
735 743
736 if (ipv6_addr_is_multicast(&msg->target)) { 744 if (ipv6_addr_is_multicast(&msg->target)) {
737 ND_PRINTK2(KERN_WARNING 745 ND_PRINTK2(KERN_WARNING
@@ -816,7 +824,9 @@ static void ndisc_recv_ns(struct sk_buff *skb)
816 824
817 if (ipv6_chk_acast_addr(dev, &msg->target) || 825 if (ipv6_chk_acast_addr(dev, &msg->target) ||
818 (idev->cnf.forwarding && 826 (idev->cnf.forwarding &&
819 pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) { 827 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
828 (pneigh = pneigh_lookup(&nd_tbl,
829 &msg->target, dev, 0)) != NULL)) {
820 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && 830 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
821 skb->pkt_type != PACKET_HOST && 831 skb->pkt_type != PACKET_HOST &&
822 inc != 0 && 832 inc != 0 &&
@@ -837,12 +847,14 @@ static void ndisc_recv_ns(struct sk_buff *skb)
837 goto out; 847 goto out;
838 } 848 }
839 849
850 is_router = !!(pneigh ? pneigh->flags & NTF_ROUTER : idev->cnf.forwarding);
851
840 if (dad) { 852 if (dad) {
841 struct in6_addr maddr; 853 struct in6_addr maddr;
842 854
843 ipv6_addr_all_nodes(&maddr); 855 ipv6_addr_all_nodes(&maddr);
844 ndisc_send_na(dev, NULL, &maddr, &msg->target, 856 ndisc_send_na(dev, NULL, &maddr, &msg->target,
845 idev->cnf.forwarding, 0, (ifp != NULL), 1); 857 is_router, 0, (ifp != NULL), 1);
846 goto out; 858 goto out;
847 } 859 }
848 860
@@ -863,7 +875,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
863 NEIGH_UPDATE_F_OVERRIDE); 875 NEIGH_UPDATE_F_OVERRIDE);
864 if (neigh || !dev->hard_header) { 876 if (neigh || !dev->hard_header) {
865 ndisc_send_na(dev, neigh, saddr, &msg->target, 877 ndisc_send_na(dev, neigh, saddr, &msg->target,
866 idev->cnf.forwarding, 878 is_router,
867 1, (ifp != NULL && inc), inc); 879 1, (ifp != NULL && inc), inc);
868 if (neigh) 880 if (neigh)
869 neigh_release(neigh); 881 neigh_release(neigh);
@@ -946,6 +958,20 @@ static void ndisc_recv_na(struct sk_buff *skb)
946 if (neigh->nud_state & NUD_FAILED) 958 if (neigh->nud_state & NUD_FAILED)
947 goto out; 959 goto out;
948 960
961 /*
962 * Don't update the neighbor cache entry on a proxy NA from
963 * ourselves because either the proxied node is off link or it
964 * has already sent a NA to us.
965 */
966 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
967 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
968 pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
969 /* XXX: idev->cnf.prixy_ndp */
970 WARN_ON(skb->dst != NULL &&
971 ((struct rt6_info *)skb->dst)->rt6i_idev);
972 goto out;
973 }
974
949 neigh_update(neigh, lladdr, 975 neigh_update(neigh, lladdr,
950 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE, 976 msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
951 NEIGH_UPDATE_F_WEAK_OVERRIDE| 977 NEIGH_UPDATE_F_WEAK_OVERRIDE|
@@ -960,7 +986,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
960 struct rt6_info *rt; 986 struct rt6_info *rt;
961 rt = rt6_get_dflt_router(saddr, dev); 987 rt = rt6_get_dflt_router(saddr, dev);
962 if (rt) 988 if (rt)
963 ip6_del_rt(rt, NULL, NULL, NULL); 989 ip6_del_rt(rt);
964 } 990 }
965 991
966out: 992out:
@@ -1113,7 +1139,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1113 1139
1114 if (rt && lifetime == 0) { 1140 if (rt && lifetime == 0) {
1115 neigh_clone(neigh); 1141 neigh_clone(neigh);
1116 ip6_del_rt(rt, NULL, NULL, NULL); 1142 ip6_del_rt(rt);
1117 rt = NULL; 1143 rt = NULL;
1118 } 1144 }
1119 1145
@@ -1345,7 +1371,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
1345 1371
1346 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1); 1372 neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
1347 if (neigh) { 1373 if (neigh) {
1348 rt6_redirect(dest, &skb->nh.ipv6h->saddr, neigh, lladdr, 1374 rt6_redirect(dest, &skb->nh.ipv6h->daddr,
1375 &skb->nh.ipv6h->saddr, neigh, lladdr,
1349 on_link); 1376 on_link);
1350 neigh_release(neigh); 1377 neigh_release(neigh);
1351 } 1378 }
@@ -1381,7 +1408,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1381 return; 1408 return;
1382 } 1409 }
1383 1410
1384 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr); 1411 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &skb->nh.ipv6h->saddr,
1412 dev->ifindex);
1385 1413
1386 dst = ip6_route_output(NULL, &fl); 1414 dst = ip6_route_output(NULL, &fl);
1387 if (dst == NULL) 1415 if (dst == NULL)
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 395a417ba955..580b1aba6722 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -87,7 +87,7 @@ unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
87 unsigned int csum = 0; 87 unsigned int csum = 0;
88 88
89 switch (skb->ip_summed) { 89 switch (skb->ip_summed) {
90 case CHECKSUM_HW: 90 case CHECKSUM_COMPLETE:
91 if (hook != NF_IP6_PRE_ROUTING && hook != NF_IP6_LOCAL_IN) 91 if (hook != NF_IP6_PRE_ROUTING && hook != NF_IP6_LOCAL_IN)
92 break; 92 break;
93 if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, 93 if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index eeeb57d4c9c5..ac1dfebde175 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -5,7 +5,7 @@
5# Link order matters here. 5# Link order matters here.
6obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o 6obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
7obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o 7obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
8obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o 8obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
9obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o 9obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
10obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o 10obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
11obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o 11obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index b4b7d441af25..9510c24ca8d2 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -56,15 +56,15 @@ struct ipq_queue_entry {
56 56
57typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long); 57typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long);
58 58
59static unsigned char copy_mode = IPQ_COPY_NONE; 59static unsigned char copy_mode __read_mostly = IPQ_COPY_NONE;
60static unsigned int queue_maxlen = IPQ_QMAX_DEFAULT; 60static unsigned int queue_maxlen __read_mostly = IPQ_QMAX_DEFAULT;
61static DEFINE_RWLOCK(queue_lock); 61static DEFINE_RWLOCK(queue_lock);
62static int peer_pid; 62static int peer_pid __read_mostly;
63static unsigned int copy_range; 63static unsigned int copy_range __read_mostly;
64static unsigned int queue_total; 64static unsigned int queue_total;
65static unsigned int queue_dropped = 0; 65static unsigned int queue_dropped = 0;
66static unsigned int queue_user_dropped = 0; 66static unsigned int queue_user_dropped = 0;
67static struct sock *ipqnl; 67static struct sock *ipqnl __read_mostly;
68static LIST_HEAD(queue_list); 68static LIST_HEAD(queue_list);
69static DEFINE_MUTEX(ipqnl_mutex); 69static DEFINE_MUTEX(ipqnl_mutex);
70 70
@@ -206,9 +206,9 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
206 break; 206 break;
207 207
208 case IPQ_COPY_PACKET: 208 case IPQ_COPY_PACKET:
209 if (entry->skb->ip_summed == CHECKSUM_HW && 209 if ((entry->skb->ip_summed == CHECKSUM_PARTIAL ||
210 (*errp = skb_checksum_help(entry->skb, 210 entry->skb->ip_summed == CHECKSUM_COMPLETE) &&
211 entry->info->outdev == NULL))) { 211 (*errp = skb_checksum_help(entry->skb))) {
212 read_unlock_bh(&queue_lock); 212 read_unlock_bh(&queue_lock);
213 return NULL; 213 return NULL;
214 } 214 }
@@ -505,7 +505,7 @@ ipq_rcv_skb(struct sk_buff *skb)
505 if (type <= IPQM_BASE) 505 if (type <= IPQM_BASE)
506 return; 506 return;
507 507
508 if (security_netlink_recv(skb)) 508 if (security_netlink_recv(skb, CAP_NET_ADMIN))
509 RCV_SKB_FAIL(-EPERM); 509 RCV_SKB_FAIL(-EPERM);
510 510
511 write_lock_bh(&queue_lock); 511 write_lock_bh(&queue_lock);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 2e72f89a7019..4ab368fa0b8f 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -19,13 +19,13 @@
19 */ 19 */
20 20
21#include <linux/capability.h> 21#include <linux/capability.h>
22#include <linux/config.h>
23#include <linux/in.h> 22#include <linux/in.h>
24#include <linux/skbuff.h> 23#include <linux/skbuff.h>
25#include <linux/kmod.h> 24#include <linux/kmod.h>
26#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
28#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/poison.h>
29#include <linux/icmpv6.h> 29#include <linux/icmpv6.h>
30#include <net/ipv6.h> 30#include <net/ipv6.h>
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -70,9 +70,6 @@ do { \
70#define IP_NF_ASSERT(x) 70#define IP_NF_ASSERT(x)
71#endif 71#endif
72 72
73
74#include <linux/netfilter_ipv4/listhelp.h>
75
76#if 0 73#if 0
77/* All the better to debug you with... */ 74/* All the better to debug you with... */
78#define static 75#define static
@@ -220,8 +217,7 @@ ip6t_error(struct sk_buff **pskb,
220 const struct net_device *out, 217 const struct net_device *out,
221 unsigned int hooknum, 218 unsigned int hooknum,
222 const struct xt_target *target, 219 const struct xt_target *target,
223 const void *targinfo, 220 const void *targinfo)
224 void *userinfo)
225{ 221{
226 if (net_ratelimit()) 222 if (net_ratelimit())
227 printk("ip6_tables: error: `%s'\n", (char *)targinfo); 223 printk("ip6_tables: error: `%s'\n", (char *)targinfo);
@@ -258,8 +254,7 @@ ip6t_do_table(struct sk_buff **pskb,
258 unsigned int hook, 254 unsigned int hook,
259 const struct net_device *in, 255 const struct net_device *in,
260 const struct net_device *out, 256 const struct net_device *out,
261 struct xt_table *table, 257 struct xt_table *table)
262 void *userdata)
263{ 258{
264 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 259 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
265 int offset = 0; 260 int offset = 0;
@@ -349,8 +344,7 @@ ip6t_do_table(struct sk_buff **pskb,
349 in, out, 344 in, out,
350 hook, 345 hook,
351 t->u.kernel.target, 346 t->u.kernel.target,
352 t->data, 347 t->data);
353 userdata);
354 348
355#ifdef CONFIG_NETFILTER_DEBUG 349#ifdef CONFIG_NETFILTER_DEBUG
356 if (((struct ip6t_entry *)table_base)->comefrom 350 if (((struct ip6t_entry *)table_base)->comefrom
@@ -377,7 +371,7 @@ ip6t_do_table(struct sk_buff **pskb,
377 } while (!hotdrop); 371 } while (!hotdrop);
378 372
379#ifdef CONFIG_NETFILTER_DEBUG 373#ifdef CONFIG_NETFILTER_DEBUG
380 ((struct ip6t_entry *)table_base)->comefrom = 0xdead57ac; 374 ((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON;
381#endif 375#endif
382 read_unlock_bh(&table->lock); 376 read_unlock_bh(&table->lock);
383 377
@@ -507,8 +501,7 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
507 return 1; 501 return 1;
508 502
509 if (m->u.kernel.match->destroy) 503 if (m->u.kernel.match->destroy)
510 m->u.kernel.match->destroy(m->u.kernel.match, m->data, 504 m->u.kernel.match->destroy(m->u.kernel.match, m->data);
511 m->u.match_size - sizeof(*m));
512 module_put(m->u.kernel.match->me); 505 module_put(m->u.kernel.match->me);
513 return 0; 506 return 0;
514} 507}
@@ -561,7 +554,6 @@ check_match(struct ip6t_entry_match *m,
561 554
562 if (m->u.kernel.match->checkentry 555 if (m->u.kernel.match->checkentry
563 && !m->u.kernel.match->checkentry(name, ipv6, match, m->data, 556 && !m->u.kernel.match->checkentry(name, ipv6, match, m->data,
564 m->u.match_size - sizeof(*m),
565 hookmask)) { 557 hookmask)) {
566 duprintf("ip_tables: check failed for `%s'.\n", 558 duprintf("ip_tables: check failed for `%s'.\n",
567 m->u.kernel.match->name); 559 m->u.kernel.match->name);
@@ -618,12 +610,10 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
618 if (t->u.kernel.target == &ip6t_standard_target) { 610 if (t->u.kernel.target == &ip6t_standard_target) {
619 if (!standard_check(t, size)) { 611 if (!standard_check(t, size)) {
620 ret = -EINVAL; 612 ret = -EINVAL;
621 goto cleanup_matches; 613 goto err;
622 } 614 }
623 } else if (t->u.kernel.target->checkentry 615 } else if (t->u.kernel.target->checkentry
624 && !t->u.kernel.target->checkentry(name, e, target, t->data, 616 && !t->u.kernel.target->checkentry(name, e, target, t->data,
625 t->u.target_size
626 - sizeof(*t),
627 e->comefrom)) { 617 e->comefrom)) {
628 duprintf("ip_tables: check failed for `%s'.\n", 618 duprintf("ip_tables: check failed for `%s'.\n",
629 t->u.kernel.target->name); 619 t->u.kernel.target->name);
@@ -695,8 +685,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
695 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 685 IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
696 t = ip6t_get_target(e); 686 t = ip6t_get_target(e);
697 if (t->u.kernel.target->destroy) 687 if (t->u.kernel.target->destroy)
698 t->u.kernel.target->destroy(t->u.kernel.target, t->data, 688 t->u.kernel.target->destroy(t->u.kernel.target, t->data);
699 t->u.target_size - sizeof(*t));
700 module_put(t->u.kernel.target->me); 689 module_put(t->u.kernel.target->me);
701 return 0; 690 return 0;
702} 691}
@@ -1281,7 +1270,8 @@ int ip6t_register_table(struct xt_table *table,
1281 return ret; 1270 return ret;
1282 } 1271 }
1283 1272
1284 if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1273 ret = xt_register_table(table, &bootstrap, newinfo);
1274 if (ret != 0) {
1285 xt_free_table_info(newinfo); 1275 xt_free_table_info(newinfo);
1286 return ret; 1276 return ret;
1287 } 1277 }
@@ -1351,7 +1341,6 @@ icmp6_checkentry(const char *tablename,
1351 const void *entry, 1341 const void *entry,
1352 const struct xt_match *match, 1342 const struct xt_match *match,
1353 void *matchinfo, 1343 void *matchinfo,
1354 unsigned int matchsize,
1355 unsigned int hook_mask) 1344 unsigned int hook_mask)
1356{ 1345{
1357 const struct ip6t_icmp *icmpinfo = matchinfo; 1346 const struct ip6t_icmp *icmpinfo = matchinfo;
@@ -1397,23 +1386,39 @@ static int __init ip6_tables_init(void)
1397{ 1386{
1398 int ret; 1387 int ret;
1399 1388
1400 xt_proto_init(AF_INET6); 1389 ret = xt_proto_init(AF_INET6);
1390 if (ret < 0)
1391 goto err1;
1401 1392
1402 /* Noone else will be downing sem now, so we won't sleep */ 1393 /* Noone else will be downing sem now, so we won't sleep */
1403 xt_register_target(&ip6t_standard_target); 1394 ret = xt_register_target(&ip6t_standard_target);
1404 xt_register_target(&ip6t_error_target); 1395 if (ret < 0)
1405 xt_register_match(&icmp6_matchstruct); 1396 goto err2;
1397 ret = xt_register_target(&ip6t_error_target);
1398 if (ret < 0)
1399 goto err3;
1400 ret = xt_register_match(&icmp6_matchstruct);
1401 if (ret < 0)
1402 goto err4;
1406 1403
1407 /* Register setsockopt */ 1404 /* Register setsockopt */
1408 ret = nf_register_sockopt(&ip6t_sockopts); 1405 ret = nf_register_sockopt(&ip6t_sockopts);
1409 if (ret < 0) { 1406 if (ret < 0)
1410 duprintf("Unable to register sockopts.\n"); 1407 goto err5;
1411 xt_proto_fini(AF_INET6);
1412 return ret;
1413 }
1414 1408
1415 printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); 1409 printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n");
1416 return 0; 1410 return 0;
1411
1412err5:
1413 xt_unregister_match(&icmp6_matchstruct);
1414err4:
1415 xt_unregister_target(&ip6t_error_target);
1416err3:
1417 xt_unregister_target(&ip6t_standard_target);
1418err2:
1419 xt_proto_fini(AF_INET6);
1420err1:
1421 return ret;
1417} 1422}
1418 1423
1419static void __exit ip6_tables_fini(void) 1424static void __exit ip6_tables_fini(void)
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index b8eff8ee69b1..435750f664dd 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -22,11 +22,10 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
22 const struct net_device *out, 22 const struct net_device *out,
23 unsigned int hooknum, 23 unsigned int hooknum,
24 const struct xt_target *target, 24 const struct xt_target *target,
25 const void *targinfo, void *userinfo) 25 const void *targinfo)
26{ 26{
27 struct ipv6hdr *ip6h; 27 struct ipv6hdr *ip6h;
28 const struct ip6t_HL_info *info = targinfo; 28 const struct ip6t_HL_info *info = targinfo;
29 u_int16_t diffs[2];
30 int new_hl; 29 int new_hl;
31 30
32 if (!skb_make_writable(pskb, (*pskb)->len)) 31 if (!skb_make_writable(pskb, (*pskb)->len))
@@ -53,11 +52,8 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
53 break; 52 break;
54 } 53 }
55 54
56 if (new_hl != ip6h->hop_limit) { 55 if (new_hl != ip6h->hop_limit)
57 diffs[0] = htons(((unsigned)ip6h->hop_limit) << 8) ^ 0xFFFF;
58 ip6h->hop_limit = new_hl; 56 ip6h->hop_limit = new_hl;
59 diffs[1] = htons(((unsigned)ip6h->hop_limit) << 8);
60 }
61 57
62 return IP6T_CONTINUE; 58 return IP6T_CONTINUE;
63} 59}
@@ -66,7 +62,6 @@ static int ip6t_hl_checkentry(const char *tablename,
66 const void *entry, 62 const void *entry,
67 const struct xt_target *target, 63 const struct xt_target *target,
68 void *targinfo, 64 void *targinfo,
69 unsigned int targinfosize,
70 unsigned int hook_mask) 65 unsigned int hook_mask)
71{ 66{
72 struct ip6t_HL_info *info = targinfo; 67 struct ip6t_HL_info *info = targinfo;
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 73c6300109d6..0cf537d30185 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -427,8 +427,7 @@ ip6t_log_target(struct sk_buff **pskb,
427 const struct net_device *out, 427 const struct net_device *out,
428 unsigned int hooknum, 428 unsigned int hooknum,
429 const struct xt_target *target, 429 const struct xt_target *target,
430 const void *targinfo, 430 const void *targinfo)
431 void *userinfo)
432{ 431{
433 const struct ip6t_log_info *loginfo = targinfo; 432 const struct ip6t_log_info *loginfo = targinfo;
434 struct nf_loginfo li; 433 struct nf_loginfo li;
@@ -452,7 +451,6 @@ static int ip6t_log_checkentry(const char *tablename,
452 const void *entry, 451 const void *entry,
453 const struct xt_target *target, 452 const struct xt_target *target,
454 void *targinfo, 453 void *targinfo,
455 unsigned int targinfosize,
456 unsigned int hook_mask) 454 unsigned int hook_mask)
457{ 455{
458 const struct ip6t_log_info *loginfo = targinfo; 456 const struct ip6t_log_info *loginfo = targinfo;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index de1175c27f6d..311eae82feb3 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -15,7 +15,6 @@
15 * 2 of the License, or (at your option) any later version. 15 * 2 of the License, or (at your option) any later version.
16 */ 16 */
17 17
18#include <linux/config.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/skbuff.h> 19#include <linux/skbuff.h>
21#include <linux/icmpv6.h> 20#include <linux/icmpv6.h>
@@ -97,6 +96,7 @@ static void send_reset(struct sk_buff *oldskb)
97 ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr); 96 ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr);
98 fl.fl_ip_sport = otcph.dest; 97 fl.fl_ip_sport = otcph.dest;
99 fl.fl_ip_dport = otcph.source; 98 fl.fl_ip_dport = otcph.source;
99 security_skb_classify_flow(oldskb, &fl);
100 dst = ip6_route_output(NULL, &fl); 100 dst = ip6_route_output(NULL, &fl);
101 if (dst == NULL) 101 if (dst == NULL)
102 return; 102 return;
@@ -180,8 +180,7 @@ static unsigned int reject6_target(struct sk_buff **pskb,
180 const struct net_device *out, 180 const struct net_device *out,
181 unsigned int hooknum, 181 unsigned int hooknum,
182 const struct xt_target *target, 182 const struct xt_target *target,
183 const void *targinfo, 183 const void *targinfo)
184 void *userinfo)
185{ 184{
186 const struct ip6t_reject_info *reject = targinfo; 185 const struct ip6t_reject_info *reject = targinfo;
187 186
@@ -224,7 +223,6 @@ static int check(const char *tablename,
224 const void *entry, 223 const void *entry,
225 const struct xt_target *target, 224 const struct xt_target *target,
226 void *targinfo, 225 void *targinfo,
227 unsigned int targinfosize,
228 unsigned int hook_mask) 226 unsigned int hook_mask)
229{ 227{
230 const struct ip6t_reject_info *rejinfo = targinfo; 228 const struct ip6t_reject_info *rejinfo = targinfo;
@@ -257,9 +255,7 @@ static struct ip6t_target ip6t_reject_reg = {
257 255
258static int __init ip6t_reject_init(void) 256static int __init ip6t_reject_init(void)
259{ 257{
260 if (ip6t_register_target(&ip6t_reject_reg)) 258 return ip6t_register_target(&ip6t_reject_reg);
261 return -EINVAL;
262 return 0;
263} 259}
264 260
265static void __exit ip6t_reject_fini(void) 261static void __exit ip6t_reject_fini(void)
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 2f7bb20c758b..ec1b1608156c 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -102,7 +102,6 @@ checkentry(const char *tablename,
102 const void *entry, 102 const void *entry,
103 const struct xt_match *match, 103 const struct xt_match *match,
104 void *matchinfo, 104 void *matchinfo,
105 unsigned int matchinfosize,
106 unsigned int hook_mask) 105 unsigned int hook_mask)
107{ 106{
108 const struct ip6t_ah *ahinfo = matchinfo; 107 const struct ip6t_ah *ahinfo = matchinfo;
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
deleted file mode 100644
index 9422413d0571..000000000000
--- a/net/ipv6/netfilter/ip6t_dst.c
+++ /dev/null
@@ -1,220 +0,0 @@
1/* Kernel module to match Hop-by-Hop and Destination parameters. */
2
3/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/module.h>
11#include <linux/skbuff.h>
12#include <linux/ipv6.h>
13#include <linux/types.h>
14#include <net/checksum.h>
15#include <net/ipv6.h>
16
17#include <asm/byteorder.h>
18
19#include <linux/netfilter_ipv6/ip6_tables.h>
20#include <linux/netfilter_ipv6/ip6t_opts.h>
21
22#define HOPBYHOP 0
23
24MODULE_LICENSE("GPL");
25#if HOPBYHOP
26MODULE_DESCRIPTION("IPv6 HbH match");
27#else
28MODULE_DESCRIPTION("IPv6 DST match");
29#endif
30MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
31
32#if 0
33#define DEBUGP printk
34#else
35#define DEBUGP(format, args...)
36#endif
37
38/*
39 * (Type & 0xC0) >> 6
40 * 0 -> ignorable
41 * 1 -> must drop the packet
42 * 2 -> send ICMP PARM PROB regardless and drop packet
43 * 3 -> Send ICMP if not a multicast address and drop packet
44 * (Type & 0x20) >> 5
45 * 0 -> invariant
46 * 1 -> can change the routing
47 * (Type & 0x1F) Type
48 * 0 -> Pad1 (only 1 byte!)
49 * 1 -> PadN LENGTH info (total length = length + 2)
50 * C0 | 2 -> JUMBO 4 x x x x ( xxxx > 64k )
51 * 5 -> RTALERT 2 x x
52 */
53
54static int
55match(const struct sk_buff *skb,
56 const struct net_device *in,
57 const struct net_device *out,
58 const struct xt_match *match,
59 const void *matchinfo,
60 int offset,
61 unsigned int protoff,
62 int *hotdrop)
63{
64 struct ipv6_opt_hdr _optsh, *oh;
65 const struct ip6t_opts *optinfo = matchinfo;
66 unsigned int temp;
67 unsigned int ptr;
68 unsigned int hdrlen = 0;
69 unsigned int ret = 0;
70 u8 _opttype, *tp = NULL;
71 u8 _optlen, *lp = NULL;
72 unsigned int optlen;
73
74#if HOPBYHOP
75 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
76#else
77 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
78#endif
79 return 0;
80
81 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
82 if (oh == NULL) {
83 *hotdrop = 1;
84 return 0;
85 }
86
87 hdrlen = ipv6_optlen(oh);
88 if (skb->len - ptr < hdrlen) {
89 /* Packet smaller than it's length field */
90 return 0;
91 }
92
93 DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
94
95 DEBUGP("len %02X %04X %02X ",
96 optinfo->hdrlen, hdrlen,
97 (!(optinfo->flags & IP6T_OPTS_LEN) ||
98 ((optinfo->hdrlen == hdrlen) ^
99 !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
100
101 ret = (oh != NULL) &&
102 (!(optinfo->flags & IP6T_OPTS_LEN) ||
103 ((optinfo->hdrlen == hdrlen) ^
104 !!(optinfo->invflags & IP6T_OPTS_INV_LEN)));
105
106 ptr += 2;
107 hdrlen -= 2;
108 if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
109 return ret;
110 } else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
111 DEBUGP("Not strict - not implemented");
112 } else {
113 DEBUGP("Strict ");
114 DEBUGP("#%d ", optinfo->optsnr);
115 for (temp = 0; temp < optinfo->optsnr; temp++) {
116 /* type field exists ? */
117 if (hdrlen < 1)
118 break;
119 tp = skb_header_pointer(skb, ptr, sizeof(_opttype),
120 &_opttype);
121 if (tp == NULL)
122 break;
123
124 /* Type check */
125 if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
126 DEBUGP("Tbad %02X %02X\n",
127 *tp,
128 (optinfo->opts[temp] & 0xFF00) >> 8);
129 return 0;
130 } else {
131 DEBUGP("Tok ");
132 }
133 /* Length check */
134 if (*tp) {
135 u16 spec_len;
136
137 /* length field exists ? */
138 if (hdrlen < 2)
139 break;
140 lp = skb_header_pointer(skb, ptr + 1,
141 sizeof(_optlen),
142 &_optlen);
143 if (lp == NULL)
144 break;
145 spec_len = optinfo->opts[temp] & 0x00FF;
146
147 if (spec_len != 0x00FF && spec_len != *lp) {
148 DEBUGP("Lbad %02X %04X\n", *lp,
149 spec_len);
150 return 0;
151 }
152 DEBUGP("Lok ");
153 optlen = *lp + 2;
154 } else {
155 DEBUGP("Pad1\n");
156 optlen = 1;
157 }
158
159 /* Step to the next */
160 DEBUGP("len%04X \n", optlen);
161
162 if ((ptr > skb->len - optlen || hdrlen < optlen) &&
163 (temp < optinfo->optsnr - 1)) {
164 DEBUGP("new pointer is too large! \n");
165 break;
166 }
167 ptr += optlen;
168 hdrlen -= optlen;
169 }
170 if (temp == optinfo->optsnr)
171 return ret;
172 else
173 return 0;
174 }
175
176 return 0;
177}
178
179/* Called when user tries to insert an entry of this type. */
180static int
181checkentry(const char *tablename,
182 const void *info,
183 const struct xt_match *match,
184 void *matchinfo,
185 unsigned int matchinfosize,
186 unsigned int hook_mask)
187{
188 const struct ip6t_opts *optsinfo = matchinfo;
189
190 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
191 DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
192 return 0;
193 }
194 return 1;
195}
196
197static struct ip6t_match opts_match = {
198#if HOPBYHOP
199 .name = "hbh",
200#else
201 .name = "dst",
202#endif
203 .match = match,
204 .matchsize = sizeof(struct ip6t_opts),
205 .checkentry = checkentry,
206 .me = THIS_MODULE,
207};
208
209static int __init ip6t_dst_init(void)
210{
211 return ip6t_register_match(&opts_match);
212}
213
214static void __exit ip6t_dst_fini(void)
215{
216 ip6t_unregister_match(&opts_match);
217}
218
219module_init(ip6t_dst_init);
220module_exit(ip6t_dst_fini);
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 06768c84bd31..78d9c8b9e28a 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -119,7 +119,6 @@ checkentry(const char *tablename,
119 const void *ip, 119 const void *ip,
120 const struct xt_match *match, 120 const struct xt_match *match,
121 void *matchinfo, 121 void *matchinfo,
122 unsigned int matchinfosize,
123 unsigned int hook_mask) 122 unsigned int hook_mask)
124{ 123{
125 const struct ip6t_frag *fraginfo = matchinfo; 124 const struct ip6t_frag *fraginfo = matchinfo;
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 374f1be85c0d..d32a205e3af2 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -19,15 +19,10 @@
19#include <linux/netfilter_ipv6/ip6_tables.h> 19#include <linux/netfilter_ipv6/ip6_tables.h>
20#include <linux/netfilter_ipv6/ip6t_opts.h> 20#include <linux/netfilter_ipv6/ip6t_opts.h>
21 21
22#define HOPBYHOP 1
23
24MODULE_LICENSE("GPL"); 22MODULE_LICENSE("GPL");
25#if HOPBYHOP 23MODULE_DESCRIPTION("IPv6 opts match");
26MODULE_DESCRIPTION("IPv6 HbH match");
27#else
28MODULE_DESCRIPTION("IPv6 DST match");
29#endif
30MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 24MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
25MODULE_ALIAS("ip6t_dst");
31 26
32#if 0 27#if 0
33#define DEBUGP printk 28#define DEBUGP printk
@@ -71,11 +66,7 @@ match(const struct sk_buff *skb,
71 u8 _optlen, *lp = NULL; 66 u8 _optlen, *lp = NULL;
72 unsigned int optlen; 67 unsigned int optlen;
73 68
74#if HOPBYHOP 69 if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0)
75 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
76#else
77 if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
78#endif
79 return 0; 70 return 0;
80 71
81 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); 72 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
@@ -182,7 +173,6 @@ checkentry(const char *tablename,
182 const void *entry, 173 const void *entry,
183 const struct xt_match *match, 174 const struct xt_match *match,
184 void *matchinfo, 175 void *matchinfo,
185 unsigned int matchinfosize,
186 unsigned int hook_mask) 176 unsigned int hook_mask)
187{ 177{
188 const struct ip6t_opts *optsinfo = matchinfo; 178 const struct ip6t_opts *optsinfo = matchinfo;
@@ -194,26 +184,35 @@ checkentry(const char *tablename,
194 return 1; 184 return 1;
195} 185}
196 186
197static struct ip6t_match opts_match = { 187static struct xt_match opts_match[] = {
198#if HOPBYHOP 188 {
199 .name = "hbh", 189 .name = "hbh",
200#else 190 .family = AF_INET6,
201 .name = "dst", 191 .match = match,
202#endif 192 .matchsize = sizeof(struct ip6t_opts),
203 .match = match, 193 .checkentry = checkentry,
204 .matchsize = sizeof(struct ip6t_opts), 194 .me = THIS_MODULE,
205 .checkentry = checkentry, 195 .data = NEXTHDR_HOP,
206 .me = THIS_MODULE, 196 },
197 {
198 .name = "dst",
199 .family = AF_INET6,
200 .match = match,
201 .matchsize = sizeof(struct ip6t_opts),
202 .checkentry = checkentry,
203 .me = THIS_MODULE,
204 .data = NEXTHDR_DEST,
205 },
207}; 206};
208 207
209static int __init ip6t_hbh_init(void) 208static int __init ip6t_hbh_init(void)
210{ 209{
211 return ip6t_register_match(&opts_match); 210 return xt_register_matches(opts_match, ARRAY_SIZE(opts_match));
212} 211}
213 212
214static void __exit ip6t_hbh_fini(void) 213static void __exit ip6t_hbh_fini(void)
215{ 214{
216 ip6t_unregister_match(&opts_match); 215 xt_unregister_matches(opts_match, ARRAY_SIZE(opts_match));
217} 216}
218 217
219module_init(ip6t_hbh_init); 218module_init(ip6t_hbh_init);
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 9375eeb1369f..3093c398002f 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -128,7 +128,6 @@ ipv6header_checkentry(const char *tablename,
128 const void *ip, 128 const void *ip,
129 const struct xt_match *match, 129 const struct xt_match *match,
130 void *matchinfo, 130 void *matchinfo,
131 unsigned int matchsize,
132 unsigned int hook_mask) 131 unsigned int hook_mask)
133{ 132{
134 const struct ip6t_ipv6header_info *info = matchinfo; 133 const struct ip6t_ipv6header_info *info = matchinfo;
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 5d047990cd44..4eb9bbc4ebc3 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -57,7 +57,6 @@ checkentry(const char *tablename,
57 const void *ip, 57 const void *ip,
58 const struct xt_match *match, 58 const struct xt_match *match,
59 void *matchinfo, 59 void *matchinfo,
60 unsigned int matchsize,
61 unsigned int hook_mask) 60 unsigned int hook_mask)
62{ 61{
63 const struct ip6t_owner_info *info = matchinfo; 62 const struct ip6t_owner_info *info = matchinfo;
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index fbb0184a41d8..bcb2e168a5bc 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -197,7 +197,6 @@ checkentry(const char *tablename,
197 const void *entry, 197 const void *entry,
198 const struct xt_match *match, 198 const struct xt_match *match,
199 void *matchinfo, 199 void *matchinfo,
200 unsigned int matchinfosize,
201 unsigned int hook_mask) 200 unsigned int hook_mask)
202{ 201{
203 const struct ip6t_rt *rtinfo = matchinfo; 202 const struct ip6t_rt *rtinfo = matchinfo;
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 60976c0c58e8..2fc07c74decf 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -108,7 +108,7 @@ ip6t_hook(unsigned int hook,
108 const struct net_device *out, 108 const struct net_device *out,
109 int (*okfn)(struct sk_buff *)) 109 int (*okfn)(struct sk_buff *))
110{ 110{
111 return ip6t_do_table(pskb, hook, in, out, &packet_filter, NULL); 111 return ip6t_do_table(pskb, hook, in, out, &packet_filter);
112} 112}
113 113
114static unsigned int 114static unsigned int
@@ -128,7 +128,7 @@ ip6t_local_out_hook(unsigned int hook,
128 } 128 }
129#endif 129#endif
130 130
131 return ip6t_do_table(pskb, hook, in, out, &packet_filter, NULL); 131 return ip6t_do_table(pskb, hook, in, out, &packet_filter);
132} 132}
133 133
134static struct nf_hook_ops ip6t_ops[] = { 134static struct nf_hook_ops ip6t_ops[] = {
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 03a13eab1dae..386ea260e767 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -138,7 +138,7 @@ ip6t_route_hook(unsigned int hook,
138 const struct net_device *out, 138 const struct net_device *out,
139 int (*okfn)(struct sk_buff *)) 139 int (*okfn)(struct sk_buff *))
140{ 140{
141 return ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL); 141 return ip6t_do_table(pskb, hook, in, out, &packet_mangler);
142} 142}
143 143
144static unsigned int 144static unsigned int
@@ -174,18 +174,14 @@ ip6t_local_hook(unsigned int hook,
174 /* flowlabel and prio (includes version, which shouldn't change either */ 174 /* flowlabel and prio (includes version, which shouldn't change either */
175 flowlabel = *((u_int32_t *) (*pskb)->nh.ipv6h); 175 flowlabel = *((u_int32_t *) (*pskb)->nh.ipv6h);
176 176
177 ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL); 177 ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler);
178 178
179 if (ret != NF_DROP && ret != NF_STOLEN 179 if (ret != NF_DROP && ret != NF_STOLEN
180 && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr)) 180 && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr))
181 || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr)) 181 || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr))
182 || (*pskb)->nfmark != nfmark 182 || (*pskb)->nfmark != nfmark
183 || (*pskb)->nh.ipv6h->hop_limit != hop_limit)) { 183 || (*pskb)->nh.ipv6h->hop_limit != hop_limit))
184 184 return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP;
185 /* something which could affect routing has changed */
186
187 DEBUGP("ip6table_mangle: we'd need to re-route a packet\n");
188 }
189 185
190 return ret; 186 return ret;
191} 187}
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 61a7c58e99f8..b4154da575c0 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -122,7 +122,7 @@ ip6t_hook(unsigned int hook,
122 const struct net_device *out, 122 const struct net_device *out,
123 int (*okfn)(struct sk_buff *)) 123 int (*okfn)(struct sk_buff *))
124{ 124{
125 return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL); 125 return ip6t_do_table(pskb, hook, in, out, &packet_raw);
126} 126}
127 127
128static struct nf_hook_ops ip6t_ops[] = { 128static struct nf_hook_ops ip6t_ops[] = {
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2a71c3b669f1..e5e53fff9e38 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -20,7 +20,6 @@
20 * structures. 20 * structures.
21 */ 21 */
22 22
23#include <linux/config.h>
24#include <linux/types.h> 23#include <linux/types.h>
25#include <linux/ipv6.h> 24#include <linux/ipv6.h>
26#include <linux/in6.h> 25#include <linux/in6.h>
@@ -336,7 +335,7 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = {
336/* From nf_conntrack_proto_icmpv6.c */ 335/* From nf_conntrack_proto_icmpv6.c */
337extern unsigned int nf_ct_icmpv6_timeout; 336extern unsigned int nf_ct_icmpv6_timeout;
338 337
339/* From nf_conntrack_frag6.c */ 338/* From nf_conntrack_reasm.c */
340extern unsigned int nf_ct_frag6_timeout; 339extern unsigned int nf_ct_frag6_timeout;
341extern unsigned int nf_ct_frag6_low_thresh; 340extern unsigned int nf_ct_frag6_low_thresh;
342extern unsigned int nf_ct_frag6_high_thresh; 341extern unsigned int nf_ct_frag6_high_thresh;
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index ef18a7b7014b..34d447208ffd 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -33,7 +33,7 @@
33#include <net/netfilter/nf_conntrack_core.h> 33#include <net/netfilter/nf_conntrack_core.h>
34#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 34#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
35 35
36unsigned long nf_ct_icmpv6_timeout = 30*HZ; 36unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
37 37
38#if 0 38#if 0
39#define DEBUGP printk 39#define DEBUGP printk
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c32a029e43f0..bf93c1ea6be9 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -14,7 +14,6 @@
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 */ 15 */
16 16
17#include <linux/config.h>
18#include <linux/errno.h> 17#include <linux/errno.h>
19#include <linux/types.h> 18#include <linux/types.h>
20#include <linux/string.h> 19#include <linux/string.h>
@@ -55,9 +54,9 @@
55#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */ 54#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
56#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT 55#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
57 56
58unsigned int nf_ct_frag6_high_thresh = 256*1024; 57unsigned int nf_ct_frag6_high_thresh __read_mostly = 256*1024;
59unsigned int nf_ct_frag6_low_thresh = 192*1024; 58unsigned int nf_ct_frag6_low_thresh __read_mostly = 192*1024;
60unsigned long nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT; 59unsigned long nf_ct_frag6_timeout __read_mostly = IPV6_FRAG_TIMEOUT;
61 60
62struct nf_ct_frag6_skb_cb 61struct nf_ct_frag6_skb_cb
63{ 62{
@@ -409,7 +408,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
409 return -1; 408 return -1;
410 } 409 }
411 410
412 if (skb->ip_summed == CHECKSUM_HW) 411 if (skb->ip_summed == CHECKSUM_COMPLETE)
413 skb->csum = csum_sub(skb->csum, 412 skb->csum = csum_sub(skb->csum,
414 csum_partial(skb->nh.raw, 413 csum_partial(skb->nh.raw,
415 (u8*)(fhdr + 1) - skb->nh.raw, 414 (u8*)(fhdr + 1) - skb->nh.raw,
@@ -641,7 +640,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
641 head->len += fp->len; 640 head->len += fp->len;
642 if (head->ip_summed != fp->ip_summed) 641 if (head->ip_summed != fp->ip_summed)
643 head->ip_summed = CHECKSUM_NONE; 642 head->ip_summed = CHECKSUM_NONE;
644 else if (head->ip_summed == CHECKSUM_HW) 643 else if (head->ip_summed == CHECKSUM_COMPLETE)
645 head->csum = csum_add(head->csum, fp->csum); 644 head->csum = csum_add(head->csum, fp->csum);
646 head->truesize += fp->truesize; 645 head->truesize += fp->truesize;
647 atomic_sub(fp->truesize, &nf_ct_frag6_mem); 646 atomic_sub(fp->truesize, &nf_ct_frag6_mem);
@@ -653,7 +652,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
653 head->nh.ipv6h->payload_len = htons(payload_len); 652 head->nh.ipv6h->payload_len = htons(payload_len);
654 653
655 /* Yes, and fold redundant checksum back. 8) */ 654 /* Yes, and fold redundant checksum back. 8) */
656 if (head->ip_summed == CHECKSUM_HW) 655 if (head->ip_summed == CHECKSUM_COMPLETE)
657 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); 656 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
658 657
659 fq->fragments = NULL; 658 fq->fragments = NULL;
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 779ddf77f4d4..efee7a6301a8 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -17,7 +17,6 @@
17 * as published by the Free Software Foundation; either version 17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version. 18 * 2 of the License, or (at your option) any later version.
19 */ 19 */
20#include <linux/config.h>
21#include <linux/sched.h> 20#include <linux/sched.h>
22#include <linux/socket.h> 21#include <linux/socket.h>
23#include <linux/net.h> 22#include <linux/net.h>
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index fa1ce0ae123e..d09329ca3267 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -50,6 +50,9 @@
50#include <net/udp.h> 50#include <net/udp.h>
51#include <net/inet_common.h> 51#include <net/inet_common.h>
52#include <net/tcp_states.h> 52#include <net/tcp_states.h>
53#ifdef CONFIG_IPV6_MIP6
54#include <net/mip6.h>
55#endif
53 56
54#include <net/rawv6.h> 57#include <net/rawv6.h>
55#include <net/xfrm.h> 58#include <net/xfrm.h>
@@ -169,8 +172,32 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
169 sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); 172 sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
170 173
171 while (sk) { 174 while (sk) {
175 int filtered;
176
172 delivered = 1; 177 delivered = 1;
173 if (nexthdr != IPPROTO_ICMPV6 || !icmpv6_filter(sk, skb)) { 178 switch (nexthdr) {
179 case IPPROTO_ICMPV6:
180 filtered = icmpv6_filter(sk, skb);
181 break;
182#ifdef CONFIG_IPV6_MIP6
183 case IPPROTO_MH:
184 /* XXX: To validate MH only once for each packet,
185 * this is placed here. It should be after checking
186 * xfrm policy, however it doesn't. The checking xfrm
187 * policy is placed in rawv6_rcv() because it is
188 * required for each socket.
189 */
190 filtered = mip6_mh_filter(sk, skb);
191 break;
192#endif
193 default:
194 filtered = 0;
195 break;
196 }
197
198 if (filtered < 0)
199 break;
200 if (filtered == 0) {
174 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC); 201 struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
175 202
176 /* Not releasing hash table! */ 203 /* Not releasing hash table! */
@@ -334,7 +361,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
334 if (!rp->checksum) 361 if (!rp->checksum)
335 skb->ip_summed = CHECKSUM_UNNECESSARY; 362 skb->ip_summed = CHECKSUM_UNNECESSARY;
336 363
337 if (skb->ip_summed == CHECKSUM_HW) { 364 if (skb->ip_summed == CHECKSUM_COMPLETE) {
338 skb_postpull_rcsum(skb, skb->nh.raw, 365 skb_postpull_rcsum(skb, skb->nh.raw,
339 skb->h.raw - skb->nh.raw); 366 skb->h.raw - skb->nh.raw);
340 if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr, 367 if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr,
@@ -411,6 +438,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
411 /* Copy the address. */ 438 /* Copy the address. */
412 if (sin6) { 439 if (sin6) {
413 sin6->sin6_family = AF_INET6; 440 sin6->sin6_family = AF_INET6;
441 sin6->sin6_port = 0;
414 ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr); 442 ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
415 sin6->sin6_flowinfo = 0; 443 sin6->sin6_flowinfo = 0;
416 sin6->sin6_scope_id = 0; 444 sin6->sin6_scope_id = 0;
@@ -581,6 +609,9 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
581 struct iovec *iov; 609 struct iovec *iov;
582 u8 __user *type = NULL; 610 u8 __user *type = NULL;
583 u8 __user *code = NULL; 611 u8 __user *code = NULL;
612#ifdef CONFIG_IPV6_MIP6
613 u8 len = 0;
614#endif
584 int probed = 0; 615 int probed = 0;
585 int i; 616 int i;
586 617
@@ -612,6 +643,20 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
612 probed = 1; 643 probed = 1;
613 } 644 }
614 break; 645 break;
646#ifdef CONFIG_IPV6_MIP6
647 case IPPROTO_MH:
648 if (iov->iov_base && iov->iov_len < 1)
649 break;
650 /* check if type field is readable or not. */
651 if (iov->iov_len > 2 - len) {
652 u8 __user *p = iov->iov_base;
653 get_user(fl->fl_mh_type, &p[2 - len]);
654 probed = 1;
655 } else
656 len += iov->iov_len;
657
658 break;
659#endif
615 default: 660 default:
616 probed = 1; 661 probed = 1;
617 break; 662 break;
@@ -758,6 +803,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
758 803
759 if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) 804 if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
760 fl.oif = np->mcast_oif; 805 fl.oif = np->mcast_oif;
806 security_sk_classify_flow(sk, &fl);
761 807
762 err = ip6_dst_lookup(sk, &dst, &fl); 808 err = ip6_dst_lookup(sk, &dst, &fl);
763 if (err) 809 if (err)
@@ -780,7 +826,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
780 } 826 }
781 827
782 if (tclass < 0) { 828 if (tclass < 0) {
783 tclass = np->cork.tclass; 829 tclass = np->tclass;
784 if (tclass < 0) 830 if (tclass < 0)
785 tclass = 0; 831 tclass = 0;
786 } 832 }
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index eef985e010ea..f39bbedd1327 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -28,7 +28,6 @@
28 * YOSHIFUJI,H. @USAGI Always remove fragment header to 28 * YOSHIFUJI,H. @USAGI Always remove fragment header to
29 * calculate ICV correctly. 29 * calculate ICV correctly.
30 */ 30 */
31#include <linux/config.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/string.h> 33#include <linux/string.h>
@@ -54,10 +53,10 @@
54#include <net/ndisc.h> 53#include <net/ndisc.h>
55#include <net/addrconf.h> 54#include <net/addrconf.h>
56 55
57int sysctl_ip6frag_high_thresh = 256*1024; 56int sysctl_ip6frag_high_thresh __read_mostly = 256*1024;
58int sysctl_ip6frag_low_thresh = 192*1024; 57int sysctl_ip6frag_low_thresh __read_mostly = 192*1024;
59 58
60int sysctl_ip6frag_time = IPV6_FRAG_TIMEOUT; 59int sysctl_ip6frag_time __read_mostly = IPV6_FRAG_TIMEOUT;
61 60
62struct ip6frag_skb_cb 61struct ip6frag_skb_cb
63{ 62{
@@ -153,7 +152,7 @@ static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr,
153} 152}
154 153
155static struct timer_list ip6_frag_secret_timer; 154static struct timer_list ip6_frag_secret_timer;
156int sysctl_ip6frag_secret_interval = 10 * 60 * HZ; 155int sysctl_ip6frag_secret_interval __read_mostly = 10 * 60 * HZ;
157 156
158static void ip6_frag_secret_rebuild(unsigned long dummy) 157static void ip6_frag_secret_rebuild(unsigned long dummy)
159{ 158{
@@ -434,7 +433,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
434 return; 433 return;
435 } 434 }
436 435
437 if (skb->ip_summed == CHECKSUM_HW) 436 if (skb->ip_summed == CHECKSUM_COMPLETE)
438 skb->csum = csum_sub(skb->csum, 437 skb->csum = csum_sub(skb->csum,
439 csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0)); 438 csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0));
440 439
@@ -648,7 +647,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
648 head->len += fp->len; 647 head->len += fp->len;
649 if (head->ip_summed != fp->ip_summed) 648 if (head->ip_summed != fp->ip_summed)
650 head->ip_summed = CHECKSUM_NONE; 649 head->ip_summed = CHECKSUM_NONE;
651 else if (head->ip_summed == CHECKSUM_HW) 650 else if (head->ip_summed == CHECKSUM_COMPLETE)
652 head->csum = csum_add(head->csum, fp->csum); 651 head->csum = csum_add(head->csum, fp->csum);
653 head->truesize += fp->truesize; 652 head->truesize += fp->truesize;
654 atomic_sub(fp->truesize, &ip6_frag_mem); 653 atomic_sub(fp->truesize, &ip6_frag_mem);
@@ -663,7 +662,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
663 *skb_in = head; 662 *skb_in = head;
664 663
665 /* Yes, and fold redundant checksum back. 8) */ 664 /* Yes, and fold redundant checksum back. 8) */
666 if (head->ip_summed == CHECKSUM_HW) 665 if (head->ip_summed == CHECKSUM_COMPLETE)
667 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); 666 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
668 667
669 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 668 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8a777932786d..d6b4b4f48d18 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -22,10 +22,11 @@
22 * routers in REACHABLE, STALE, DELAY or PROBE states). 22 * routers in REACHABLE, STALE, DELAY or PROBE states).
23 * - always select the same router if it is (probably) 23 * - always select the same router if it is (probably)
24 * reachable. otherwise, round-robin the list. 24 * reachable. otherwise, round-robin the list.
25 * Ville Nuorvala
26 * Fixed routing subtrees.
25 */ 27 */
26 28
27#include <linux/capability.h> 29#include <linux/capability.h>
28#include <linux/config.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
30#include <linux/types.h> 31#include <linux/types.h>
31#include <linux/times.h> 32#include <linux/times.h>
@@ -36,7 +37,6 @@
36#include <linux/netdevice.h> 37#include <linux/netdevice.h>
37#include <linux/in6.h> 38#include <linux/in6.h>
38#include <linux/init.h> 39#include <linux/init.h>
39#include <linux/netlink.h>
40#include <linux/if_arp.h> 40#include <linux/if_arp.h>
41 41
42#ifdef CONFIG_PROC_FS 42#ifdef CONFIG_PROC_FS
@@ -54,6 +54,8 @@
54#include <linux/rtnetlink.h> 54#include <linux/rtnetlink.h>
55#include <net/dst.h> 55#include <net/dst.h>
56#include <net/xfrm.h> 56#include <net/xfrm.h>
57#include <net/netevent.h>
58#include <net/netlink.h>
57 59
58#include <asm/uaccess.h> 60#include <asm/uaccess.h>
59 61
@@ -74,9 +76,6 @@
74 76
75#define CLONE_OFFLINK_ROUTE 0 77#define CLONE_OFFLINK_ROUTE 0
76 78
77#define RT6_SELECT_F_IFACE 0x1
78#define RT6_SELECT_F_REACHABLE 0x2
79
80static int ip6_rt_max_size = 4096; 79static int ip6_rt_max_size = 4096;
81static int ip6_rt_gc_min_interval = HZ / 2; 80static int ip6_rt_gc_min_interval = HZ / 2;
82static int ip6_rt_gc_timeout = 60*HZ; 81static int ip6_rt_gc_timeout = 60*HZ;
@@ -140,15 +139,49 @@ struct rt6_info ip6_null_entry = {
140 .rt6i_ref = ATOMIC_INIT(1), 139 .rt6i_ref = ATOMIC_INIT(1),
141}; 140};
142 141
143struct fib6_node ip6_routing_table = { 142#ifdef CONFIG_IPV6_MULTIPLE_TABLES
144 .leaf = &ip6_null_entry,
145 .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
146};
147 143
148/* Protects all the ip6 fib */ 144struct rt6_info ip6_prohibit_entry = {
145 .u = {
146 .dst = {
147 .__refcnt = ATOMIC_INIT(1),
148 .__use = 1,
149 .dev = &loopback_dev,
150 .obsolete = -1,
151 .error = -EACCES,
152 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
153 .input = ip6_pkt_discard,
154 .output = ip6_pkt_discard_out,
155 .ops = &ip6_dst_ops,
156 .path = (struct dst_entry*)&ip6_prohibit_entry,
157 }
158 },
159 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
160 .rt6i_metric = ~(u32) 0,
161 .rt6i_ref = ATOMIC_INIT(1),
162};
149 163
150DEFINE_RWLOCK(rt6_lock); 164struct rt6_info ip6_blk_hole_entry = {
165 .u = {
166 .dst = {
167 .__refcnt = ATOMIC_INIT(1),
168 .__use = 1,
169 .dev = &loopback_dev,
170 .obsolete = -1,
171 .error = -EINVAL,
172 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
173 .input = ip6_pkt_discard,
174 .output = ip6_pkt_discard_out,
175 .ops = &ip6_dst_ops,
176 .path = (struct dst_entry*)&ip6_blk_hole_entry,
177 }
178 },
179 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
180 .rt6i_metric = ~(u32) 0,
181 .rt6i_ref = ATOMIC_INIT(1),
182};
151 183
184#endif
152 185
153/* allocate dst with ip6_dst_ops */ 186/* allocate dst with ip6_dst_ops */
154static __inline__ struct rt6_info *ip6_dst_alloc(void) 187static __inline__ struct rt6_info *ip6_dst_alloc(void)
@@ -188,8 +221,14 @@ static __inline__ int rt6_check_expired(const struct rt6_info *rt)
188 time_after(jiffies, rt->rt6i_expires)); 221 time_after(jiffies, rt->rt6i_expires));
189} 222}
190 223
224static inline int rt6_need_strict(struct in6_addr *daddr)
225{
226 return (ipv6_addr_type(daddr) &
227 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
228}
229
191/* 230/*
192 * Route lookup. Any rt6_lock is implied. 231 * Route lookup. Any table->tb6_lock is implied.
193 */ 232 */
194 233
195static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, 234static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt,
@@ -298,7 +337,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
298 int m, n; 337 int m, n;
299 338
300 m = rt6_check_dev(rt, oif); 339 m = rt6_check_dev(rt, oif);
301 if (!m && (strict & RT6_SELECT_F_IFACE)) 340 if (!m && (strict & RT6_LOOKUP_F_IFACE))
302 return -1; 341 return -1;
303#ifdef CONFIG_IPV6_ROUTER_PREF 342#ifdef CONFIG_IPV6_ROUTER_PREF
304 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; 343 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
@@ -306,7 +345,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
306 n = rt6_check_neigh(rt); 345 n = rt6_check_neigh(rt);
307 if (n > 1) 346 if (n > 1)
308 m |= 16; 347 m |= 16;
309 else if (!n && strict & RT6_SELECT_F_REACHABLE) 348 else if (!n && strict & RT6_LOOKUP_F_REACHABLE)
310 return -1; 349 return -1;
311 return m; 350 return m;
312} 351}
@@ -346,10 +385,10 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
346 } 385 }
347 386
348 if (!match && 387 if (!match &&
349 (strict & RT6_SELECT_F_REACHABLE) && 388 (strict & RT6_LOOKUP_F_REACHABLE) &&
350 last && last != rt0) { 389 last && last != rt0) {
351 /* no entries matched; do round-robin */ 390 /* no entries matched; do round-robin */
352 static spinlock_t lock = SPIN_LOCK_UNLOCKED; 391 static DEFINE_SPINLOCK(lock);
353 spin_lock(&lock); 392 spin_lock(&lock);
354 *head = rt0->u.next; 393 *head = rt0->u.next;
355 rt0->u.next = last->u.next; 394 rt0->u.next = last->u.next;
@@ -417,7 +456,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
417 rt = rt6_get_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex); 456 rt = rt6_get_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex);
418 457
419 if (rt && !lifetime) { 458 if (rt && !lifetime) {
420 ip6_del_rt(rt, NULL, NULL, NULL); 459 ip6_del_rt(rt);
421 rt = NULL; 460 rt = NULL;
422 } 461 }
423 462
@@ -441,44 +480,95 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
441} 480}
442#endif 481#endif
443 482
444struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, 483#define BACKTRACK(saddr) \
445 int oif, int strict) 484do { \
485 if (rt == &ip6_null_entry) { \
486 struct fib6_node *pn; \
487 while (fn) { \
488 if (fn->fn_flags & RTN_TL_ROOT) \
489 goto out; \
490 pn = fn->parent; \
491 if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
492 fn = fib6_lookup(pn->subtree, NULL, saddr); \
493 else \
494 fn = pn; \
495 if (fn->fn_flags & RTN_RTINFO) \
496 goto restart; \
497 } \
498 } \
499} while(0)
500
501static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table,
502 struct flowi *fl, int flags)
446{ 503{
447 struct fib6_node *fn; 504 struct fib6_node *fn;
448 struct rt6_info *rt; 505 struct rt6_info *rt;
449 506
450 read_lock_bh(&rt6_lock); 507 read_lock_bh(&table->tb6_lock);
451 fn = fib6_lookup(&ip6_routing_table, daddr, saddr); 508 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
452 rt = rt6_device_match(fn->leaf, oif, strict); 509restart:
510 rt = fn->leaf;
511 rt = rt6_device_match(rt, fl->oif, flags);
512 BACKTRACK(&fl->fl6_src);
513out:
453 dst_hold(&rt->u.dst); 514 dst_hold(&rt->u.dst);
454 rt->u.dst.__use++; 515 read_unlock_bh(&table->tb6_lock);
455 read_unlock_bh(&rt6_lock);
456 516
457 rt->u.dst.lastuse = jiffies; 517 rt->u.dst.lastuse = jiffies;
458 if (rt->u.dst.error == 0) 518 rt->u.dst.__use++;
459 return rt; 519
460 dst_release(&rt->u.dst); 520 return rt;
521
522}
523
524struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
525 int oif, int strict)
526{
527 struct flowi fl = {
528 .oif = oif,
529 .nl_u = {
530 .ip6_u = {
531 .daddr = *daddr,
532 /* TODO: saddr */
533 },
534 },
535 };
536 struct dst_entry *dst;
537 int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
538
539 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup);
540 if (dst->error == 0)
541 return (struct rt6_info *) dst;
542
543 dst_release(dst);
544
461 return NULL; 545 return NULL;
462} 546}
463 547
464/* ip6_ins_rt is called with FREE rt6_lock. 548/* ip6_ins_rt is called with FREE table->tb6_lock.
465 It takes new route entry, the addition fails by any reason the 549 It takes new route entry, the addition fails by any reason the
466 route is freed. In any case, if caller does not hold it, it may 550 route is freed. In any case, if caller does not hold it, it may
467 be destroyed. 551 be destroyed.
468 */ 552 */
469 553
470int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, 554static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
471 void *_rtattr, struct netlink_skb_parms *req)
472{ 555{
473 int err; 556 int err;
557 struct fib6_table *table;
474 558
475 write_lock_bh(&rt6_lock); 559 table = rt->rt6i_table;
476 err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req); 560 write_lock_bh(&table->tb6_lock);
477 write_unlock_bh(&rt6_lock); 561 err = fib6_add(&table->tb6_root, rt, info);
562 write_unlock_bh(&table->tb6_lock);
478 563
479 return err; 564 return err;
480} 565}
481 566
567int ip6_ins_rt(struct rt6_info *rt)
568{
569 return __ip6_ins_rt(rt, NULL);
570}
571
482static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr, 572static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
483 struct in6_addr *saddr) 573 struct in6_addr *saddr)
484{ 574{
@@ -532,51 +622,39 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
532 return rt; 622 return rt;
533} 623}
534 624
535#define BACKTRACK() \ 625static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
536if (rt == &ip6_null_entry) { \ 626 struct flowi *fl, int flags)
537 while ((fn = fn->parent) != NULL) { \
538 if (fn->fn_flags & RTN_ROOT) { \
539 goto out; \
540 } \
541 if (fn->fn_flags & RTN_RTINFO) \
542 goto restart; \
543 } \
544}
545
546
547void ip6_route_input(struct sk_buff *skb)
548{ 627{
549 struct fib6_node *fn; 628 struct fib6_node *fn;
550 struct rt6_info *rt, *nrt; 629 struct rt6_info *rt, *nrt;
551 int strict; 630 int strict = 0;
552 int attempts = 3; 631 int attempts = 3;
553 int err; 632 int err;
554 int reachable = RT6_SELECT_F_REACHABLE; 633 int reachable = RT6_LOOKUP_F_REACHABLE;
555 634
556 strict = ipv6_addr_type(&skb->nh.ipv6h->daddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL) ? RT6_SELECT_F_IFACE : 0; 635 strict |= flags & RT6_LOOKUP_F_IFACE;
557 636
558relookup: 637relookup:
559 read_lock_bh(&rt6_lock); 638 read_lock_bh(&table->tb6_lock);
560 639
561restart_2: 640restart_2:
562 fn = fib6_lookup(&ip6_routing_table, &skb->nh.ipv6h->daddr, 641 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
563 &skb->nh.ipv6h->saddr);
564 642
565restart: 643restart:
566 rt = rt6_select(&fn->leaf, skb->dev->ifindex, strict | reachable); 644 rt = rt6_select(&fn->leaf, fl->iif, strict | reachable);
567 BACKTRACK(); 645 BACKTRACK(&fl->fl6_src);
568 if (rt == &ip6_null_entry || 646 if (rt == &ip6_null_entry ||
569 rt->rt6i_flags & RTF_CACHE) 647 rt->rt6i_flags & RTF_CACHE)
570 goto out; 648 goto out;
571 649
572 dst_hold(&rt->u.dst); 650 dst_hold(&rt->u.dst);
573 read_unlock_bh(&rt6_lock); 651 read_unlock_bh(&table->tb6_lock);
574 652
575 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 653 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
576 nrt = rt6_alloc_cow(rt, &skb->nh.ipv6h->daddr, &skb->nh.ipv6h->saddr); 654 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
577 else { 655 else {
578#if CLONE_OFFLINK_ROUTE 656#if CLONE_OFFLINK_ROUTE
579 nrt = rt6_alloc_clone(rt, &skb->nh.ipv6h->daddr); 657 nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
580#else 658#else
581 goto out2; 659 goto out2;
582#endif 660#endif
@@ -587,7 +665,7 @@ restart:
587 665
588 dst_hold(&rt->u.dst); 666 dst_hold(&rt->u.dst);
589 if (nrt) { 667 if (nrt) {
590 err = ip6_ins_rt(nrt, NULL, NULL, &NETLINK_CB(skb)); 668 err = ip6_ins_rt(nrt);
591 if (!err) 669 if (!err)
592 goto out2; 670 goto out2;
593 } 671 }
@@ -596,7 +674,7 @@ restart:
596 goto out2; 674 goto out2;
597 675
598 /* 676 /*
599 * Race condition! In the gap, when rt6_lock was 677 * Race condition! In the gap, when table->tb6_lock was
600 * released someone could insert this route. Relookup. 678 * released someone could insert this route. Relookup.
601 */ 679 */
602 dst_release(&rt->u.dst); 680 dst_release(&rt->u.dst);
@@ -608,40 +686,63 @@ out:
608 goto restart_2; 686 goto restart_2;
609 } 687 }
610 dst_hold(&rt->u.dst); 688 dst_hold(&rt->u.dst);
611 read_unlock_bh(&rt6_lock); 689 read_unlock_bh(&table->tb6_lock);
612out2: 690out2:
613 rt->u.dst.lastuse = jiffies; 691 rt->u.dst.lastuse = jiffies;
614 rt->u.dst.__use++; 692 rt->u.dst.__use++;
615 skb->dst = (struct dst_entry *) rt; 693
616 return; 694 return rt;
617} 695}
618 696
619struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) 697void ip6_route_input(struct sk_buff *skb)
698{
699 struct ipv6hdr *iph = skb->nh.ipv6h;
700 struct flowi fl = {
701 .iif = skb->dev->ifindex,
702 .nl_u = {
703 .ip6_u = {
704 .daddr = iph->daddr,
705 .saddr = iph->saddr,
706#ifdef CONFIG_IPV6_ROUTE_FWMARK
707 .fwmark = skb->nfmark,
708#endif
709 .flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK,
710 },
711 },
712 .proto = iph->nexthdr,
713 };
714 int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0;
715
716 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input);
717}
718
719static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
720 struct flowi *fl, int flags)
620{ 721{
621 struct fib6_node *fn; 722 struct fib6_node *fn;
622 struct rt6_info *rt, *nrt; 723 struct rt6_info *rt, *nrt;
623 int strict; 724 int strict = 0;
624 int attempts = 3; 725 int attempts = 3;
625 int err; 726 int err;
626 int reachable = RT6_SELECT_F_REACHABLE; 727 int reachable = RT6_LOOKUP_F_REACHABLE;
627 728
628 strict = ipv6_addr_type(&fl->fl6_dst) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL) ? RT6_SELECT_F_IFACE : 0; 729 strict |= flags & RT6_LOOKUP_F_IFACE;
629 730
630relookup: 731relookup:
631 read_lock_bh(&rt6_lock); 732 read_lock_bh(&table->tb6_lock);
632 733
633restart_2: 734restart_2:
634 fn = fib6_lookup(&ip6_routing_table, &fl->fl6_dst, &fl->fl6_src); 735 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
635 736
636restart: 737restart:
637 rt = rt6_select(&fn->leaf, fl->oif, strict | reachable); 738 rt = rt6_select(&fn->leaf, fl->oif, strict | reachable);
638 BACKTRACK(); 739 BACKTRACK(&fl->fl6_src);
639 if (rt == &ip6_null_entry || 740 if (rt == &ip6_null_entry ||
640 rt->rt6i_flags & RTF_CACHE) 741 rt->rt6i_flags & RTF_CACHE)
641 goto out; 742 goto out;
642 743
643 dst_hold(&rt->u.dst); 744 dst_hold(&rt->u.dst);
644 read_unlock_bh(&rt6_lock); 745 read_unlock_bh(&table->tb6_lock);
645 746
646 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 747 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
647 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); 748 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
@@ -658,7 +759,7 @@ restart:
658 759
659 dst_hold(&rt->u.dst); 760 dst_hold(&rt->u.dst);
660 if (nrt) { 761 if (nrt) {
661 err = ip6_ins_rt(nrt, NULL, NULL, NULL); 762 err = ip6_ins_rt(nrt);
662 if (!err) 763 if (!err)
663 goto out2; 764 goto out2;
664 } 765 }
@@ -667,7 +768,7 @@ restart:
667 goto out2; 768 goto out2;
668 769
669 /* 770 /*
670 * Race condition! In the gap, when rt6_lock was 771 * Race condition! In the gap, when table->tb6_lock was
671 * released someone could insert this route. Relookup. 772 * released someone could insert this route. Relookup.
672 */ 773 */
673 dst_release(&rt->u.dst); 774 dst_release(&rt->u.dst);
@@ -679,11 +780,21 @@ out:
679 goto restart_2; 780 goto restart_2;
680 } 781 }
681 dst_hold(&rt->u.dst); 782 dst_hold(&rt->u.dst);
682 read_unlock_bh(&rt6_lock); 783 read_unlock_bh(&table->tb6_lock);
683out2: 784out2:
684 rt->u.dst.lastuse = jiffies; 785 rt->u.dst.lastuse = jiffies;
685 rt->u.dst.__use++; 786 rt->u.dst.__use++;
686 return &rt->u.dst; 787 return rt;
788}
789
790struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
791{
792 int flags = 0;
793
794 if (rt6_need_strict(&fl->fl6_dst))
795 flags |= RT6_LOOKUP_F_IFACE;
796
797 return fib6_rule_lookup(fl, flags, ip6_pol_route_output);
687} 798}
688 799
689 800
@@ -709,7 +820,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
709 820
710 if (rt) { 821 if (rt) {
711 if (rt->rt6i_flags & RTF_CACHE) 822 if (rt->rt6i_flags & RTF_CACHE)
712 ip6_del_rt(rt, NULL, NULL, NULL); 823 ip6_del_rt(rt);
713 else 824 else
714 dst_release(dst); 825 dst_release(dst);
715 } 826 }
@@ -743,11 +854,10 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
743 dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; 854 dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
744 } 855 }
745 dst->metrics[RTAX_MTU-1] = mtu; 856 dst->metrics[RTAX_MTU-1] = mtu;
857 call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst);
746 } 858 }
747} 859}
748 860
749/* Protected by rt6_lock. */
750static struct dst_entry *ndisc_dst_gc_list;
751static int ipv6_get_mtu(struct net_device *dev); 861static int ipv6_get_mtu(struct net_device *dev);
752 862
753static inline unsigned int ipv6_advmss(unsigned int mtu) 863static inline unsigned int ipv6_advmss(unsigned int mtu)
@@ -768,6 +878,9 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
768 return mtu; 878 return mtu;
769} 879}
770 880
881static struct dst_entry *ndisc_dst_gc_list;
882static DEFINE_SPINLOCK(ndisc_lock);
883
771struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 884struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
772 struct neighbour *neigh, 885 struct neighbour *neigh,
773 struct in6_addr *addr, 886 struct in6_addr *addr,
@@ -808,10 +921,10 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
808 rt->rt6i_dst.plen = 128; 921 rt->rt6i_dst.plen = 128;
809#endif 922#endif
810 923
811 write_lock_bh(&rt6_lock); 924 spin_lock_bh(&ndisc_lock);
812 rt->u.dst.next = ndisc_dst_gc_list; 925 rt->u.dst.next = ndisc_dst_gc_list;
813 ndisc_dst_gc_list = &rt->u.dst; 926 ndisc_dst_gc_list = &rt->u.dst;
814 write_unlock_bh(&rt6_lock); 927 spin_unlock_bh(&ndisc_lock);
815 928
816 fib6_force_start_gc(); 929 fib6_force_start_gc();
817 930
@@ -825,8 +938,11 @@ int ndisc_dst_gc(int *more)
825 int freed; 938 int freed;
826 939
827 next = NULL; 940 next = NULL;
941 freed = 0;
942
943 spin_lock_bh(&ndisc_lock);
828 pprev = &ndisc_dst_gc_list; 944 pprev = &ndisc_dst_gc_list;
829 freed = 0; 945
830 while ((dst = *pprev) != NULL) { 946 while ((dst = *pprev) != NULL) {
831 if (!atomic_read(&dst->__refcnt)) { 947 if (!atomic_read(&dst->__refcnt)) {
832 *pprev = dst->next; 948 *pprev = dst->next;
@@ -838,6 +954,8 @@ int ndisc_dst_gc(int *more)
838 } 954 }
839 } 955 }
840 956
957 spin_unlock_bh(&ndisc_lock);
958
841 return freed; 959 return freed;
842} 960}
843 961
@@ -898,28 +1016,24 @@ int ipv6_get_hoplimit(struct net_device *dev)
898 * 1016 *
899 */ 1017 */
900 1018
901int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, 1019int ip6_route_add(struct fib6_config *cfg)
902 void *_rtattr, struct netlink_skb_parms *req)
903{ 1020{
904 int err; 1021 int err;
905 struct rtmsg *r;
906 struct rtattr **rta;
907 struct rt6_info *rt = NULL; 1022 struct rt6_info *rt = NULL;
908 struct net_device *dev = NULL; 1023 struct net_device *dev = NULL;
909 struct inet6_dev *idev = NULL; 1024 struct inet6_dev *idev = NULL;
1025 struct fib6_table *table;
910 int addr_type; 1026 int addr_type;
911 1027
912 rta = (struct rtattr **) _rtattr; 1028 if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128)
913
914 if (rtmsg->rtmsg_dst_len > 128 || rtmsg->rtmsg_src_len > 128)
915 return -EINVAL; 1029 return -EINVAL;
916#ifndef CONFIG_IPV6_SUBTREES 1030#ifndef CONFIG_IPV6_SUBTREES
917 if (rtmsg->rtmsg_src_len) 1031 if (cfg->fc_src_len)
918 return -EINVAL; 1032 return -EINVAL;
919#endif 1033#endif
920 if (rtmsg->rtmsg_ifindex) { 1034 if (cfg->fc_ifindex) {
921 err = -ENODEV; 1035 err = -ENODEV;
922 dev = dev_get_by_index(rtmsg->rtmsg_ifindex); 1036 dev = dev_get_by_index(cfg->fc_ifindex);
923 if (!dev) 1037 if (!dev)
924 goto out; 1038 goto out;
925 idev = in6_dev_get(dev); 1039 idev = in6_dev_get(dev);
@@ -927,8 +1041,14 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
927 goto out; 1041 goto out;
928 } 1042 }
929 1043
930 if (rtmsg->rtmsg_metric == 0) 1044 if (cfg->fc_metric == 0)
931 rtmsg->rtmsg_metric = IP6_RT_PRIO_USER; 1045 cfg->fc_metric = IP6_RT_PRIO_USER;
1046
1047 table = fib6_new_table(cfg->fc_table);
1048 if (table == NULL) {
1049 err = -ENOBUFS;
1050 goto out;
1051 }
932 1052
933 rt = ip6_dst_alloc(); 1053 rt = ip6_dst_alloc();
934 1054
@@ -938,14 +1058,13 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
938 } 1058 }
939 1059
940 rt->u.dst.obsolete = -1; 1060 rt->u.dst.obsolete = -1;
941 rt->rt6i_expires = jiffies + clock_t_to_jiffies(rtmsg->rtmsg_info); 1061 rt->rt6i_expires = jiffies + clock_t_to_jiffies(cfg->fc_expires);
942 if (nlh && (r = NLMSG_DATA(nlh))) {
943 rt->rt6i_protocol = r->rtm_protocol;
944 } else {
945 rt->rt6i_protocol = RTPROT_BOOT;
946 }
947 1062
948 addr_type = ipv6_addr_type(&rtmsg->rtmsg_dst); 1063 if (cfg->fc_protocol == RTPROT_UNSPEC)
1064 cfg->fc_protocol = RTPROT_BOOT;
1065 rt->rt6i_protocol = cfg->fc_protocol;
1066
1067 addr_type = ipv6_addr_type(&cfg->fc_dst);
949 1068
950 if (addr_type & IPV6_ADDR_MULTICAST) 1069 if (addr_type & IPV6_ADDR_MULTICAST)
951 rt->u.dst.input = ip6_mc_input; 1070 rt->u.dst.input = ip6_mc_input;
@@ -954,24 +1073,22 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
954 1073
955 rt->u.dst.output = ip6_output; 1074 rt->u.dst.output = ip6_output;
956 1075
957 ipv6_addr_prefix(&rt->rt6i_dst.addr, 1076 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
958 &rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len); 1077 rt->rt6i_dst.plen = cfg->fc_dst_len;
959 rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len;
960 if (rt->rt6i_dst.plen == 128) 1078 if (rt->rt6i_dst.plen == 128)
961 rt->u.dst.flags = DST_HOST; 1079 rt->u.dst.flags = DST_HOST;
962 1080
963#ifdef CONFIG_IPV6_SUBTREES 1081#ifdef CONFIG_IPV6_SUBTREES
964 ipv6_addr_prefix(&rt->rt6i_src.addr, 1082 ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len);
965 &rtmsg->rtmsg_src, rtmsg->rtmsg_src_len); 1083 rt->rt6i_src.plen = cfg->fc_src_len;
966 rt->rt6i_src.plen = rtmsg->rtmsg_src_len;
967#endif 1084#endif
968 1085
969 rt->rt6i_metric = rtmsg->rtmsg_metric; 1086 rt->rt6i_metric = cfg->fc_metric;
970 1087
971 /* We cannot add true routes via loopback here, 1088 /* We cannot add true routes via loopback here,
972 they would result in kernel looping; promote them to reject routes 1089 they would result in kernel looping; promote them to reject routes
973 */ 1090 */
974 if ((rtmsg->rtmsg_flags&RTF_REJECT) || 1091 if ((cfg->fc_flags & RTF_REJECT) ||
975 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { 1092 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
976 /* hold loopback dev/idev if we haven't done so. */ 1093 /* hold loopback dev/idev if we haven't done so. */
977 if (dev != &loopback_dev) { 1094 if (dev != &loopback_dev) {
@@ -994,12 +1111,12 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
994 goto install_route; 1111 goto install_route;
995 } 1112 }
996 1113
997 if (rtmsg->rtmsg_flags & RTF_GATEWAY) { 1114 if (cfg->fc_flags & RTF_GATEWAY) {
998 struct in6_addr *gw_addr; 1115 struct in6_addr *gw_addr;
999 int gwa_type; 1116 int gwa_type;
1000 1117
1001 gw_addr = &rtmsg->rtmsg_gateway; 1118 gw_addr = &cfg->fc_gateway;
1002 ipv6_addr_copy(&rt->rt6i_gateway, &rtmsg->rtmsg_gateway); 1119 ipv6_addr_copy(&rt->rt6i_gateway, gw_addr);
1003 gwa_type = ipv6_addr_type(gw_addr); 1120 gwa_type = ipv6_addr_type(gw_addr);
1004 1121
1005 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { 1122 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
@@ -1016,7 +1133,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
1016 if (!(gwa_type&IPV6_ADDR_UNICAST)) 1133 if (!(gwa_type&IPV6_ADDR_UNICAST))
1017 goto out; 1134 goto out;
1018 1135
1019 grt = rt6_lookup(gw_addr, NULL, rtmsg->rtmsg_ifindex, 1); 1136 grt = rt6_lookup(gw_addr, NULL, cfg->fc_ifindex, 1);
1020 1137
1021 err = -EHOSTUNREACH; 1138 err = -EHOSTUNREACH;
1022 if (grt == NULL) 1139 if (grt == NULL)
@@ -1048,7 +1165,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
1048 if (dev == NULL) 1165 if (dev == NULL)
1049 goto out; 1166 goto out;
1050 1167
1051 if (rtmsg->rtmsg_flags & (RTF_GATEWAY|RTF_NONEXTHOP)) { 1168 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
1052 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); 1169 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
1053 if (IS_ERR(rt->rt6i_nexthop)) { 1170 if (IS_ERR(rt->rt6i_nexthop)) {
1054 err = PTR_ERR(rt->rt6i_nexthop); 1171 err = PTR_ERR(rt->rt6i_nexthop);
@@ -1057,24 +1174,24 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
1057 } 1174 }
1058 } 1175 }
1059 1176
1060 rt->rt6i_flags = rtmsg->rtmsg_flags; 1177 rt->rt6i_flags = cfg->fc_flags;
1061 1178
1062install_route: 1179install_route:
1063 if (rta && rta[RTA_METRICS-1]) { 1180 if (cfg->fc_mx) {
1064 int attrlen = RTA_PAYLOAD(rta[RTA_METRICS-1]); 1181 struct nlattr *nla;
1065 struct rtattr *attr = RTA_DATA(rta[RTA_METRICS-1]); 1182 int remaining;
1066 1183
1067 while (RTA_OK(attr, attrlen)) { 1184 nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
1068 unsigned flavor = attr->rta_type; 1185 int type = nla->nla_type;
1069 if (flavor) { 1186
1070 if (flavor > RTAX_MAX) { 1187 if (type) {
1188 if (type > RTAX_MAX) {
1071 err = -EINVAL; 1189 err = -EINVAL;
1072 goto out; 1190 goto out;
1073 } 1191 }
1074 rt->u.dst.metrics[flavor-1] = 1192
1075 *(u32 *)RTA_DATA(attr); 1193 rt->u.dst.metrics[type - 1] = nla_get_u32(nla);
1076 } 1194 }
1077 attr = RTA_NEXT(attr, attrlen);
1078 } 1195 }
1079 } 1196 }
1080 1197
@@ -1086,7 +1203,8 @@ install_route:
1086 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); 1203 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
1087 rt->u.dst.dev = dev; 1204 rt->u.dst.dev = dev;
1088 rt->rt6i_idev = idev; 1205 rt->rt6i_idev = idev;
1089 return ip6_ins_rt(rt, nlh, _rtattr, req); 1206 rt->rt6i_table = table;
1207 return __ip6_ins_rt(rt, &cfg->fc_nlinfo);
1090 1208
1091out: 1209out:
1092 if (dev) 1210 if (dev)
@@ -1098,51 +1216,65 @@ out:
1098 return err; 1216 return err;
1099} 1217}
1100 1218
1101int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) 1219static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
1102{ 1220{
1103 int err; 1221 int err;
1222 struct fib6_table *table;
1104 1223
1105 write_lock_bh(&rt6_lock); 1224 if (rt == &ip6_null_entry)
1225 return -ENOENT;
1106 1226
1107 err = fib6_del(rt, nlh, _rtattr, req); 1227 table = rt->rt6i_table;
1228 write_lock_bh(&table->tb6_lock);
1229
1230 err = fib6_del(rt, info);
1108 dst_release(&rt->u.dst); 1231 dst_release(&rt->u.dst);
1109 1232
1110 write_unlock_bh(&rt6_lock); 1233 write_unlock_bh(&table->tb6_lock);
1111 1234
1112 return err; 1235 return err;
1113} 1236}
1114 1237
1115static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) 1238int ip6_del_rt(struct rt6_info *rt)
1116{ 1239{
1240 return __ip6_del_rt(rt, NULL);
1241}
1242
1243static int ip6_route_del(struct fib6_config *cfg)
1244{
1245 struct fib6_table *table;
1117 struct fib6_node *fn; 1246 struct fib6_node *fn;
1118 struct rt6_info *rt; 1247 struct rt6_info *rt;
1119 int err = -ESRCH; 1248 int err = -ESRCH;
1120 1249
1121 read_lock_bh(&rt6_lock); 1250 table = fib6_get_table(cfg->fc_table);
1251 if (table == NULL)
1252 return err;
1122 1253
1123 fn = fib6_locate(&ip6_routing_table, 1254 read_lock_bh(&table->tb6_lock);
1124 &rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len, 1255
1125 &rtmsg->rtmsg_src, rtmsg->rtmsg_src_len); 1256 fn = fib6_locate(&table->tb6_root,
1257 &cfg->fc_dst, cfg->fc_dst_len,
1258 &cfg->fc_src, cfg->fc_src_len);
1126 1259
1127 if (fn) { 1260 if (fn) {
1128 for (rt = fn->leaf; rt; rt = rt->u.next) { 1261 for (rt = fn->leaf; rt; rt = rt->u.next) {
1129 if (rtmsg->rtmsg_ifindex && 1262 if (cfg->fc_ifindex &&
1130 (rt->rt6i_dev == NULL || 1263 (rt->rt6i_dev == NULL ||
1131 rt->rt6i_dev->ifindex != rtmsg->rtmsg_ifindex)) 1264 rt->rt6i_dev->ifindex != cfg->fc_ifindex))
1132 continue; 1265 continue;
1133 if (rtmsg->rtmsg_flags&RTF_GATEWAY && 1266 if (cfg->fc_flags & RTF_GATEWAY &&
1134 !ipv6_addr_equal(&rtmsg->rtmsg_gateway, &rt->rt6i_gateway)) 1267 !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
1135 continue; 1268 continue;
1136 if (rtmsg->rtmsg_metric && 1269 if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric)
1137 rtmsg->rtmsg_metric != rt->rt6i_metric)
1138 continue; 1270 continue;
1139 dst_hold(&rt->u.dst); 1271 dst_hold(&rt->u.dst);
1140 read_unlock_bh(&rt6_lock); 1272 read_unlock_bh(&table->tb6_lock);
1141 1273
1142 return ip6_del_rt(rt, nlh, _rtattr, req); 1274 return __ip6_del_rt(rt, &cfg->fc_nlinfo);
1143 } 1275 }
1144 } 1276 }
1145 read_unlock_bh(&rt6_lock); 1277 read_unlock_bh(&table->tb6_lock);
1146 1278
1147 return err; 1279 return err;
1148} 1280}
@@ -1150,11 +1282,17 @@ static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_r
1150/* 1282/*
1151 * Handle redirects 1283 * Handle redirects
1152 */ 1284 */
1153void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, 1285struct ip6rd_flowi {
1154 struct neighbour *neigh, u8 *lladdr, int on_link) 1286 struct flowi fl;
1287 struct in6_addr gateway;
1288};
1289
1290static struct rt6_info *__ip6_route_redirect(struct fib6_table *table,
1291 struct flowi *fl,
1292 int flags)
1155{ 1293{
1156 struct rt6_info *rt, *nrt = NULL; 1294 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl;
1157 int strict; 1295 struct rt6_info *rt;
1158 struct fib6_node *fn; 1296 struct fib6_node *fn;
1159 1297
1160 /* 1298 /*
@@ -1167,10 +1305,9 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr,
1167 * is a bit fuzzy and one might need to check all possible 1305 * is a bit fuzzy and one might need to check all possible
1168 * routes. 1306 * routes.
1169 */ 1307 */
1170 strict = ipv6_addr_type(dest) & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL);
1171 1308
1172 read_lock_bh(&rt6_lock); 1309 read_lock_bh(&table->tb6_lock);
1173 fn = fib6_lookup(&ip6_routing_table, dest, NULL); 1310 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
1174restart: 1311restart:
1175 for (rt = fn->leaf; rt; rt = rt->u.next) { 1312 for (rt = fn->leaf; rt; rt = rt->u.next) {
1176 /* 1313 /*
@@ -1185,29 +1322,60 @@ restart:
1185 continue; 1322 continue;
1186 if (!(rt->rt6i_flags & RTF_GATEWAY)) 1323 if (!(rt->rt6i_flags & RTF_GATEWAY))
1187 continue; 1324 continue;
1188 if (neigh->dev != rt->rt6i_dev) 1325 if (fl->oif != rt->rt6i_dev->ifindex)
1189 continue; 1326 continue;
1190 if (!ipv6_addr_equal(saddr, &rt->rt6i_gateway)) 1327 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
1191 continue; 1328 continue;
1192 break; 1329 break;
1193 } 1330 }
1194 if (rt)
1195 dst_hold(&rt->u.dst);
1196 else if (strict) {
1197 while ((fn = fn->parent) != NULL) {
1198 if (fn->fn_flags & RTN_ROOT)
1199 break;
1200 if (fn->fn_flags & RTN_RTINFO)
1201 goto restart;
1202 }
1203 }
1204 read_unlock_bh(&rt6_lock);
1205 1331
1206 if (!rt) { 1332 if (!rt)
1333 rt = &ip6_null_entry;
1334 BACKTRACK(&fl->fl6_src);
1335out:
1336 dst_hold(&rt->u.dst);
1337
1338 read_unlock_bh(&table->tb6_lock);
1339
1340 return rt;
1341};
1342
1343static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1344 struct in6_addr *src,
1345 struct in6_addr *gateway,
1346 struct net_device *dev)
1347{
1348 struct ip6rd_flowi rdfl = {
1349 .fl = {
1350 .oif = dev->ifindex,
1351 .nl_u = {
1352 .ip6_u = {
1353 .daddr = *dest,
1354 .saddr = *src,
1355 },
1356 },
1357 },
1358 .gateway = *gateway,
1359 };
1360 int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0;
1361
1362 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
1363}
1364
1365void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1366 struct in6_addr *saddr,
1367 struct neighbour *neigh, u8 *lladdr, int on_link)
1368{
1369 struct rt6_info *rt, *nrt = NULL;
1370 struct netevent_redirect netevent;
1371
1372 rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
1373
1374 if (rt == &ip6_null_entry) {
1207 if (net_ratelimit()) 1375 if (net_ratelimit())
1208 printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " 1376 printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
1209 "for redirect target\n"); 1377 "for redirect target\n");
1210 return; 1378 goto out;
1211 } 1379 }
1212 1380
1213 /* 1381 /*
@@ -1250,11 +1418,15 @@ restart:
1250 nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); 1418 nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
1251 nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); 1419 nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst));
1252 1420
1253 if (ip6_ins_rt(nrt, NULL, NULL, NULL)) 1421 if (ip6_ins_rt(nrt))
1254 goto out; 1422 goto out;
1255 1423
1424 netevent.old = &rt->u.dst;
1425 netevent.new = &nrt->u.dst;
1426 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
1427
1256 if (rt->rt6i_flags&RTF_CACHE) { 1428 if (rt->rt6i_flags&RTF_CACHE) {
1257 ip6_del_rt(rt, NULL, NULL, NULL); 1429 ip6_del_rt(rt);
1258 return; 1430 return;
1259 } 1431 }
1260 1432
@@ -1336,7 +1508,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1336 dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires); 1508 dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
1337 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; 1509 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
1338 1510
1339 ip6_ins_rt(nrt, NULL, NULL, NULL); 1511 ip6_ins_rt(nrt);
1340 } 1512 }
1341out: 1513out:
1342 dst_release(&rt->u.dst); 1514 dst_release(&rt->u.dst);
@@ -1372,6 +1544,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1372#ifdef CONFIG_IPV6_SUBTREES 1544#ifdef CONFIG_IPV6_SUBTREES
1373 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); 1545 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
1374#endif 1546#endif
1547 rt->rt6i_table = ort->rt6i_table;
1375 } 1548 }
1376 return rt; 1549 return rt;
1377} 1550}
@@ -1382,9 +1555,14 @@ static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixle
1382{ 1555{
1383 struct fib6_node *fn; 1556 struct fib6_node *fn;
1384 struct rt6_info *rt = NULL; 1557 struct rt6_info *rt = NULL;
1558 struct fib6_table *table;
1385 1559
1386 write_lock_bh(&rt6_lock); 1560 table = fib6_get_table(RT6_TABLE_INFO);
1387 fn = fib6_locate(&ip6_routing_table, prefix ,prefixlen, NULL, 0); 1561 if (table == NULL)
1562 return NULL;
1563
1564 write_lock_bh(&table->tb6_lock);
1565 fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0);
1388 if (!fn) 1566 if (!fn)
1389 goto out; 1567 goto out;
1390 1568
@@ -1399,7 +1577,7 @@ static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixle
1399 break; 1577 break;
1400 } 1578 }
1401out: 1579out:
1402 write_unlock_bh(&rt6_lock); 1580 write_unlock_bh(&table->tb6_lock);
1403 return rt; 1581 return rt;
1404} 1582}
1405 1583
@@ -1407,21 +1585,23 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
1407 struct in6_addr *gwaddr, int ifindex, 1585 struct in6_addr *gwaddr, int ifindex,
1408 unsigned pref) 1586 unsigned pref)
1409{ 1587{
1410 struct in6_rtmsg rtmsg; 1588 struct fib6_config cfg = {
1589 .fc_table = RT6_TABLE_INFO,
1590 .fc_metric = 1024,
1591 .fc_ifindex = ifindex,
1592 .fc_dst_len = prefixlen,
1593 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
1594 RTF_UP | RTF_PREF(pref),
1595 };
1596
1597 ipv6_addr_copy(&cfg.fc_dst, prefix);
1598 ipv6_addr_copy(&cfg.fc_gateway, gwaddr);
1411 1599
1412 memset(&rtmsg, 0, sizeof(rtmsg));
1413 rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1414 ipv6_addr_copy(&rtmsg.rtmsg_dst, prefix);
1415 rtmsg.rtmsg_dst_len = prefixlen;
1416 ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr);
1417 rtmsg.rtmsg_metric = 1024;
1418 rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | RTF_UP | RTF_PREF(pref);
1419 /* We should treat it as a default route if prefix length is 0. */ 1600 /* We should treat it as a default route if prefix length is 0. */
1420 if (!prefixlen) 1601 if (!prefixlen)
1421 rtmsg.rtmsg_flags |= RTF_DEFAULT; 1602 cfg.fc_flags |= RTF_DEFAULT;
1422 rtmsg.rtmsg_ifindex = ifindex;
1423 1603
1424 ip6_route_add(&rtmsg, NULL, NULL, NULL); 1604 ip6_route_add(&cfg);
1425 1605
1426 return rt6_get_route_info(prefix, prefixlen, gwaddr, ifindex); 1606 return rt6_get_route_info(prefix, prefixlen, gwaddr, ifindex);
1427} 1607}
@@ -1430,12 +1610,14 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
1430struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev) 1610struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev)
1431{ 1611{
1432 struct rt6_info *rt; 1612 struct rt6_info *rt;
1433 struct fib6_node *fn; 1613 struct fib6_table *table;
1434 1614
1435 fn = &ip6_routing_table; 1615 table = fib6_get_table(RT6_TABLE_DFLT);
1616 if (table == NULL)
1617 return NULL;
1436 1618
1437 write_lock_bh(&rt6_lock); 1619 write_lock_bh(&table->tb6_lock);
1438 for (rt = fn->leaf; rt; rt=rt->u.next) { 1620 for (rt = table->tb6_root.leaf; rt; rt=rt->u.next) {
1439 if (dev == rt->rt6i_dev && 1621 if (dev == rt->rt6i_dev &&
1440 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && 1622 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
1441 ipv6_addr_equal(&rt->rt6i_gateway, addr)) 1623 ipv6_addr_equal(&rt->rt6i_gateway, addr))
@@ -1443,7 +1625,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
1443 } 1625 }
1444 if (rt) 1626 if (rt)
1445 dst_hold(&rt->u.dst); 1627 dst_hold(&rt->u.dst);
1446 write_unlock_bh(&rt6_lock); 1628 write_unlock_bh(&table->tb6_lock);
1447 return rt; 1629 return rt;
1448} 1630}
1449 1631
@@ -1451,43 +1633,65 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
1451 struct net_device *dev, 1633 struct net_device *dev,
1452 unsigned int pref) 1634 unsigned int pref)
1453{ 1635{
1454 struct in6_rtmsg rtmsg; 1636 struct fib6_config cfg = {
1637 .fc_table = RT6_TABLE_DFLT,
1638 .fc_metric = 1024,
1639 .fc_ifindex = dev->ifindex,
1640 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
1641 RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
1642 };
1455 1643
1456 memset(&rtmsg, 0, sizeof(struct in6_rtmsg)); 1644 ipv6_addr_copy(&cfg.fc_gateway, gwaddr);
1457 rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1458 ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr);
1459 rtmsg.rtmsg_metric = 1024;
1460 rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP | RTF_EXPIRES |
1461 RTF_PREF(pref);
1462 1645
1463 rtmsg.rtmsg_ifindex = dev->ifindex; 1646 ip6_route_add(&cfg);
1464 1647
1465 ip6_route_add(&rtmsg, NULL, NULL, NULL);
1466 return rt6_get_dflt_router(gwaddr, dev); 1648 return rt6_get_dflt_router(gwaddr, dev);
1467} 1649}
1468 1650
1469void rt6_purge_dflt_routers(void) 1651void rt6_purge_dflt_routers(void)
1470{ 1652{
1471 struct rt6_info *rt; 1653 struct rt6_info *rt;
1654 struct fib6_table *table;
1655
1656 /* NOTE: Keep consistent with rt6_get_dflt_router */
1657 table = fib6_get_table(RT6_TABLE_DFLT);
1658 if (table == NULL)
1659 return;
1472 1660
1473restart: 1661restart:
1474 read_lock_bh(&rt6_lock); 1662 read_lock_bh(&table->tb6_lock);
1475 for (rt = ip6_routing_table.leaf; rt; rt = rt->u.next) { 1663 for (rt = table->tb6_root.leaf; rt; rt = rt->u.next) {
1476 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) { 1664 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
1477 dst_hold(&rt->u.dst); 1665 dst_hold(&rt->u.dst);
1478 1666 read_unlock_bh(&table->tb6_lock);
1479 read_unlock_bh(&rt6_lock); 1667 ip6_del_rt(rt);
1480
1481 ip6_del_rt(rt, NULL, NULL, NULL);
1482
1483 goto restart; 1668 goto restart;
1484 } 1669 }
1485 } 1670 }
1486 read_unlock_bh(&rt6_lock); 1671 read_unlock_bh(&table->tb6_lock);
1672}
1673
1674static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg,
1675 struct fib6_config *cfg)
1676{
1677 memset(cfg, 0, sizeof(*cfg));
1678
1679 cfg->fc_table = RT6_TABLE_MAIN;
1680 cfg->fc_ifindex = rtmsg->rtmsg_ifindex;
1681 cfg->fc_metric = rtmsg->rtmsg_metric;
1682 cfg->fc_expires = rtmsg->rtmsg_info;
1683 cfg->fc_dst_len = rtmsg->rtmsg_dst_len;
1684 cfg->fc_src_len = rtmsg->rtmsg_src_len;
1685 cfg->fc_flags = rtmsg->rtmsg_flags;
1686
1687 ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst);
1688 ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src);
1689 ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway);
1487} 1690}
1488 1691
1489int ipv6_route_ioctl(unsigned int cmd, void __user *arg) 1692int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1490{ 1693{
1694 struct fib6_config cfg;
1491 struct in6_rtmsg rtmsg; 1695 struct in6_rtmsg rtmsg;
1492 int err; 1696 int err;
1493 1697
@@ -1500,14 +1704,16 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1500 sizeof(struct in6_rtmsg)); 1704 sizeof(struct in6_rtmsg));
1501 if (err) 1705 if (err)
1502 return -EFAULT; 1706 return -EFAULT;
1503 1707
1708 rtmsg_to_fib6_config(&rtmsg, &cfg);
1709
1504 rtnl_lock(); 1710 rtnl_lock();
1505 switch (cmd) { 1711 switch (cmd) {
1506 case SIOCADDRT: 1712 case SIOCADDRT:
1507 err = ip6_route_add(&rtmsg, NULL, NULL, NULL); 1713 err = ip6_route_add(&cfg);
1508 break; 1714 break;
1509 case SIOCDELRT: 1715 case SIOCDELRT:
1510 err = ip6_route_del(&rtmsg, NULL, NULL, NULL); 1716 err = ip6_route_del(&cfg);
1511 break; 1717 break;
1512 default: 1718 default:
1513 err = -EINVAL; 1719 err = -EINVAL;
@@ -1526,6 +1732,10 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1526 1732
1527static int ip6_pkt_discard(struct sk_buff *skb) 1733static int ip6_pkt_discard(struct sk_buff *skb)
1528{ 1734{
1735 int type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
1736 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED)
1737 IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS);
1738
1529 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 1739 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
1530 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); 1740 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
1531 kfree_skb(skb); 1741 kfree_skb(skb);
@@ -1577,6 +1787,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1577 1787
1578 ipv6_addr_copy(&rt->rt6i_dst.addr, addr); 1788 ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
1579 rt->rt6i_dst.plen = 128; 1789 rt->rt6i_dst.plen = 128;
1790 rt->rt6i_table = fib6_get_table(RT6_TABLE_LOCAL);
1580 1791
1581 atomic_set(&rt->u.dst.__refcnt, 1); 1792 atomic_set(&rt->u.dst.__refcnt, 1);
1582 1793
@@ -1595,9 +1806,7 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg)
1595 1806
1596void rt6_ifdown(struct net_device *dev) 1807void rt6_ifdown(struct net_device *dev)
1597{ 1808{
1598 write_lock_bh(&rt6_lock); 1809 fib6_clean_all(fib6_ifdown, 0, dev);
1599 fib6_clean_tree(&ip6_routing_table, fib6_ifdown, 0, dev);
1600 write_unlock_bh(&rt6_lock);
1601} 1810}
1602 1811
1603struct rt6_mtu_change_arg 1812struct rt6_mtu_change_arg
@@ -1647,80 +1856,114 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
1647 1856
1648void rt6_mtu_change(struct net_device *dev, unsigned mtu) 1857void rt6_mtu_change(struct net_device *dev, unsigned mtu)
1649{ 1858{
1650 struct rt6_mtu_change_arg arg; 1859 struct rt6_mtu_change_arg arg = {
1860 .dev = dev,
1861 .mtu = mtu,
1862 };
1651 1863
1652 arg.dev = dev; 1864 fib6_clean_all(rt6_mtu_change_route, 0, &arg);
1653 arg.mtu = mtu;
1654 read_lock_bh(&rt6_lock);
1655 fib6_clean_tree(&ip6_routing_table, rt6_mtu_change_route, 0, &arg);
1656 read_unlock_bh(&rt6_lock);
1657} 1865}
1658 1866
1659static int inet6_rtm_to_rtmsg(struct rtmsg *r, struct rtattr **rta, 1867static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = {
1660 struct in6_rtmsg *rtmsg) 1868 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) },
1869 [RTA_OIF] = { .type = NLA_U32 },
1870 [RTA_IIF] = { .type = NLA_U32 },
1871 [RTA_PRIORITY] = { .type = NLA_U32 },
1872 [RTA_METRICS] = { .type = NLA_NESTED },
1873};
1874
1875static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
1876 struct fib6_config *cfg)
1661{ 1877{
1662 memset(rtmsg, 0, sizeof(*rtmsg)); 1878 struct rtmsg *rtm;
1879 struct nlattr *tb[RTA_MAX+1];
1880 int err;
1663 1881
1664 rtmsg->rtmsg_dst_len = r->rtm_dst_len; 1882 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
1665 rtmsg->rtmsg_src_len = r->rtm_src_len; 1883 if (err < 0)
1666 rtmsg->rtmsg_flags = RTF_UP; 1884 goto errout;
1667 if (r->rtm_type == RTN_UNREACHABLE)
1668 rtmsg->rtmsg_flags |= RTF_REJECT;
1669 1885
1670 if (rta[RTA_GATEWAY-1]) { 1886 err = -EINVAL;
1671 if (rta[RTA_GATEWAY-1]->rta_len != RTA_LENGTH(16)) 1887 rtm = nlmsg_data(nlh);
1672 return -EINVAL; 1888 memset(cfg, 0, sizeof(*cfg));
1673 memcpy(&rtmsg->rtmsg_gateway, RTA_DATA(rta[RTA_GATEWAY-1]), 16); 1889
1674 rtmsg->rtmsg_flags |= RTF_GATEWAY; 1890 cfg->fc_table = rtm->rtm_table;
1675 } 1891 cfg->fc_dst_len = rtm->rtm_dst_len;
1676 if (rta[RTA_DST-1]) { 1892 cfg->fc_src_len = rtm->rtm_src_len;
1677 if (RTA_PAYLOAD(rta[RTA_DST-1]) < ((r->rtm_dst_len+7)>>3)) 1893 cfg->fc_flags = RTF_UP;
1678 return -EINVAL; 1894 cfg->fc_protocol = rtm->rtm_protocol;
1679 memcpy(&rtmsg->rtmsg_dst, RTA_DATA(rta[RTA_DST-1]), ((r->rtm_dst_len+7)>>3)); 1895
1896 if (rtm->rtm_type == RTN_UNREACHABLE)
1897 cfg->fc_flags |= RTF_REJECT;
1898
1899 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
1900 cfg->fc_nlinfo.nlh = nlh;
1901
1902 if (tb[RTA_GATEWAY]) {
1903 nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
1904 cfg->fc_flags |= RTF_GATEWAY;
1680 } 1905 }
1681 if (rta[RTA_SRC-1]) { 1906
1682 if (RTA_PAYLOAD(rta[RTA_SRC-1]) < ((r->rtm_src_len+7)>>3)) 1907 if (tb[RTA_DST]) {
1683 return -EINVAL; 1908 int plen = (rtm->rtm_dst_len + 7) >> 3;
1684 memcpy(&rtmsg->rtmsg_src, RTA_DATA(rta[RTA_SRC-1]), ((r->rtm_src_len+7)>>3)); 1909
1910 if (nla_len(tb[RTA_DST]) < plen)
1911 goto errout;
1912
1913 nla_memcpy(&cfg->fc_dst, tb[RTA_DST], plen);
1685 } 1914 }
1686 if (rta[RTA_OIF-1]) { 1915
1687 if (rta[RTA_OIF-1]->rta_len != RTA_LENGTH(sizeof(int))) 1916 if (tb[RTA_SRC]) {
1688 return -EINVAL; 1917 int plen = (rtm->rtm_src_len + 7) >> 3;
1689 memcpy(&rtmsg->rtmsg_ifindex, RTA_DATA(rta[RTA_OIF-1]), sizeof(int)); 1918
1919 if (nla_len(tb[RTA_SRC]) < plen)
1920 goto errout;
1921
1922 nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen);
1690 } 1923 }
1691 if (rta[RTA_PRIORITY-1]) { 1924
1692 if (rta[RTA_PRIORITY-1]->rta_len != RTA_LENGTH(4)) 1925 if (tb[RTA_OIF])
1693 return -EINVAL; 1926 cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]);
1694 memcpy(&rtmsg->rtmsg_metric, RTA_DATA(rta[RTA_PRIORITY-1]), 4); 1927
1928 if (tb[RTA_PRIORITY])
1929 cfg->fc_metric = nla_get_u32(tb[RTA_PRIORITY]);
1930
1931 if (tb[RTA_METRICS]) {
1932 cfg->fc_mx = nla_data(tb[RTA_METRICS]);
1933 cfg->fc_mx_len = nla_len(tb[RTA_METRICS]);
1695 } 1934 }
1696 return 0; 1935
1936 if (tb[RTA_TABLE])
1937 cfg->fc_table = nla_get_u32(tb[RTA_TABLE]);
1938
1939 err = 0;
1940errout:
1941 return err;
1697} 1942}
1698 1943
1699int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1944int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
1700{ 1945{
1701 struct rtmsg *r = NLMSG_DATA(nlh); 1946 struct fib6_config cfg;
1702 struct in6_rtmsg rtmsg; 1947 int err;
1703 1948
1704 if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) 1949 err = rtm_to_fib6_config(skb, nlh, &cfg);
1705 return -EINVAL; 1950 if (err < 0)
1706 return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb)); 1951 return err;
1952
1953 return ip6_route_del(&cfg);
1707} 1954}
1708 1955
1709int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1956int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
1710{ 1957{
1711 struct rtmsg *r = NLMSG_DATA(nlh); 1958 struct fib6_config cfg;
1712 struct in6_rtmsg rtmsg; 1959 int err;
1713 1960
1714 if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) 1961 err = rtm_to_fib6_config(skb, nlh, &cfg);
1715 return -EINVAL; 1962 if (err < 0)
1716 return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb)); 1963 return err;
1717}
1718 1964
1719struct rt6_rtnl_dump_arg 1965 return ip6_route_add(&cfg);
1720{ 1966}
1721 struct sk_buff *skb;
1722 struct netlink_callback *cb;
1723};
1724 1967
1725static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, 1968static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1726 struct in6_addr *dst, struct in6_addr *src, 1969 struct in6_addr *dst, struct in6_addr *src,
@@ -1728,9 +1971,9 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1728 int prefix, unsigned int flags) 1971 int prefix, unsigned int flags)
1729{ 1972{
1730 struct rtmsg *rtm; 1973 struct rtmsg *rtm;
1731 struct nlmsghdr *nlh; 1974 struct nlmsghdr *nlh;
1732 unsigned char *b = skb->tail;
1733 struct rta_cacheinfo ci; 1975 struct rta_cacheinfo ci;
1976 u32 table;
1734 1977
1735 if (prefix) { /* user wants prefix routes only */ 1978 if (prefix) { /* user wants prefix routes only */
1736 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { 1979 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
@@ -1739,13 +1982,21 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1739 } 1982 }
1740 } 1983 }
1741 1984
1742 nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); 1985 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
1743 rtm = NLMSG_DATA(nlh); 1986 if (nlh == NULL)
1987 return -ENOBUFS;
1988
1989 rtm = nlmsg_data(nlh);
1744 rtm->rtm_family = AF_INET6; 1990 rtm->rtm_family = AF_INET6;
1745 rtm->rtm_dst_len = rt->rt6i_dst.plen; 1991 rtm->rtm_dst_len = rt->rt6i_dst.plen;
1746 rtm->rtm_src_len = rt->rt6i_src.plen; 1992 rtm->rtm_src_len = rt->rt6i_src.plen;
1747 rtm->rtm_tos = 0; 1993 rtm->rtm_tos = 0;
1748 rtm->rtm_table = RT_TABLE_MAIN; 1994 if (rt->rt6i_table)
1995 table = rt->rt6i_table->tb6_id;
1996 else
1997 table = RT6_TABLE_UNSPEC;
1998 rtm->rtm_table = table;
1999 NLA_PUT_U32(skb, RTA_TABLE, table);
1749 if (rt->rt6i_flags&RTF_REJECT) 2000 if (rt->rt6i_flags&RTF_REJECT)
1750 rtm->rtm_type = RTN_UNREACHABLE; 2001 rtm->rtm_type = RTN_UNREACHABLE;
1751 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) 2002 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
@@ -1766,31 +2017,35 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1766 rtm->rtm_flags |= RTM_F_CLONED; 2017 rtm->rtm_flags |= RTM_F_CLONED;
1767 2018
1768 if (dst) { 2019 if (dst) {
1769 RTA_PUT(skb, RTA_DST, 16, dst); 2020 NLA_PUT(skb, RTA_DST, 16, dst);
1770 rtm->rtm_dst_len = 128; 2021 rtm->rtm_dst_len = 128;
1771 } else if (rtm->rtm_dst_len) 2022 } else if (rtm->rtm_dst_len)
1772 RTA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr); 2023 NLA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr);
1773#ifdef CONFIG_IPV6_SUBTREES 2024#ifdef CONFIG_IPV6_SUBTREES
1774 if (src) { 2025 if (src) {
1775 RTA_PUT(skb, RTA_SRC, 16, src); 2026 NLA_PUT(skb, RTA_SRC, 16, src);
1776 rtm->rtm_src_len = 128; 2027 rtm->rtm_src_len = 128;
1777 } else if (rtm->rtm_src_len) 2028 } else if (rtm->rtm_src_len)
1778 RTA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr); 2029 NLA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr);
1779#endif 2030#endif
1780 if (iif) 2031 if (iif)
1781 RTA_PUT(skb, RTA_IIF, 4, &iif); 2032 NLA_PUT_U32(skb, RTA_IIF, iif);
1782 else if (dst) { 2033 else if (dst) {
1783 struct in6_addr saddr_buf; 2034 struct in6_addr saddr_buf;
1784 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0) 2035 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
1785 RTA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2036 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
1786 } 2037 }
2038
1787 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 2039 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
1788 goto rtattr_failure; 2040 goto nla_put_failure;
2041
1789 if (rt->u.dst.neighbour) 2042 if (rt->u.dst.neighbour)
1790 RTA_PUT(skb, RTA_GATEWAY, 16, &rt->u.dst.neighbour->primary_key); 2043 NLA_PUT(skb, RTA_GATEWAY, 16, &rt->u.dst.neighbour->primary_key);
2044
1791 if (rt->u.dst.dev) 2045 if (rt->u.dst.dev)
1792 RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->rt6i_dev->ifindex); 2046 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
1793 RTA_PUT(skb, RTA_PRIORITY, 4, &rt->rt6i_metric); 2047
2048 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
1794 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2049 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
1795 if (rt->rt6i_expires) 2050 if (rt->rt6i_expires)
1796 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); 2051 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies);
@@ -1802,23 +2057,21 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1802 ci.rta_id = 0; 2057 ci.rta_id = 0;
1803 ci.rta_ts = 0; 2058 ci.rta_ts = 0;
1804 ci.rta_tsage = 0; 2059 ci.rta_tsage = 0;
1805 RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); 2060 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
1806 nlh->nlmsg_len = skb->tail - b;
1807 return skb->len;
1808 2061
1809nlmsg_failure: 2062 return nlmsg_end(skb, nlh);
1810rtattr_failure: 2063
1811 skb_trim(skb, b - skb->data); 2064nla_put_failure:
1812 return -1; 2065 return nlmsg_cancel(skb, nlh);
1813} 2066}
1814 2067
1815static int rt6_dump_route(struct rt6_info *rt, void *p_arg) 2068int rt6_dump_route(struct rt6_info *rt, void *p_arg)
1816{ 2069{
1817 struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg; 2070 struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
1818 int prefix; 2071 int prefix;
1819 2072
1820 if (arg->cb->nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(struct rtmsg))) { 2073 if (nlmsg_len(arg->cb->nlh) >= sizeof(struct rtmsg)) {
1821 struct rtmsg *rtm = NLMSG_DATA(arg->cb->nlh); 2074 struct rtmsg *rtm = nlmsg_data(arg->cb->nlh);
1822 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0; 2075 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0;
1823 } else 2076 } else
1824 prefix = 0; 2077 prefix = 0;
@@ -1828,189 +2081,108 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg)
1828 prefix, NLM_F_MULTI); 2081 prefix, NLM_F_MULTI);
1829} 2082}
1830 2083
1831static int fib6_dump_node(struct fib6_walker_t *w) 2084int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
1832{ 2085{
1833 int res; 2086 struct nlattr *tb[RTA_MAX+1];
1834 struct rt6_info *rt; 2087 struct rt6_info *rt;
2088 struct sk_buff *skb;
2089 struct rtmsg *rtm;
2090 struct flowi fl;
2091 int err, iif = 0;
1835 2092
1836 for (rt = w->leaf; rt; rt = rt->u.next) { 2093 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
1837 res = rt6_dump_route(rt, w->args); 2094 if (err < 0)
1838 if (res < 0) { 2095 goto errout;
1839 /* Frame is full, suspend walking */
1840 w->leaf = rt;
1841 return 1;
1842 }
1843 BUG_TRAP(res!=0);
1844 }
1845 w->leaf = NULL;
1846 return 0;
1847}
1848
1849static void fib6_dump_end(struct netlink_callback *cb)
1850{
1851 struct fib6_walker_t *w = (void*)cb->args[0];
1852
1853 if (w) {
1854 cb->args[0] = 0;
1855 fib6_walker_unlink(w);
1856 kfree(w);
1857 }
1858 cb->done = (void*)cb->args[1];
1859 cb->args[1] = 0;
1860}
1861
1862static int fib6_dump_done(struct netlink_callback *cb)
1863{
1864 fib6_dump_end(cb);
1865 return cb->done ? cb->done(cb) : 0;
1866}
1867
1868int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
1869{
1870 struct rt6_rtnl_dump_arg arg;
1871 struct fib6_walker_t *w;
1872 int res;
1873 2096
1874 arg.skb = skb; 2097 err = -EINVAL;
1875 arg.cb = cb; 2098 memset(&fl, 0, sizeof(fl));
1876 2099
1877 w = (void*)cb->args[0]; 2100 if (tb[RTA_SRC]) {
1878 if (w == NULL) { 2101 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
1879 /* New dump: 2102 goto errout;
1880 *
1881 * 1. hook callback destructor.
1882 */
1883 cb->args[1] = (long)cb->done;
1884 cb->done = fib6_dump_done;
1885 2103
1886 /* 2104 ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC]));
1887 * 2. allocate and initialize walker.
1888 */
1889 w = kzalloc(sizeof(*w), GFP_ATOMIC);
1890 if (w == NULL)
1891 return -ENOMEM;
1892 RT6_TRACE("dump<%p", w);
1893 w->root = &ip6_routing_table;
1894 w->func = fib6_dump_node;
1895 w->args = &arg;
1896 cb->args[0] = (long)w;
1897 read_lock_bh(&rt6_lock);
1898 res = fib6_walk(w);
1899 read_unlock_bh(&rt6_lock);
1900 } else {
1901 w->args = &arg;
1902 read_lock_bh(&rt6_lock);
1903 res = fib6_walk_continue(w);
1904 read_unlock_bh(&rt6_lock);
1905 } 2105 }
1906#if RT6_DEBUG >= 3
1907 if (res <= 0 && skb->len == 0)
1908 RT6_TRACE("%p>dump end\n", w);
1909#endif
1910 res = res < 0 ? res : skb->len;
1911 /* res < 0 is an error. (really, impossible)
1912 res == 0 means that dump is complete, but skb still can contain data.
1913 res > 0 dump is not complete, but frame is full.
1914 */
1915 /* Destroy walker, if dump of this table is complete. */
1916 if (res <= 0)
1917 fib6_dump_end(cb);
1918 return res;
1919}
1920
1921int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
1922{
1923 struct rtattr **rta = arg;
1924 int iif = 0;
1925 int err = -ENOBUFS;
1926 struct sk_buff *skb;
1927 struct flowi fl;
1928 struct rt6_info *rt;
1929 2106
1930 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 2107 if (tb[RTA_DST]) {
1931 if (skb == NULL) 2108 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
1932 goto out; 2109 goto errout;
1933 2110
1934 /* Reserve room for dummy headers, this skb can pass 2111 ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST]));
1935 through good chunk of routing engine. 2112 }
1936 */
1937 skb->mac.raw = skb->data;
1938 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
1939 2113
1940 memset(&fl, 0, sizeof(fl)); 2114 if (tb[RTA_IIF])
1941 if (rta[RTA_SRC-1]) 2115 iif = nla_get_u32(tb[RTA_IIF]);
1942 ipv6_addr_copy(&fl.fl6_src,
1943 (struct in6_addr*)RTA_DATA(rta[RTA_SRC-1]));
1944 if (rta[RTA_DST-1])
1945 ipv6_addr_copy(&fl.fl6_dst,
1946 (struct in6_addr*)RTA_DATA(rta[RTA_DST-1]));
1947 2116
1948 if (rta[RTA_IIF-1]) 2117 if (tb[RTA_OIF])
1949 memcpy(&iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); 2118 fl.oif = nla_get_u32(tb[RTA_OIF]);
1950 2119
1951 if (iif) { 2120 if (iif) {
1952 struct net_device *dev; 2121 struct net_device *dev;
1953 dev = __dev_get_by_index(iif); 2122 dev = __dev_get_by_index(iif);
1954 if (!dev) { 2123 if (!dev) {
1955 err = -ENODEV; 2124 err = -ENODEV;
1956 goto out_free; 2125 goto errout;
1957 } 2126 }
1958 } 2127 }
1959 2128
1960 fl.oif = 0; 2129 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1961 if (rta[RTA_OIF-1]) 2130 if (skb == NULL) {
1962 memcpy(&fl.oif, RTA_DATA(rta[RTA_OIF-1]), sizeof(int)); 2131 err = -ENOBUFS;
2132 goto errout;
2133 }
1963 2134
1964 rt = (struct rt6_info*)ip6_route_output(NULL, &fl); 2135 /* Reserve room for dummy headers, this skb can pass
2136 through good chunk of routing engine.
2137 */
2138 skb->mac.raw = skb->data;
2139 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
1965 2140
2141 rt = (struct rt6_info*) ip6_route_output(NULL, &fl);
1966 skb->dst = &rt->u.dst; 2142 skb->dst = &rt->u.dst;
1967 2143
1968 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; 2144 err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
1969 err = rt6_fill_node(skb, rt,
1970 &fl.fl6_dst, &fl.fl6_src,
1971 iif,
1972 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2145 RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
1973 nlh->nlmsg_seq, 0, 0); 2146 nlh->nlmsg_seq, 0, 0);
1974 if (err < 0) { 2147 if (err < 0) {
1975 err = -EMSGSIZE; 2148 kfree_skb(skb);
1976 goto out_free; 2149 goto errout;
1977 } 2150 }
1978 2151
1979 err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); 2152 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
1980 if (err > 0) 2153errout:
1981 err = 0;
1982out:
1983 return err; 2154 return err;
1984out_free:
1985 kfree_skb(skb);
1986 goto out;
1987} 2155}
1988 2156
1989void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh, 2157void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
1990 struct netlink_skb_parms *req)
1991{ 2158{
1992 struct sk_buff *skb; 2159 struct sk_buff *skb;
1993 int size = NLMSG_SPACE(sizeof(struct rtmsg)+256); 2160 u32 pid = 0, seq = 0;
1994 u32 pid = current->pid; 2161 struct nlmsghdr *nlh = NULL;
1995 u32 seq = 0; 2162 int payload = sizeof(struct rtmsg) + 256;
1996 2163 int err = -ENOBUFS;
1997 if (req) 2164
1998 pid = req->pid; 2165 if (info) {
1999 if (nlh) 2166 pid = info->pid;
2000 seq = nlh->nlmsg_seq; 2167 nlh = info->nlh;
2001 2168 if (nlh)
2002 skb = alloc_skb(size, gfp_any()); 2169 seq = nlh->nlmsg_seq;
2003 if (!skb) {
2004 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_ROUTE, ENOBUFS);
2005 return;
2006 } 2170 }
2007 if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) { 2171
2172 skb = nlmsg_new(nlmsg_total_size(payload), gfp_any());
2173 if (skb == NULL)
2174 goto errout;
2175
2176 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2177 if (err < 0) {
2008 kfree_skb(skb); 2178 kfree_skb(skb);
2009 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_ROUTE, EINVAL); 2179 goto errout;
2010 return;
2011 } 2180 }
2012 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_ROUTE; 2181
2013 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_ROUTE, gfp_any()); 2182 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
2183errout:
2184 if (err < 0)
2185 rtnl_set_sk_err(RTNLGRP_IPV6_ROUTE, err);
2014} 2186}
2015 2187
2016/* 2188/*
@@ -2086,16 +2258,13 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2086 2258
2087static int rt6_proc_info(char *buffer, char **start, off_t offset, int length) 2259static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
2088{ 2260{
2089 struct rt6_proc_arg arg; 2261 struct rt6_proc_arg arg = {
2090 arg.buffer = buffer; 2262 .buffer = buffer,
2091 arg.offset = offset; 2263 .offset = offset,
2092 arg.length = length; 2264 .length = length,
2093 arg.skip = 0; 2265 };
2094 arg.len = 0;
2095 2266
2096 read_lock_bh(&rt6_lock); 2267 fib6_clean_all(rt6_info_route, 0, &arg);
2097 fib6_clean_tree(&ip6_routing_table, rt6_info_route, 0, &arg);
2098 read_unlock_bh(&rt6_lock);
2099 2268
2100 *start = buffer; 2269 *start = buffer;
2101 if (offset) 2270 if (offset)
@@ -2250,13 +2419,9 @@ void __init ip6_route_init(void)
2250{ 2419{
2251 struct proc_dir_entry *p; 2420 struct proc_dir_entry *p;
2252 2421
2253 ip6_dst_ops.kmem_cachep = kmem_cache_create("ip6_dst_cache", 2422 ip6_dst_ops.kmem_cachep =
2254 sizeof(struct rt6_info), 2423 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
2255 0, SLAB_HWCACHE_ALIGN, 2424 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
2256 NULL, NULL);
2257 if (!ip6_dst_ops.kmem_cachep)
2258 panic("cannot create ip6_dst_cache");
2259
2260 fib6_init(); 2425 fib6_init();
2261#ifdef CONFIG_PROC_FS 2426#ifdef CONFIG_PROC_FS
2262 p = proc_net_create("ipv6_route", 0, rt6_proc_info); 2427 p = proc_net_create("ipv6_route", 0, rt6_proc_info);
@@ -2268,10 +2433,16 @@ void __init ip6_route_init(void)
2268#ifdef CONFIG_XFRM 2433#ifdef CONFIG_XFRM
2269 xfrm6_init(); 2434 xfrm6_init();
2270#endif 2435#endif
2436#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2437 fib6_rules_init();
2438#endif
2271} 2439}
2272 2440
2273void ip6_route_cleanup(void) 2441void ip6_route_cleanup(void)
2274{ 2442{
2443#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2444 fib6_rules_cleanup();
2445#endif
2275#ifdef CONFIG_PROC_FS 2446#ifdef CONFIG_PROC_FS
2276 proc_net_remove("ipv6_route"); 2447 proc_net_remove("ipv6_route");
2277 proc_net_remove("rt6_stats"); 2448 proc_net_remove("rt6_stats");
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 6578c3080f47..836eecd7e62b 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -18,7 +18,6 @@
18 * Nate Thompson <nate@thebog.net>: 6to4 support 18 * Nate Thompson <nate@thebog.net>: 6to4 support
19 */ 19 */
20 20
21#include <linux/config.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/capability.h> 22#include <linux/capability.h>
24#include <linux/errno.h> 23#include <linux/errno.h>
@@ -381,7 +380,6 @@ static int ipip6_rcv(struct sk_buff *skb)
381 secpath_reset(skb); 380 secpath_reset(skb);
382 skb->mac.raw = skb->nh.raw; 381 skb->mac.raw = skb->nh.raw;
383 skb->nh.raw = skb->data; 382 skb->nh.raw = skb->data;
384 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
385 IPCB(skb)->flags = 0; 383 IPCB(skb)->flags = 0;
386 skb->protocol = htons(ETH_P_IPV6); 384 skb->protocol = htons(ETH_P_IPV6);
387 skb->pkt_type = PACKET_HOST; 385 skb->pkt_type = PACKET_HOST;
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 8eff9fa1e983..7a4639db1346 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -7,7 +7,6 @@
7 7
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/sysctl.h> 9#include <linux/sysctl.h>
10#include <linux/config.h>
11#include <linux/in6.h> 10#include <linux/in6.h>
12#include <linux/ipv6.h> 11#include <linux/ipv6.h>
13#include <net/ndisc.h> 12#include <net/ndisc.h>
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a50eb306e9e2..3b6575478fcc 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -26,7 +26,6 @@
26 */ 26 */
27 27
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/config.h>
30#include <linux/errno.h> 29#include <linux/errno.h>
31#include <linux/types.h> 30#include <linux/types.h>
32#include <linux/socket.h> 31#include <linux/socket.h>
@@ -252,6 +251,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
252 final_p = &final; 251 final_p = &final;
253 } 252 }
254 253
254 security_sk_classify_flow(sk, &fl);
255
255 err = ip6_dst_lookup(sk, &dst, &fl); 256 err = ip6_dst_lookup(sk, &dst, &fl);
256 if (err) 257 if (err)
257 goto failure; 258 goto failure;
@@ -270,9 +271,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
270 ipv6_addr_copy(&np->saddr, saddr); 271 ipv6_addr_copy(&np->saddr, saddr);
271 inet->rcv_saddr = LOOPBACK4_IPV6; 272 inet->rcv_saddr = LOOPBACK4_IPV6;
272 273
273 ip6_dst_store(sk, dst, NULL); 274 sk->sk_gso_type = SKB_GSO_TCPV6;
274 sk->sk_route_caps = dst->dev->features & 275 __ip6_dst_store(sk, dst, NULL, NULL);
275 ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
276 276
277 icsk->icsk_ext_hdr_len = 0; 277 icsk->icsk_ext_hdr_len = 0;
278 if (np->opt) 278 if (np->opt)
@@ -376,6 +376,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
376 fl.oif = sk->sk_bound_dev_if; 376 fl.oif = sk->sk_bound_dev_if;
377 fl.fl_ip_dport = inet->dport; 377 fl.fl_ip_dport = inet->dport;
378 fl.fl_ip_sport = inet->sport; 378 fl.fl_ip_sport = inet->sport;
379 security_skb_classify_flow(skb, &fl);
379 380
380 if ((err = ip6_dst_lookup(sk, &dst, &fl))) { 381 if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
381 sk->sk_err_soft = -err; 382 sk->sk_err_soft = -err;
@@ -429,7 +430,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
429 case TCP_SYN_RECV: /* Cannot happen. 430 case TCP_SYN_RECV: /* Cannot happen.
430 It can, it SYNs are crossed. --ANK */ 431 It can, it SYNs are crossed. --ANK */
431 if (!sock_owned_by_user(sk)) { 432 if (!sock_owned_by_user(sk)) {
432 TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
433 sk->sk_err = err; 433 sk->sk_err = err;
434 sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ 434 sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */
435 435
@@ -470,6 +470,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
470 fl.oif = treq->iif; 470 fl.oif = treq->iif;
471 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 471 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
472 fl.fl_ip_sport = inet_sk(sk)->sport; 472 fl.fl_ip_sport = inet_sk(sk)->sport;
473 security_req_classify_flow(req, &fl);
473 474
474 if (dst == NULL) { 475 if (dst == NULL) {
475 opt = np->opt; 476 opt = np->opt;
@@ -544,7 +545,7 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
544 struct ipv6_pinfo *np = inet6_sk(sk); 545 struct ipv6_pinfo *np = inet6_sk(sk);
545 struct tcphdr *th = skb->h.th; 546 struct tcphdr *th = skb->h.th;
546 547
547 if (skb->ip_summed == CHECKSUM_HW) { 548 if (skb->ip_summed == CHECKSUM_PARTIAL) {
548 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); 549 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0);
549 skb->csum = offsetof(struct tcphdr, check); 550 skb->csum = offsetof(struct tcphdr, check);
550 } else { 551 } else {
@@ -554,6 +555,24 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
554 } 555 }
555} 556}
556 557
558static int tcp_v6_gso_send_check(struct sk_buff *skb)
559{
560 struct ipv6hdr *ipv6h;
561 struct tcphdr *th;
562
563 if (!pskb_may_pull(skb, sizeof(*th)))
564 return -EINVAL;
565
566 ipv6h = skb->nh.ipv6h;
567 th = skb->h.th;
568
569 th->check = 0;
570 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
571 IPPROTO_TCP, 0);
572 skb->csum = offsetof(struct tcphdr, check);
573 skb->ip_summed = CHECKSUM_PARTIAL;
574 return 0;
575}
557 576
558static void tcp_v6_send_reset(struct sk_buff *skb) 577static void tcp_v6_send_reset(struct sk_buff *skb)
559{ 578{
@@ -610,6 +629,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
610 fl.oif = inet6_iif(skb); 629 fl.oif = inet6_iif(skb);
611 fl.fl_ip_dport = t1->dest; 630 fl.fl_ip_dport = t1->dest;
612 fl.fl_ip_sport = t1->source; 631 fl.fl_ip_sport = t1->source;
632 security_skb_classify_flow(skb, &fl);
613 633
614 /* sk = NULL, but it is safe for now. RST socket required. */ 634 /* sk = NULL, but it is safe for now. RST socket required. */
615 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { 635 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
@@ -676,6 +696,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
676 fl.oif = inet6_iif(skb); 696 fl.oif = inet6_iif(skb);
677 fl.fl_ip_dport = t1->dest; 697 fl.fl_ip_dport = t1->dest;
678 fl.fl_ip_sport = t1->source; 698 fl.fl_ip_sport = t1->source;
699 security_skb_classify_flow(skb, &fl);
679 700
680 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { 701 if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
681 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 702 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
@@ -805,6 +826,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
805 826
806 tcp_rsk(req)->snt_isn = isn; 827 tcp_rsk(req)->snt_isn = isn;
807 828
829 security_inet_conn_request(sk, skb, req);
830
808 if (tcp_v6_send_synack(sk, req, NULL)) 831 if (tcp_v6_send_synack(sk, req, NULL))
809 goto drop; 832 goto drop;
810 833
@@ -815,7 +838,6 @@ drop:
815 if (req) 838 if (req)
816 reqsk_free(req); 839 reqsk_free(req);
817 840
818 TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
819 return 0; /* don't send reset */ 841 return 0; /* don't send reset */
820} 842}
821 843
@@ -909,6 +931,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
909 fl.oif = sk->sk_bound_dev_if; 931 fl.oif = sk->sk_bound_dev_if;
910 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 932 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
911 fl.fl_ip_sport = inet_sk(sk)->sport; 933 fl.fl_ip_sport = inet_sk(sk)->sport;
934 security_req_classify_flow(req, &fl);
912 935
913 if (ip6_dst_lookup(sk, &dst, &fl)) 936 if (ip6_dst_lookup(sk, &dst, &fl))
914 goto out; 937 goto out;
@@ -930,9 +953,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
930 * comment in that function for the gory details. -acme 953 * comment in that function for the gory details. -acme
931 */ 954 */
932 955
933 ip6_dst_store(newsk, dst, NULL); 956 newsk->sk_gso_type = SKB_GSO_TCPV6;
934 newsk->sk_route_caps = dst->dev->features & 957 __ip6_dst_store(newsk, dst, NULL, NULL);
935 ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
936 958
937 newtcp6sk = (struct tcp6_sock *)newsk; 959 newtcp6sk = (struct tcp6_sock *)newsk;
938 inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; 960 inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
@@ -1011,7 +1033,7 @@ out:
1011 1033
1012static int tcp_v6_checksum_init(struct sk_buff *skb) 1034static int tcp_v6_checksum_init(struct sk_buff *skb)
1013{ 1035{
1014 if (skb->ip_summed == CHECKSUM_HW) { 1036 if (skb->ip_summed == CHECKSUM_COMPLETE) {
1015 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1037 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1016 &skb->nh.ipv6h->daddr,skb->csum)) { 1038 &skb->nh.ipv6h->daddr,skb->csum)) {
1017 skb->ip_summed = CHECKSUM_UNNECESSARY; 1039 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1053,7 +1075,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1053 if (skb->protocol == htons(ETH_P_IP)) 1075 if (skb->protocol == htons(ETH_P_IP))
1054 return tcp_v4_do_rcv(sk, skb); 1076 return tcp_v4_do_rcv(sk, skb);
1055 1077
1056 if (sk_filter(sk, skb, 0)) 1078 if (sk_filter(sk, skb))
1057 goto discard; 1079 goto discard;
1058 1080
1059 /* 1081 /*
@@ -1210,12 +1232,12 @@ process:
1210 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 1232 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1211 goto discard_and_relse; 1233 goto discard_and_relse;
1212 1234
1213 if (sk_filter(sk, skb, 0)) 1235 if (sk_filter(sk, skb))
1214 goto discard_and_relse; 1236 goto discard_and_relse;
1215 1237
1216 skb->dev = NULL; 1238 skb->dev = NULL;
1217 1239
1218 bh_lock_sock(sk); 1240 bh_lock_sock_nested(sk);
1219 ret = 0; 1241 ret = 0;
1220 if (!sock_owned_by_user(sk)) { 1242 if (!sock_owned_by_user(sk)) {
1221#ifdef CONFIG_NET_DMA 1243#ifdef CONFIG_NET_DMA
@@ -1469,7 +1491,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1469 dest->s6_addr32[0], dest->s6_addr32[1], 1491 dest->s6_addr32[0], dest->s6_addr32[1],
1470 dest->s6_addr32[2], dest->s6_addr32[3], destp, 1492 dest->s6_addr32[2], dest->s6_addr32[3], destp,
1471 sp->sk_state, 1493 sp->sk_state,
1472 tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, 1494 tp->write_seq-tp->snd_una,
1495 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
1473 timer_active, 1496 timer_active,
1474 jiffies_to_clock_t(timer_expires - jiffies), 1497 jiffies_to_clock_t(timer_expires - jiffies),
1475 icsk->icsk_retransmits, 1498 icsk->icsk_retransmits,
@@ -1605,6 +1628,8 @@ struct proto tcpv6_prot = {
1605static struct inet6_protocol tcpv6_protocol = { 1628static struct inet6_protocol tcpv6_protocol = {
1606 .handler = tcp_v6_rcv, 1629 .handler = tcp_v6_rcv,
1607 .err_handler = tcp_v6_err, 1630 .err_handler = tcp_v6_err,
1631 .gso_send_check = tcp_v6_gso_send_check,
1632 .gso_segment = tcp_tso_segment,
1608 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 1633 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1609}; 1634};
1610 1635
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 8d3432a70f3a..9662561701d1 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -23,7 +23,6 @@
23 * 2 of the License, or (at your option) any later version. 23 * 2 of the License, or (at your option) any later version.
24 */ 24 */
25 25
26#include <linux/config.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/types.h> 27#include <linux/types.h>
29#include <linux/socket.h> 28#include <linux/socket.h>
@@ -62,81 +61,9 @@
62 61
63DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; 62DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
64 63
65/* Grrr, addr_type already calculated by caller, but I don't want 64static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
66 * to add some silly "cookie" argument to this method just for that.
67 */
68static int udp_v6_get_port(struct sock *sk, unsigned short snum)
69{ 65{
70 struct sock *sk2; 66 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
71 struct hlist_node *node;
72
73 write_lock_bh(&udp_hash_lock);
74 if (snum == 0) {
75 int best_size_so_far, best, result, i;
76
77 if (udp_port_rover > sysctl_local_port_range[1] ||
78 udp_port_rover < sysctl_local_port_range[0])
79 udp_port_rover = sysctl_local_port_range[0];
80 best_size_so_far = 32767;
81 best = result = udp_port_rover;
82 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
83 int size;
84 struct hlist_head *list;
85
86 list = &udp_hash[result & (UDP_HTABLE_SIZE - 1)];
87 if (hlist_empty(list)) {
88 if (result > sysctl_local_port_range[1])
89 result = sysctl_local_port_range[0] +
90 ((result - sysctl_local_port_range[0]) &
91 (UDP_HTABLE_SIZE - 1));
92 goto gotit;
93 }
94 size = 0;
95 sk_for_each(sk2, node, list)
96 if (++size >= best_size_so_far)
97 goto next;
98 best_size_so_far = size;
99 best = result;
100 next:;
101 }
102 result = best;
103 for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) {
104 if (result > sysctl_local_port_range[1])
105 result = sysctl_local_port_range[0]
106 + ((result - sysctl_local_port_range[0]) &
107 (UDP_HTABLE_SIZE - 1));
108 if (!udp_lport_inuse(result))
109 break;
110 }
111 if (i >= (1 << 16) / UDP_HTABLE_SIZE)
112 goto fail;
113gotit:
114 udp_port_rover = snum = result;
115 } else {
116 sk_for_each(sk2, node,
117 &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]) {
118 if (inet_sk(sk2)->num == snum &&
119 sk2 != sk &&
120 (!sk2->sk_bound_dev_if ||
121 !sk->sk_bound_dev_if ||
122 sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
123 (!sk2->sk_reuse || !sk->sk_reuse) &&
124 ipv6_rcv_saddr_equal(sk, sk2))
125 goto fail;
126 }
127 }
128
129 inet_sk(sk)->num = snum;
130 if (sk_unhashed(sk)) {
131 sk_add_node(sk, &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]);
132 sock_prot_inc_use(sk->sk_prot);
133 }
134 write_unlock_bh(&udp_hash_lock);
135 return 0;
136
137fail:
138 write_unlock_bh(&udp_hash_lock);
139 return 1;
140} 67}
141 68
142static void udp_v6_hash(struct sock *sk) 69static void udp_v6_hash(struct sock *sk)
@@ -346,6 +273,8 @@ out:
346 273
347static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) 274static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
348{ 275{
276 int rc;
277
349 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { 278 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) {
350 kfree_skb(skb); 279 kfree_skb(skb);
351 return -1; 280 return -1;
@@ -357,7 +286,10 @@ static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
357 return 0; 286 return 0;
358 } 287 }
359 288
360 if (sock_queue_rcv_skb(sk,skb)<0) { 289 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
290 /* Note that an ENOMEM error is charged twice */
291 if (rc == -ENOMEM)
292 UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS);
361 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 293 UDP6_INC_STATS_BH(UDP_MIB_INERRORS);
362 kfree_skb(skb); 294 kfree_skb(skb);
363 return 0; 295 return 0;
@@ -476,7 +408,7 @@ static int udpv6_rcv(struct sk_buff **pskb)
476 uh = skb->h.uh; 408 uh = skb->h.uh;
477 } 409 }
478 410
479 if (skb->ip_summed == CHECKSUM_HW && 411 if (skb->ip_summed == CHECKSUM_COMPLETE &&
480 !csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) 412 !csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum))
481 skb->ip_summed = CHECKSUM_UNNECESSARY; 413 skb->ip_summed = CHECKSUM_UNNECESSARY;
482 414
@@ -783,7 +715,9 @@ do_udp_sendmsg:
783 connected = 0; 715 connected = 0;
784 } 716 }
785 717
786 err = ip6_dst_lookup(sk, &dst, fl); 718 security_sk_classify_flow(sk, fl);
719
720 err = ip6_sk_dst_lookup(sk, &dst, fl);
787 if (err) 721 if (err)
788 goto out; 722 goto out;
789 if (final_p) 723 if (final_p)
@@ -841,7 +775,12 @@ do_append_data:
841 if (connected) { 775 if (connected) {
842 ip6_dst_store(sk, dst, 776 ip6_dst_store(sk, dst,
843 ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ? 777 ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ?
844 &np->daddr : NULL); 778 &np->daddr : NULL,
779#ifdef CONFIG_IPV6_SUBTREES
780 ipv6_addr_equal(&fl->fl6_src, &np->saddr) ?
781 &np->saddr :
782#endif
783 NULL);
845 } else { 784 } else {
846 dst_release(dst); 785 dst_release(dst);
847 } 786 }
@@ -856,6 +795,16 @@ out:
856 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); 795 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS);
857 return len; 796 return len;
858 } 797 }
798 /*
799 * ENOBUFS = no kernel mem, SOCK_NOSPACE = no sndbuf space. Reporting
800 * ENOBUFS might not be good (it's not tunable per se), but otherwise
801 * we don't have a good statistic (IpOutDiscards but it can be too many
802 * things). We could add another new stat but at least for now that
803 * seems like overkill.
804 */
805 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
806 UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS);
807 }
859 return err; 808 return err;
860 809
861do_confirm: 810do_confirm:
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 0405d74ff910..5c8b7a568800 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,10 +16,10 @@
16#include <net/ipv6.h> 16#include <net/ipv6.h>
17#include <net/xfrm.h> 17#include <net/xfrm.h>
18 18
19int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) 19int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
20{ 20{
21 int err; 21 int err;
22 u32 seq; 22 __be32 seq;
23 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 23 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
24 struct xfrm_state *x; 24 struct xfrm_state *x;
25 int xfrm_nr = 0; 25 int xfrm_nr = 0;
@@ -72,7 +72,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
72 if (x->mode->input(x, skb)) 72 if (x->mode->input(x, skb))
73 goto drop; 73 goto drop;
74 74
75 if (x->props.mode) { /* XXX */ 75 if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
76 decaps = 1; 76 decaps = 1;
77 break; 77 break;
78 } 78 }
@@ -138,3 +138,111 @@ int xfrm6_rcv(struct sk_buff **pskb)
138{ 138{
139 return xfrm6_rcv_spi(*pskb, 0); 139 return xfrm6_rcv_spi(*pskb, 0);
140} 140}
141
142int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
143 xfrm_address_t *saddr, u8 proto)
144{
145 struct xfrm_state *x = NULL;
146 int wildcard = 0;
147 struct in6_addr any;
148 xfrm_address_t *xany;
149 struct xfrm_state *xfrm_vec_one = NULL;
150 int nh = 0;
151 int i = 0;
152
153 ipv6_addr_set(&any, 0, 0, 0, 0);
154 xany = (xfrm_address_t *)&any;
155
156 for (i = 0; i < 3; i++) {
157 xfrm_address_t *dst, *src;
158 switch (i) {
159 case 0:
160 dst = daddr;
161 src = saddr;
162 break;
163 case 1:
164 /* lookup state with wild-card source address */
165 wildcard = 1;
166 dst = daddr;
167 src = xany;
168 break;
169 case 2:
170 default:
171 /* lookup state with wild-card addresses */
172 wildcard = 1; /* XXX */
173 dst = xany;
174 src = xany;
175 break;
176 }
177
178 x = xfrm_state_lookup_byaddr(dst, src, proto, AF_INET6);
179 if (!x)
180 continue;
181
182 spin_lock(&x->lock);
183
184 if (wildcard) {
185 if ((x->props.flags & XFRM_STATE_WILDRECV) == 0) {
186 spin_unlock(&x->lock);
187 xfrm_state_put(x);
188 x = NULL;
189 continue;
190 }
191 }
192
193 if (unlikely(x->km.state != XFRM_STATE_VALID)) {
194 spin_unlock(&x->lock);
195 xfrm_state_put(x);
196 x = NULL;
197 continue;
198 }
199 if (xfrm_state_check_expire(x)) {
200 spin_unlock(&x->lock);
201 xfrm_state_put(x);
202 x = NULL;
203 continue;
204 }
205
206 nh = x->type->input(x, skb);
207 if (nh <= 0) {
208 spin_unlock(&x->lock);
209 xfrm_state_put(x);
210 x = NULL;
211 continue;
212 }
213
214 x->curlft.bytes += skb->len;
215 x->curlft.packets++;
216
217 spin_unlock(&x->lock);
218
219 xfrm_vec_one = x;
220 break;
221 }
222
223 if (!xfrm_vec_one)
224 goto drop;
225
226 /* Allocate new secpath or COW existing one. */
227 if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
228 struct sec_path *sp;
229 sp = secpath_dup(skb->sp);
230 if (!sp)
231 goto drop;
232 if (skb->sp)
233 secpath_put(skb->sp);
234 skb->sp = sp;
235 }
236
237 if (1 + skb->sp->len > XFRM_MAX_DEPTH)
238 goto drop;
239
240 skb->sp->xvec[skb->sp->len] = xfrm_vec_one;
241 skb->sp->len ++;
242
243 return 1;
244drop:
245 if (xfrm_vec_one)
246 xfrm_state_put(xfrm_vec_one);
247 return -1;
248}
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
new file mode 100644
index 000000000000..6031c16d46ca
--- /dev/null
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -0,0 +1,93 @@
1/*
2 * xfrm6_mode_ro.c - Route optimization mode for IPv6.
3 *
4 * Copyright (C)2003-2006 Helsinki University of Technology
5 * Copyright (C)2003-2006 USAGI/WIDE Project
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21/*
22 * Authors:
23 * Noriaki TAKAMIYA @USAGI
24 * Masahide NAKAMURA @USAGI
25 */
26
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/skbuff.h>
31#include <linux/stringify.h>
32#include <net/ipv6.h>
33#include <net/xfrm.h>
34
35/* Add route optimization header space.
36 *
37 * The IP header and mutable extension headers will be moved forward to make
38 * space for the route optimization header.
39 *
40 * On exit, skb->h will be set to the start of the encapsulation header to be
41 * filled in by x->type->output and skb->nh will be set to the nextheader field
42 * of the extension header directly preceding the encapsulation header, or in
43 * its absence, that of the top IP header. The value of skb->data will always
44 * point to the top IP header.
45 */
46static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
47{
48 struct ipv6hdr *iph;
49 u8 *prevhdr;
50 int hdr_len;
51
52 skb_push(skb, x->props.header_len);
53 iph = skb->nh.ipv6h;
54
55 hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
56 skb->nh.raw = prevhdr - x->props.header_len;
57 skb->h.raw = skb->data + hdr_len;
58 memmove(skb->data, iph, hdr_len);
59 return 0;
60}
61
62/*
63 * Do nothing about routing optimization header unlike IPsec.
64 */
65static int xfrm6_ro_input(struct xfrm_state *x, struct sk_buff *skb)
66{
67 return 0;
68}
69
70static struct xfrm_mode xfrm6_ro_mode = {
71 .input = xfrm6_ro_input,
72 .output = xfrm6_ro_output,
73 .owner = THIS_MODULE,
74 .encap = XFRM_MODE_ROUTEOPTIMIZATION,
75};
76
77static int __init xfrm6_ro_init(void)
78{
79 return xfrm_register_mode(&xfrm6_ro_mode, AF_INET6);
80}
81
82static void __exit xfrm6_ro_exit(void)
83{
84 int err;
85
86 err = xfrm_unregister_mode(&xfrm6_ro_mode, AF_INET6);
87 BUG_ON(err);
88}
89
90module_init(xfrm6_ro_init);
91module_exit(xfrm6_ro_exit);
92MODULE_LICENSE("GPL");
93MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_ROUTEOPTIMIZATION);
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c
index 711d713e36d8..3a4b39b12bad 100644
--- a/net/ipv6/xfrm6_mode_transport.c
+++ b/net/ipv6/xfrm6_mode_transport.c
@@ -25,9 +25,8 @@
25 * its absence, that of the top IP header. The value of skb->data will always 25 * its absence, that of the top IP header. The value of skb->data will always
26 * point to the top IP header. 26 * point to the top IP header.
27 */ 27 */
28static int xfrm6_transport_output(struct sk_buff *skb) 28static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
29{ 29{
30 struct xfrm_state *x = skb->dst->xfrm;
31 struct ipv6hdr *iph; 30 struct ipv6hdr *iph;
32 u8 *prevhdr; 31 u8 *prevhdr;
33 int hdr_len; 32 int hdr_len;
@@ -35,7 +34,7 @@ static int xfrm6_transport_output(struct sk_buff *skb)
35 skb_push(skb, x->props.header_len); 34 skb_push(skb, x->props.header_len);
36 iph = skb->nh.ipv6h; 35 iph = skb->nh.ipv6h;
37 36
38 hdr_len = ip6_find_1stfragopt(skb, &prevhdr); 37 hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
39 skb->nh.raw = prevhdr - x->props.header_len; 38 skb->nh.raw = prevhdr - x->props.header_len;
40 skb->h.raw = skb->data + hdr_len; 39 skb->h.raw = skb->data + hdr_len;
41 memmove(skb->data, iph, hdr_len); 40 memmove(skb->data, iph, hdr_len);
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 8af79be2edca..5e7d8a7d6414 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -37,10 +37,9 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
37 * its absence, that of the top IP header. The value of skb->data will always 37 * its absence, that of the top IP header. The value of skb->data will always
38 * point to the top IP header. 38 * point to the top IP header.
39 */ 39 */
40static int xfrm6_tunnel_output(struct sk_buff *skb) 40static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
41{ 41{
42 struct dst_entry *dst = skb->dst; 42 struct dst_entry *dst = skb->dst;
43 struct xfrm_state *x = dst->xfrm;
44 struct ipv6hdr *iph, *top_iph; 43 struct ipv6hdr *iph, *top_iph;
45 int dsfield; 44 int dsfield;
46 45
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 48fccb1eca08..c260ea104c52 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -17,6 +17,12 @@
17#include <net/ipv6.h> 17#include <net/ipv6.h>
18#include <net/xfrm.h> 18#include <net/xfrm.h>
19 19
20int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
21 u8 **prevhdr)
22{
23 return ip6_find_1stfragopt(skb, prevhdr);
24}
25
20static int xfrm6_tunnel_check_size(struct sk_buff *skb) 26static int xfrm6_tunnel_check_size(struct sk_buff *skb)
21{ 27{
22 int mtu, ret = 0; 28 int mtu, ret = 0;
@@ -41,13 +47,13 @@ static int xfrm6_output_one(struct sk_buff *skb)
41 struct xfrm_state *x = dst->xfrm; 47 struct xfrm_state *x = dst->xfrm;
42 int err; 48 int err;
43 49
44 if (skb->ip_summed == CHECKSUM_HW) { 50 if (skb->ip_summed == CHECKSUM_PARTIAL) {
45 err = skb_checksum_help(skb, 0); 51 err = skb_checksum_help(skb);
46 if (err) 52 if (err)
47 goto error_nolock; 53 goto error_nolock;
48 } 54 }
49 55
50 if (x->props.mode) { 56 if (x->props.mode == XFRM_MODE_TUNNEL) {
51 err = xfrm6_tunnel_check_size(skb); 57 err = xfrm6_tunnel_check_size(skb);
52 if (err) 58 if (err)
53 goto error_nolock; 59 goto error_nolock;
@@ -59,7 +65,7 @@ static int xfrm6_output_one(struct sk_buff *skb)
59 if (err) 65 if (err)
60 goto error; 66 goto error;
61 67
62 err = x->mode->output(skb); 68 err = x->mode->output(x, skb);
63 if (err) 69 if (err)
64 goto error; 70 goto error;
65 71
@@ -69,6 +75,8 @@ static int xfrm6_output_one(struct sk_buff *skb)
69 75
70 x->curlft.bytes += skb->len; 76 x->curlft.bytes += skb->len;
71 x->curlft.packets++; 77 x->curlft.packets++;
78 if (x->props.mode == XFRM_MODE_ROUTEOPTIMIZATION)
79 x->lastused = (u64)xtime.tv_sec;
72 80
73 spin_unlock_bh(&x->lock); 81 spin_unlock_bh(&x->lock);
74 82
@@ -80,7 +88,7 @@ static int xfrm6_output_one(struct sk_buff *skb)
80 } 88 }
81 dst = skb->dst; 89 dst = skb->dst;
82 x = dst->xfrm; 90 x = dst->xfrm;
83 } while (x && !x->props.mode); 91 } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
84 92
85 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; 93 IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
86 err = 0; 94 err = 0;
@@ -122,10 +130,10 @@ static int xfrm6_output_finish(struct sk_buff *skb)
122{ 130{
123 struct sk_buff *segs; 131 struct sk_buff *segs;
124 132
125 if (!skb_shinfo(skb)->gso_size) 133 if (!skb_is_gso(skb))
126 return xfrm6_output_finish2(skb); 134 return xfrm6_output_finish2(skb);
127 135
128 skb->protocol = htons(ETH_P_IP); 136 skb->protocol = htons(ETH_P_IPV6);
129 segs = skb_gso_segment(skb, 0); 137 segs = skb_gso_segment(skb, 0);
130 kfree_skb(skb); 138 kfree_skb(skb);
131 if (unlikely(IS_ERR(segs))) 139 if (unlikely(IS_ERR(segs)))
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index ee715f2691e9..6a252e2134d1 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -12,13 +12,15 @@
12 */ 12 */
13 13
14#include <linux/compiler.h> 14#include <linux/compiler.h>
15#include <linux/config.h>
16#include <linux/netdevice.h> 15#include <linux/netdevice.h>
17#include <net/addrconf.h> 16#include <net/addrconf.h>
18#include <net/xfrm.h> 17#include <net/xfrm.h>
19#include <net/ip.h> 18#include <net/ip.h>
20#include <net/ipv6.h> 19#include <net/ipv6.h>
21#include <net/ip6_route.h> 20#include <net/ip6_route.h>
21#ifdef CONFIG_IPV6_MIP6
22#include <net/mip6.h>
23#endif
22 24
23static struct dst_ops xfrm6_dst_ops; 25static struct dst_ops xfrm6_dst_ops;
24static struct xfrm_policy_afinfo xfrm6_policy_afinfo; 26static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
@@ -32,6 +34,26 @@ static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
32 return err; 34 return err;
33} 35}
34 36
37static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
38{
39 struct rt6_info *rt;
40 struct flowi fl_tunnel = {
41 .nl_u = {
42 .ip6_u = {
43 .daddr = *(struct in6_addr *)&daddr->a6,
44 },
45 },
46 };
47
48 if (!xfrm6_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
49 ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)&daddr->a6,
50 (struct in6_addr *)&saddr->a6);
51 dst_release(&rt->u.dst);
52 return 0;
53 }
54 return -EHOSTUNREACH;
55}
56
35static struct dst_entry * 57static struct dst_entry *
36__xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy) 58__xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
37{ 59{
@@ -51,7 +73,9 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
51 xdst->u.rt6.rt6i_src.plen); 73 xdst->u.rt6.rt6i_src.plen);
52 if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && 74 if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) &&
53 ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && 75 ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) &&
54 xfrm_bundle_ok(xdst, fl, AF_INET6)) { 76 xfrm_bundle_ok(xdst, fl, AF_INET6,
77 (xdst->u.rt6.rt6i_dst.plen != 128 ||
78 xdst->u.rt6.rt6i_src.plen != 128))) {
55 dst_clone(dst); 79 dst_clone(dst);
56 break; 80 break;
57 } 81 }
@@ -60,6 +84,40 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
60 return dst; 84 return dst;
61} 85}
62 86
87static inline struct in6_addr*
88__xfrm6_bundle_addr_remote(struct xfrm_state *x, struct in6_addr *addr)
89{
90 return (x->type->remote_addr) ?
91 (struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t *)addr) :
92 (struct in6_addr*)&x->id.daddr;
93}
94
95static inline struct in6_addr*
96__xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
97{
98 return (x->type->local_addr) ?
99 (struct in6_addr*)x->type->local_addr(x, (xfrm_address_t *)addr) :
100 (struct in6_addr*)&x->props.saddr;
101}
102
103static inline void
104__xfrm6_bundle_len_inc(int *len, int *nflen, struct xfrm_state *x)
105{
106 if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)
107 *nflen += x->props.header_len;
108 else
109 *len += x->props.header_len;
110}
111
112static inline void
113__xfrm6_bundle_len_dec(int *len, int *nflen, struct xfrm_state *x)
114{
115 if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)
116 *nflen -= x->props.header_len;
117 else
118 *len -= x->props.header_len;
119}
120
63/* Allocate chain of dst_entry's, attach known xfrm's, calculate 121/* Allocate chain of dst_entry's, attach known xfrm's, calculate
64 * all the metrics... Shortly, bundle a bundle. 122 * all the metrics... Shortly, bundle a bundle.
65 */ 123 */
@@ -84,6 +142,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
84 int i; 142 int i;
85 int err = 0; 143 int err = 0;
86 int header_len = 0; 144 int header_len = 0;
145 int nfheader_len = 0;
87 int trailer_len = 0; 146 int trailer_len = 0;
88 147
89 dst = dst_prev = NULL; 148 dst = dst_prev = NULL;
@@ -110,17 +169,18 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
110 169
111 xdst = (struct xfrm_dst *)dst1; 170 xdst = (struct xfrm_dst *)dst1;
112 xdst->route = &rt->u.dst; 171 xdst->route = &rt->u.dst;
172 xdst->genid = xfrm[i]->genid;
113 if (rt->rt6i_node) 173 if (rt->rt6i_node)
114 xdst->route_cookie = rt->rt6i_node->fn_sernum; 174 xdst->route_cookie = rt->rt6i_node->fn_sernum;
115 175
116 dst1->next = dst_prev; 176 dst1->next = dst_prev;
117 dst_prev = dst1; 177 dst_prev = dst1;
118 if (xfrm[i]->props.mode) { 178 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
119 remote = (struct in6_addr*)&xfrm[i]->id.daddr; 179 remote = __xfrm6_bundle_addr_remote(xfrm[i], remote);
120 local = (struct in6_addr*)&xfrm[i]->props.saddr; 180 local = __xfrm6_bundle_addr_local(xfrm[i], local);
121 tunnel = 1; 181 tunnel = 1;
122 } 182 }
123 header_len += xfrm[i]->props.header_len; 183 __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
124 trailer_len += xfrm[i]->props.trailer_len; 184 trailer_len += xfrm[i]->props.trailer_len;
125 185
126 if (tunnel) { 186 if (tunnel) {
@@ -155,6 +215,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
155 dst_prev->flags |= DST_HOST; 215 dst_prev->flags |= DST_HOST;
156 dst_prev->lastuse = jiffies; 216 dst_prev->lastuse = jiffies;
157 dst_prev->header_len = header_len; 217 dst_prev->header_len = header_len;
218 dst_prev->nfheader_len = nfheader_len;
158 dst_prev->trailer_len = trailer_len; 219 dst_prev->trailer_len = trailer_len;
159 memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); 220 memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
160 221
@@ -173,7 +234,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
173 x->u.rt6.rt6i_src = rt0->rt6i_src; 234 x->u.rt6.rt6i_src = rt0->rt6i_src;
174 x->u.rt6.rt6i_idev = rt0->rt6i_idev; 235 x->u.rt6.rt6i_idev = rt0->rt6i_idev;
175 in6_dev_hold(rt0->rt6i_idev); 236 in6_dev_hold(rt0->rt6i_idev);
176 header_len -= x->u.dst.xfrm->props.header_len; 237 __xfrm6_bundle_len_dec(&header_len, &nfheader_len, x->u.dst.xfrm);
177 trailer_len -= x->u.dst.xfrm->props.trailer_len; 238 trailer_len -= x->u.dst.xfrm->props.trailer_len;
178 } 239 }
179 240
@@ -233,6 +294,18 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
233 fl->proto = nexthdr; 294 fl->proto = nexthdr;
234 return; 295 return;
235 296
297#ifdef CONFIG_IPV6_MIP6
298 case IPPROTO_MH:
299 if (pskb_may_pull(skb, skb->nh.raw + offset + 3 - skb->data)) {
300 struct ip6_mh *mh;
301 mh = (struct ip6_mh *)exthdr;
302
303 fl->fl_mh_type = mh->ip6mh_type;
304 }
305 fl->proto = nexthdr;
306 return;
307#endif
308
236 /* XXX Why are there these headers? */ 309 /* XXX Why are there these headers? */
237 case IPPROTO_AH: 310 case IPPROTO_AH:
238 case IPPROTO_ESP: 311 case IPPROTO_ESP:
@@ -309,6 +382,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
309 .family = AF_INET6, 382 .family = AF_INET6,
310 .dst_ops = &xfrm6_dst_ops, 383 .dst_ops = &xfrm6_dst_ops,
311 .dst_lookup = xfrm6_dst_lookup, 384 .dst_lookup = xfrm6_dst_lookup,
385 .get_saddr = xfrm6_get_saddr,
312 .find_bundle = __xfrm6_find_bundle, 386 .find_bundle = __xfrm6_find_bundle,
313 .bundle_create = __xfrm6_bundle_create, 387 .bundle_create = __xfrm6_bundle_create,
314 .decode_session = _decode_session6, 388 .decode_session = _decode_session6,
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index b33296b3f6de..9ddaa9d41539 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -29,9 +29,9 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
29 ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst); 29 ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
30 ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src); 30 ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
31 x->sel.dport = xfrm_flowi_dport(fl); 31 x->sel.dport = xfrm_flowi_dport(fl);
32 x->sel.dport_mask = ~0; 32 x->sel.dport_mask = htons(0xffff);
33 x->sel.sport = xfrm_flowi_sport(fl); 33 x->sel.sport = xfrm_flowi_sport(fl);
34 x->sel.sport_mask = ~0; 34 x->sel.sport_mask = htons(0xffff);
35 x->sel.prefixlen_d = 128; 35 x->sel.prefixlen_d = 128;
36 x->sel.prefixlen_s = 128; 36 x->sel.prefixlen_s = 128;
37 x->sel.proto = fl->proto; 37 x->sel.proto = fl->proto;
@@ -42,102 +42,135 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
42 memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr)); 42 memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
43 if (ipv6_addr_any((struct in6_addr*)&x->props.saddr)) 43 if (ipv6_addr_any((struct in6_addr*)&x->props.saddr))
44 memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr)); 44 memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr));
45 if (tmpl->mode && ipv6_addr_any((struct in6_addr*)&x->props.saddr)) {
46 struct rt6_info *rt;
47 struct flowi fl_tunnel = {
48 .nl_u = {
49 .ip6_u = {
50 .daddr = *(struct in6_addr *)daddr,
51 }
52 }
53 };
54 if (!xfrm_dst_lookup((struct xfrm_dst **)&rt,
55 &fl_tunnel, AF_INET6)) {
56 ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)daddr,
57 (struct in6_addr *)&x->props.saddr);
58 dst_release(&rt->u.dst);
59 }
60 }
61 x->props.mode = tmpl->mode; 45 x->props.mode = tmpl->mode;
62 x->props.reqid = tmpl->reqid; 46 x->props.reqid = tmpl->reqid;
63 x->props.family = AF_INET6; 47 x->props.family = AF_INET6;
64} 48}
65 49
66static struct xfrm_state * 50static int
67__xfrm6_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto) 51__xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
68{ 52{
69 unsigned h = __xfrm6_spi_hash(daddr, spi, proto); 53 int i;
70 struct xfrm_state *x; 54 int j = 0;
71 55
72 list_for_each_entry(x, xfrm6_state_afinfo.state_byspi+h, byspi) { 56 /* Rule 1: select IPsec transport except AH */
73 if (x->props.family == AF_INET6 && 57 for (i = 0; i < n; i++) {
74 spi == x->id.spi && 58 if (src[i]->props.mode == XFRM_MODE_TRANSPORT &&
75 ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) && 59 src[i]->id.proto != IPPROTO_AH) {
76 proto == x->id.proto) { 60 dst[j++] = src[i];
77 xfrm_state_hold(x); 61 src[i] = NULL;
78 return x; 62 }
63 }
64 if (j == n)
65 goto end;
66
67 /* Rule 2: select MIPv6 RO or inbound trigger */
68#ifdef CONFIG_IPV6_MIP6
69 for (i = 0; i < n; i++) {
70 if (src[i] &&
71 (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
72 src[i]->props.mode == XFRM_MODE_IN_TRIGGER)) {
73 dst[j++] = src[i];
74 src[i] = NULL;
75 }
76 }
77 if (j == n)
78 goto end;
79#endif
80
81 /* Rule 3: select IPsec transport AH */
82 for (i = 0; i < n; i++) {
83 if (src[i] &&
84 src[i]->props.mode == XFRM_MODE_TRANSPORT &&
85 src[i]->id.proto == IPPROTO_AH) {
86 dst[j++] = src[i];
87 src[i] = NULL;
79 } 88 }
80 } 89 }
81 return NULL; 90 if (j == n)
91 goto end;
92
93 /* Rule 4: select IPsec tunnel */
94 for (i = 0; i < n; i++) {
95 if (src[i] &&
96 src[i]->props.mode == XFRM_MODE_TUNNEL) {
97 dst[j++] = src[i];
98 src[i] = NULL;
99 }
100 }
101 if (likely(j == n))
102 goto end;
103
104 /* Final rule */
105 for (i = 0; i < n; i++) {
106 if (src[i]) {
107 dst[j++] = src[i];
108 src[i] = NULL;
109 }
110 }
111
112 end:
113 return 0;
82} 114}
83 115
84static struct xfrm_state * 116static int
85__xfrm6_find_acq(u8 mode, u32 reqid, u8 proto, 117__xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
86 xfrm_address_t *daddr, xfrm_address_t *saddr,
87 int create)
88{ 118{
89 struct xfrm_state *x, *x0; 119 int i;
90 unsigned h = __xfrm6_dst_hash(daddr); 120 int j = 0;
91 121
92 x0 = NULL; 122 /* Rule 1: select IPsec transport */
93 123 for (i = 0; i < n; i++) {
94 list_for_each_entry(x, xfrm6_state_afinfo.state_bydst+h, bydst) { 124 if (src[i]->mode == XFRM_MODE_TRANSPORT) {
95 if (x->props.family == AF_INET6 && 125 dst[j++] = src[i];
96 ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) && 126 src[i] = NULL;
97 mode == x->props.mode && 127 }
98 proto == x->id.proto &&
99 ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) &&
100 reqid == x->props.reqid &&
101 x->km.state == XFRM_STATE_ACQ &&
102 !x->id.spi) {
103 x0 = x;
104 break;
105 }
106 } 128 }
107 if (!x0 && create && (x0 = xfrm_state_alloc()) != NULL) { 129 if (j == n)
108 ipv6_addr_copy((struct in6_addr *)x0->sel.daddr.a6, 130 goto end;
109 (struct in6_addr *)daddr); 131
110 ipv6_addr_copy((struct in6_addr *)x0->sel.saddr.a6, 132 /* Rule 2: select MIPv6 RO or inbound trigger */
111 (struct in6_addr *)saddr); 133#ifdef CONFIG_IPV6_MIP6
112 x0->sel.prefixlen_d = 128; 134 for (i = 0; i < n; i++) {
113 x0->sel.prefixlen_s = 128; 135 if (src[i] &&
114 ipv6_addr_copy((struct in6_addr *)x0->props.saddr.a6, 136 (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||
115 (struct in6_addr *)saddr); 137 src[i]->mode == XFRM_MODE_IN_TRIGGER)) {
116 x0->km.state = XFRM_STATE_ACQ; 138 dst[j++] = src[i];
117 ipv6_addr_copy((struct in6_addr *)x0->id.daddr.a6, 139 src[i] = NULL;
118 (struct in6_addr *)daddr); 140 }
119 x0->id.proto = proto;
120 x0->props.family = AF_INET6;
121 x0->props.mode = mode;
122 x0->props.reqid = reqid;
123 x0->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
124 xfrm_state_hold(x0);
125 x0->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
126 add_timer(&x0->timer);
127 xfrm_state_hold(x0);
128 list_add_tail(&x0->bydst, xfrm6_state_afinfo.state_bydst+h);
129 wake_up(&km_waitq);
130 } 141 }
131 if (x0) 142 if (j == n)
132 xfrm_state_hold(x0); 143 goto end;
133 return x0; 144#endif
145
146 /* Rule 3: select IPsec tunnel */
147 for (i = 0; i < n; i++) {
148 if (src[i] &&
149 src[i]->mode == XFRM_MODE_TUNNEL) {
150 dst[j++] = src[i];
151 src[i] = NULL;
152 }
153 }
154 if (likely(j == n))
155 goto end;
156
157 /* Final rule */
158 for (i = 0; i < n; i++) {
159 if (src[i]) {
160 dst[j++] = src[i];
161 src[i] = NULL;
162 }
163 }
164
165 end:
166 return 0;
134} 167}
135 168
136static struct xfrm_state_afinfo xfrm6_state_afinfo = { 169static struct xfrm_state_afinfo xfrm6_state_afinfo = {
137 .family = AF_INET6, 170 .family = AF_INET6,
138 .init_tempsel = __xfrm6_init_tempsel, 171 .init_tempsel = __xfrm6_init_tempsel,
139 .state_lookup = __xfrm6_state_lookup, 172 .tmpl_sort = __xfrm6_tmpl_sort,
140 .find_acq = __xfrm6_find_acq, 173 .state_sort = __xfrm6_state_sort,
141}; 174};
142 175
143void __init xfrm6_state_init(void) 176void __init xfrm6_state_init(void)
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index d37768e5064f..7af227bb1551 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -21,7 +21,6 @@
21 * Based on net/ipv4/xfrm4_tunnel.c 21 * Based on net/ipv4/xfrm4_tunnel.c
22 * 22 *
23 */ 23 */
24#include <linux/config.h>
25#include <linux/module.h> 24#include <linux/module.h>
26#include <linux/xfrm.h> 25#include <linux/xfrm.h>
27#include <linux/list.h> 26#include <linux/list.h>
@@ -32,27 +31,6 @@
32#include <linux/icmpv6.h> 31#include <linux/icmpv6.h>
33#include <linux/mutex.h> 32#include <linux/mutex.h>
34 33
35#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
36# define X6TDEBUG 3
37#else
38# define X6TDEBUG 1
39#endif
40
41#define X6TPRINTK(fmt, args...) printk(fmt, ## args)
42#define X6TNOPRINTK(fmt, args...) do { ; } while(0)
43
44#if X6TDEBUG >= 1
45# define X6TPRINTK1 X6TPRINTK
46#else
47# define X6TPRINTK1 X6TNOPRINTK
48#endif
49
50#if X6TDEBUG >= 3
51# define X6TPRINTK3 X6TPRINTK
52#else
53# define X6TPRINTK3 X6TNOPRINTK
54#endif
55
56/* 34/*
57 * xfrm_tunnel_spi things are for allocating unique id ("spi") 35 * xfrm_tunnel_spi things are for allocating unique id ("spi")
58 * per xfrm_address_t. 36 * per xfrm_address_t.
@@ -63,15 +41,8 @@ struct xfrm6_tunnel_spi {
63 xfrm_address_t addr; 41 xfrm_address_t addr;
64 u32 spi; 42 u32 spi;
65 atomic_t refcnt; 43 atomic_t refcnt;
66#ifdef XFRM6_TUNNEL_SPI_MAGIC
67 u32 magic;
68#endif
69}; 44};
70 45
71#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG
72# define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
73#endif
74
75static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock); 46static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
76 47
77static u32 xfrm6_tunnel_spi; 48static u32 xfrm6_tunnel_spi;
@@ -87,43 +58,15 @@ static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly;
87static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE]; 58static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
88static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE]; 59static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
89 60
90#ifdef XFRM6_TUNNEL_SPI_MAGIC
91static int x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi,
92 const char *name)
93{
94 if (unlikely(x6spi->magic != XFRM6_TUNNEL_SPI_MAGIC)) {
95 X6TPRINTK3(KERN_DEBUG "%s(): x6spi object "
96 "at %p has corrupted magic %08x "
97 "(should be %08x)\n",
98 name, x6spi, x6spi->magic, XFRM6_TUNNEL_SPI_MAGIC);
99 return -1;
100 }
101 return 0;
102}
103#else
104static int inline x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi,
105 const char *name)
106{
107 return 0;
108}
109#endif
110
111#define X6SPI_CHECK_MAGIC(x6spi) x6spi_check_magic((x6spi), __FUNCTION__)
112
113
114static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) 61static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
115{ 62{
116 unsigned h; 63 unsigned h;
117 64
118 X6TPRINTK3(KERN_DEBUG "%s(addr=%p)\n", __FUNCTION__, addr);
119
120 h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]; 65 h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3];
121 h ^= h >> 16; 66 h ^= h >> 16;
122 h ^= h >> 8; 67 h ^= h >> 8;
123 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1; 68 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;
124 69
125 X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, h);
126
127 return h; 70 return h;
128} 71}
129 72
@@ -137,19 +80,13 @@ static int xfrm6_tunnel_spi_init(void)
137{ 80{
138 int i; 81 int i;
139 82
140 X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
141
142 xfrm6_tunnel_spi = 0; 83 xfrm6_tunnel_spi = 0;
143 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi", 84 xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi",
144 sizeof(struct xfrm6_tunnel_spi), 85 sizeof(struct xfrm6_tunnel_spi),
145 0, SLAB_HWCACHE_ALIGN, 86 0, SLAB_HWCACHE_ALIGN,
146 NULL, NULL); 87 NULL, NULL);
147 if (!xfrm6_tunnel_spi_kmem) { 88 if (!xfrm6_tunnel_spi_kmem)
148 X6TPRINTK1(KERN_ERR
149 "%s(): failed to allocate xfrm6_tunnel_spi_kmem\n",
150 __FUNCTION__);
151 return -ENOMEM; 89 return -ENOMEM;
152 }
153 90
154 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) 91 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
155 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]); 92 INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]);
@@ -162,22 +99,16 @@ static void xfrm6_tunnel_spi_fini(void)
162{ 99{
163 int i; 100 int i;
164 101
165 X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
166
167 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) { 102 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) {
168 if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i])) 103 if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i]))
169 goto err; 104 return;
170 } 105 }
171 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) { 106 for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) {
172 if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i])) 107 if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
173 goto err; 108 return;
174 } 109 }
175 kmem_cache_destroy(xfrm6_tunnel_spi_kmem); 110 kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
176 xfrm6_tunnel_spi_kmem = NULL; 111 xfrm6_tunnel_spi_kmem = NULL;
177 return;
178err:
179 X6TPRINTK1(KERN_ERR "%s(): table is not empty\n", __FUNCTION__);
180 return;
181} 112}
182 113
183static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 114static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
@@ -185,19 +116,13 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
185 struct xfrm6_tunnel_spi *x6spi; 116 struct xfrm6_tunnel_spi *x6spi;
186 struct hlist_node *pos; 117 struct hlist_node *pos;
187 118
188 X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
189
190 hlist_for_each_entry(x6spi, pos, 119 hlist_for_each_entry(x6spi, pos,
191 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], 120 &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
192 list_byaddr) { 121 list_byaddr) {
193 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { 122 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
194 X6SPI_CHECK_MAGIC(x6spi);
195 X6TPRINTK3(KERN_DEBUG "%s() = %p(%u)\n", __FUNCTION__, x6spi, x6spi->spi);
196 return x6spi; 123 return x6spi;
197 }
198 } 124 }
199 125
200 X6TPRINTK3(KERN_DEBUG "%s() = NULL(0)\n", __FUNCTION__);
201 return NULL; 126 return NULL;
202} 127}
203 128
@@ -206,8 +131,6 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
206 struct xfrm6_tunnel_spi *x6spi; 131 struct xfrm6_tunnel_spi *x6spi;
207 u32 spi; 132 u32 spi;
208 133
209 X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
210
211 read_lock_bh(&xfrm6_tunnel_spi_lock); 134 read_lock_bh(&xfrm6_tunnel_spi_lock);
212 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 135 x6spi = __xfrm6_tunnel_spi_lookup(saddr);
213 spi = x6spi ? x6spi->spi : 0; 136 spi = x6spi ? x6spi->spi : 0;
@@ -224,8 +147,6 @@ static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
224 struct hlist_node *pos; 147 struct hlist_node *pos;
225 unsigned index; 148 unsigned index;
226 149
227 X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
228
229 if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || 150 if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN ||
230 xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) 151 xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX)
231 xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN; 152 xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN;
@@ -259,18 +180,10 @@ try_next_2:;
259 spi = 0; 180 spi = 0;
260 goto out; 181 goto out;
261alloc_spi: 182alloc_spi:
262 X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " NIP6_FMT "\n",
263 __FUNCTION__,
264 NIP6(*(struct in6_addr *)saddr));
265 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC); 183 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC);
266 if (!x6spi) { 184 if (!x6spi)
267 X6TPRINTK1(KERN_ERR "%s(): kmem_cache_alloc() failed\n",
268 __FUNCTION__);
269 goto out; 185 goto out;
270 } 186
271#ifdef XFRM6_TUNNEL_SPI_MAGIC
272 x6spi->magic = XFRM6_TUNNEL_SPI_MAGIC;
273#endif
274 memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr)); 187 memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
275 x6spi->spi = spi; 188 x6spi->spi = spi;
276 atomic_set(&x6spi->refcnt, 1); 189 atomic_set(&x6spi->refcnt, 1);
@@ -279,9 +192,7 @@ alloc_spi:
279 192
280 index = xfrm6_tunnel_spi_hash_byaddr(saddr); 193 index = xfrm6_tunnel_spi_hash_byaddr(saddr);
281 hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]); 194 hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
282 X6SPI_CHECK_MAGIC(x6spi);
283out: 195out:
284 X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi);
285 return spi; 196 return spi;
286} 197}
287 198
@@ -290,8 +201,6 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
290 struct xfrm6_tunnel_spi *x6spi; 201 struct xfrm6_tunnel_spi *x6spi;
291 u32 spi; 202 u32 spi;
292 203
293 X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
294
295 write_lock_bh(&xfrm6_tunnel_spi_lock); 204 write_lock_bh(&xfrm6_tunnel_spi_lock);
296 x6spi = __xfrm6_tunnel_spi_lookup(saddr); 205 x6spi = __xfrm6_tunnel_spi_lookup(saddr);
297 if (x6spi) { 206 if (x6spi) {
@@ -301,8 +210,6 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
301 spi = __xfrm6_tunnel_alloc_spi(saddr); 210 spi = __xfrm6_tunnel_alloc_spi(saddr);
302 write_unlock_bh(&xfrm6_tunnel_spi_lock); 211 write_unlock_bh(&xfrm6_tunnel_spi_lock);
303 212
304 X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi);
305
306 return spi; 213 return spi;
307} 214}
308 215
@@ -313,8 +220,6 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
313 struct xfrm6_tunnel_spi *x6spi; 220 struct xfrm6_tunnel_spi *x6spi;
314 struct hlist_node *pos, *n; 221 struct hlist_node *pos, *n;
315 222
316 X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr);
317
318 write_lock_bh(&xfrm6_tunnel_spi_lock); 223 write_lock_bh(&xfrm6_tunnel_spi_lock);
319 224
320 hlist_for_each_entry_safe(x6spi, pos, n, 225 hlist_for_each_entry_safe(x6spi, pos, n,
@@ -322,12 +227,6 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
322 list_byaddr) 227 list_byaddr)
323 { 228 {
324 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { 229 if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
325 X6TPRINTK3(KERN_DEBUG "%s(): x6spi object for " NIP6_FMT
326 " found at %p\n",
327 __FUNCTION__,
328 NIP6(*(struct in6_addr *)saddr),
329 x6spi);
330 X6SPI_CHECK_MAGIC(x6spi);
331 if (atomic_dec_and_test(&x6spi->refcnt)) { 230 if (atomic_dec_and_test(&x6spi->refcnt)) {
332 hlist_del(&x6spi->list_byaddr); 231 hlist_del(&x6spi->list_byaddr);
333 hlist_del(&x6spi->list_byspi); 232 hlist_del(&x6spi->list_byspi);
@@ -359,7 +258,7 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
359static int xfrm6_tunnel_rcv(struct sk_buff *skb) 258static int xfrm6_tunnel_rcv(struct sk_buff *skb)
360{ 259{
361 struct ipv6hdr *iph = skb->nh.ipv6h; 260 struct ipv6hdr *iph = skb->nh.ipv6h;
362 u32 spi; 261 __be32 spi;
363 262
364 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 263 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
365 return xfrm6_rcv_spi(skb, spi); 264 return xfrm6_rcv_spi(skb, spi);
@@ -378,20 +277,14 @@ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
378 case ICMPV6_ADDR_UNREACH: 277 case ICMPV6_ADDR_UNREACH:
379 case ICMPV6_PORT_UNREACH: 278 case ICMPV6_PORT_UNREACH:
380 default: 279 default:
381 X6TPRINTK3(KERN_DEBUG
382 "xfrm6_tunnel: Destination Unreach.\n");
383 break; 280 break;
384 } 281 }
385 break; 282 break;
386 case ICMPV6_PKT_TOOBIG: 283 case ICMPV6_PKT_TOOBIG:
387 X6TPRINTK3(KERN_DEBUG
388 "xfrm6_tunnel: Packet Too Big.\n");
389 break; 284 break;
390 case ICMPV6_TIME_EXCEED: 285 case ICMPV6_TIME_EXCEED:
391 switch (code) { 286 switch (code) {
392 case ICMPV6_EXC_HOPLIMIT: 287 case ICMPV6_EXC_HOPLIMIT:
393 X6TPRINTK3(KERN_DEBUG
394 "xfrm6_tunnel: Too small Hoplimit.\n");
395 break; 288 break;
396 case ICMPV6_EXC_FRAGTIME: 289 case ICMPV6_EXC_FRAGTIME:
397 default: 290 default:
@@ -414,7 +307,7 @@ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
414 307
415static int xfrm6_tunnel_init_state(struct xfrm_state *x) 308static int xfrm6_tunnel_init_state(struct xfrm_state *x)
416{ 309{
417 if (!x->props.mode) 310 if (x->props.mode != XFRM_MODE_TUNNEL)
418 return -EINVAL; 311 return -EINVAL;
419 312
420 if (x->encap) 313 if (x->encap)
@@ -448,22 +341,14 @@ static struct xfrm6_tunnel xfrm6_tunnel_handler = {
448 341
449static int __init xfrm6_tunnel_init(void) 342static int __init xfrm6_tunnel_init(void)
450{ 343{
451 X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); 344 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0)
452
453 if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) {
454 X6TPRINTK1(KERN_ERR
455 "xfrm6_tunnel init: can't add xfrm type\n");
456 return -EAGAIN; 345 return -EAGAIN;
457 } 346
458 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) { 347 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {
459 X6TPRINTK1(KERN_ERR
460 "xfrm6_tunnel init(): can't add handler\n");
461 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 348 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
462 return -EAGAIN; 349 return -EAGAIN;
463 } 350 }
464 if (xfrm6_tunnel_spi_init() < 0) { 351 if (xfrm6_tunnel_spi_init() < 0) {
465 X6TPRINTK1(KERN_ERR
466 "xfrm6_tunnel init: failed to initialize spi\n");
467 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); 352 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
468 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 353 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
469 return -EAGAIN; 354 return -EAGAIN;
@@ -473,15 +358,9 @@ static int __init xfrm6_tunnel_init(void)
473 358
474static void __exit xfrm6_tunnel_fini(void) 359static void __exit xfrm6_tunnel_fini(void)
475{ 360{
476 X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
477
478 xfrm6_tunnel_spi_fini(); 361 xfrm6_tunnel_spi_fini();
479 if (xfrm6_tunnel_deregister(&xfrm6_tunnel_handler)) 362 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
480 X6TPRINTK1(KERN_ERR 363 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
481 "xfrm6_tunnel close: can't remove handler\n");
482 if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0)
483 X6TPRINTK1(KERN_ERR
484 "xfrm6_tunnel close: can't remove xfrm type\n");
485} 364}
486 365
487module_init(xfrm6_tunnel_init); 366module_init(xfrm6_tunnel_init);