aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/Kconfig7
-rw-r--r--net/ipv6/Makefile4
-rw-r--r--net/ipv6/addrconf.c190
-rw-r--r--net/ipv6/af_inet6.c27
-rw-r--r--net/ipv6/ah6.c5
-rw-r--r--net/ipv6/datagram.c16
-rw-r--r--net/ipv6/esp6.c2
-rw-r--r--net/ipv6/exthdrs.c59
-rw-r--r--net/ipv6/exthdrs_core.c2
-rw-r--r--net/ipv6/fib6_rules.c60
-rw-r--r--net/ipv6/icmp.c23
-rw-r--r--net/ipv6/inet6_connection_sock.c17
-rw-r--r--net/ipv6/inet6_hashtables.c6
-rw-r--r--net/ipv6/ip6_fib.c8
-rw-r--r--net/ipv6/ip6_flowlabel.c8
-rw-r--r--net/ipv6/ip6_input.c42
-rw-r--r--net/ipv6/ip6_output.c84
-rw-r--r--net/ipv6/ip6_tunnel.c296
-rw-r--r--net/ipv6/ipcomp6.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c11
-rw-r--r--net/ipv6/mcast.c36
-rw-r--r--net/ipv6/mip6.c4
-rw-r--r--net/ipv6/ndisc.c29
-rw-r--r--net/ipv6/netfilter.c11
-rw-r--r--net/ipv6/netfilter/Kconfig2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c3
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c23
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c9
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c93
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c40
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c26
-rw-r--r--net/ipv6/proc.c18
-rw-r--r--net/ipv6/raw.c25
-rw-r--r--net/ipv6/reassembly.c87
-rw-r--r--net/ipv6/route.c97
-rw-r--r--net/ipv6/sit.c22
-rw-r--r--net/ipv6/tcp_ipv6.c607
-rw-r--r--net/ipv6/tunnel6.c2
-rw-r--r--net/ipv6/udp.c426
-rw-r--r--net/ipv6/udp_impl.h34
-rw-r--r--net/ipv6/udplite.c105
-rw-r--r--net/ipv6/xfrm6_policy.c3
-rw-r--r--net/ipv6/xfrm6_tunnel.c8
44 files changed, 1592 insertions, 991 deletions
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 6e48f52e197c..deb4101a2a81 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -196,10 +196,3 @@ config IPV6_SUBTREES
196 196
197 If unsure, say N. 197 If unsure, say N.
198 198
199config IPV6_ROUTE_FWMARK
200 bool "IPv6: use netfilter MARK value as routing key"
201 depends on IPV6_MULTIPLE_TABLES && NETFILTER
202 ---help---
203 If you say Y here, you will be able to specify different routes for
204 packets with different mark values (see iptables(8), MARK target).
205
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index addcc011bc01..8bacda109b7f 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -5,8 +5,8 @@
5obj-$(CONFIG_IPV6) += ipv6.o 5obj-$(CONFIG_IPV6) += ipv6.o
6 6
7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ 7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ 8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
9 protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ 9 raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ 10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
11 ip6_flowlabel.o ipv6_syms.o inet6_connection_sock.o 11 ip6_flowlabel.o ipv6_syms.o inet6_connection_sock.o
12 12
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b312a5f7a759..a5e8d207a51b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -232,7 +232,7 @@ static inline unsigned ipv6_addr_scope2type(unsigned scope)
232 232
233int __ipv6_addr_type(const struct in6_addr *addr) 233int __ipv6_addr_type(const struct in6_addr *addr)
234{ 234{
235 u32 st; 235 __be32 st;
236 236
237 st = addr->s6_addr32[0]; 237 st = addr->s6_addr32[0];
238 238
@@ -1164,7 +1164,7 @@ record_it:
1164int ipv6_get_saddr(struct dst_entry *dst, 1164int ipv6_get_saddr(struct dst_entry *dst,
1165 struct in6_addr *daddr, struct in6_addr *saddr) 1165 struct in6_addr *daddr, struct in6_addr *saddr)
1166{ 1166{
1167 return ipv6_dev_get_saddr(dst ? ((struct rt6_info *)dst)->rt6i_idev->dev : NULL, daddr, saddr); 1167 return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr);
1168} 1168}
1169 1169
1170 1170
@@ -3098,10 +3098,9 @@ static inline int rt_scope(int ifa_scope)
3098 3098
3099static inline int inet6_ifaddr_msgsize(void) 3099static inline int inet6_ifaddr_msgsize(void)
3100{ 3100{
3101 return nlmsg_total_size(sizeof(struct ifaddrmsg) + 3101 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
3102 nla_total_size(16) + 3102 + nla_total_size(16) /* IFA_ADDRESS */
3103 nla_total_size(sizeof(struct ifa_cacheinfo)) + 3103 + nla_total_size(sizeof(struct ifa_cacheinfo));
3104 128);
3105} 3104}
3106 3105
3107static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3106static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
@@ -3329,10 +3328,8 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3329 3328
3330 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3329 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3331 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3330 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3332 if (err < 0) { 3331 /* failure implies BUG in inet6_ifaddr_msgsize() */
3333 kfree_skb(skb); 3332 BUG_ON(err < 0);
3334 goto errout_ifa;
3335 }
3336 3333
3337 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); 3334 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
3338errout_ifa: 3335errout_ifa:
@@ -3351,10 +3348,8 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3351 goto errout; 3348 goto errout;
3352 3349
3353 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); 3350 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3354 if (err < 0) { 3351 /* failure implies BUG in inet6_ifaddr_msgsize() */
3355 kfree_skb(skb); 3352 BUG_ON(err < 0);
3356 goto errout;
3357 }
3358 3353
3359 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3354 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3360errout: 3355errout:
@@ -3365,6 +3360,8 @@ errout:
3365static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, 3360static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
3366 __s32 *array, int bytes) 3361 __s32 *array, int bytes)
3367{ 3362{
3363 BUG_ON(bytes < (DEVCONF_MAX * 4));
3364
3368 memset(array, 0, bytes); 3365 memset(array, 0, bytes);
3369 array[DEVCONF_FORWARDING] = cnf->forwarding; 3366 array[DEVCONF_FORWARDING] = cnf->forwarding;
3370 array[DEVCONF_HOPLIMIT] = cnf->hop_limit; 3367 array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
@@ -3397,80 +3394,76 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
3397 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; 3394 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
3398} 3395}
3399 3396
3400/* Maximum length of ifinfomsg attributes */ 3397static inline size_t inet6_if_nlmsg_size(void)
3401#define INET6_IFINFO_RTA_SPACE \ 3398{
3402 RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \ 3399 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
3403 RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \ 3400 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
3404 RTA_SPACE(sizeof(u32)) /* MTU */ + \ 3401 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
3405 RTA_SPACE(sizeof(int)) /* LINK */ + \ 3402 + nla_total_size(4) /* IFLA_MTU */
3406 RTA_SPACE(0) /* PROTINFO */ + \ 3403 + nla_total_size(4) /* IFLA_LINK */
3407 RTA_SPACE(sizeof(u32)) /* FLAGS */ + \ 3404 + nla_total_size( /* IFLA_PROTINFO */
3408 RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \ 3405 nla_total_size(4) /* IFLA_INET6_FLAGS */
3409 RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */ 3406 + nla_total_size(sizeof(struct ifla_cacheinfo))
3407 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
3408 );
3409}
3410 3410
3411static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 3411static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3412 u32 pid, u32 seq, int event, unsigned int flags) 3412 u32 pid, u32 seq, int event, unsigned int flags)
3413{ 3413{
3414 struct net_device *dev = idev->dev; 3414 struct net_device *dev = idev->dev;
3415 __s32 *array = NULL; 3415 struct nlattr *conf;
3416 struct ifinfomsg *r; 3416 struct ifinfomsg *hdr;
3417 struct nlmsghdr *nlh; 3417 struct nlmsghdr *nlh;
3418 unsigned char *b = skb->tail; 3418 void *protoinfo;
3419 struct rtattr *subattr; 3419 struct ifla_cacheinfo ci;
3420 __u32 mtu = dev->mtu; 3420
3421 struct ifla_cacheinfo ci; 3421 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
3422 3422 if (nlh == NULL)
3423 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 3423 return -ENOBUFS;
3424 r = NLMSG_DATA(nlh); 3424
3425 r->ifi_family = AF_INET6; 3425 hdr = nlmsg_data(nlh);
3426 r->__ifi_pad = 0; 3426 hdr->ifi_family = AF_INET6;
3427 r->ifi_type = dev->type; 3427 hdr->__ifi_pad = 0;
3428 r->ifi_index = dev->ifindex; 3428 hdr->ifi_type = dev->type;
3429 r->ifi_flags = dev_get_flags(dev); 3429 hdr->ifi_index = dev->ifindex;
3430 r->ifi_change = 0; 3430 hdr->ifi_flags = dev_get_flags(dev);
3431 3431 hdr->ifi_change = 0;
3432 RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); 3432
3433 NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
3433 3434
3434 if (dev->addr_len) 3435 if (dev->addr_len)
3435 RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 3436 NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
3436 3437
3437 RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu); 3438 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
3438 if (dev->ifindex != dev->iflink) 3439 if (dev->ifindex != dev->iflink)
3439 RTA_PUT(skb, IFLA_LINK, sizeof(int), &dev->iflink); 3440 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
3440
3441 subattr = (struct rtattr*)skb->tail;
3442 3441
3443 RTA_PUT(skb, IFLA_PROTINFO, 0, NULL); 3442 protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
3443 if (protoinfo == NULL)
3444 goto nla_put_failure;
3444 3445
3445 /* return the device flags */ 3446 NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
3446 RTA_PUT(skb, IFLA_INET6_FLAGS, sizeof(__u32), &idev->if_flags);
3447 3447
3448 /* return interface cacheinfo */
3449 ci.max_reasm_len = IPV6_MAXPLEN; 3448 ci.max_reasm_len = IPV6_MAXPLEN;
3450 ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 3449 ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
3451 + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); 3450 + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3452 ci.reachable_time = idev->nd_parms->reachable_time; 3451 ci.reachable_time = idev->nd_parms->reachable_time;
3453 ci.retrans_time = idev->nd_parms->retrans_time; 3452 ci.retrans_time = idev->nd_parms->retrans_time;
3454 RTA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); 3453 NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
3455 3454
3456 /* return the device sysctl params */ 3455 conf = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
3457 if ((array = kmalloc(DEVCONF_MAX * sizeof(*array), GFP_ATOMIC)) == NULL) 3456 if (conf == NULL)
3458 goto rtattr_failure; 3457 goto nla_put_failure;
3459 ipv6_store_devconf(&idev->cnf, array, DEVCONF_MAX * sizeof(*array)); 3458 ipv6_store_devconf(&idev->cnf, nla_data(conf), nla_len(conf));
3460 RTA_PUT(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(*array), array);
3461 3459
3462 /* XXX - Statistics/MC not implemented */ 3460 /* XXX - Statistics/MC not implemented */
3463 subattr->rta_len = skb->tail - (u8*)subattr;
3464 3461
3465 nlh->nlmsg_len = skb->tail - b; 3462 nla_nest_end(skb, protoinfo);
3466 kfree(array); 3463 return nlmsg_end(skb, nlh);
3467 return skb->len;
3468 3464
3469nlmsg_failure: 3465nla_put_failure:
3470rtattr_failure: 3466 return nlmsg_cancel(skb, nlh);
3471 kfree(array);
3472 skb_trim(skb, b - skb->data);
3473 return -1;
3474} 3467}
3475 3468
3476static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3469static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
@@ -3501,18 +3494,15 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3501void inet6_ifinfo_notify(int event, struct inet6_dev *idev) 3494void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3502{ 3495{
3503 struct sk_buff *skb; 3496 struct sk_buff *skb;
3504 int payload = sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE;
3505 int err = -ENOBUFS; 3497 int err = -ENOBUFS;
3506 3498
3507 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3499 skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
3508 if (skb == NULL) 3500 if (skb == NULL)
3509 goto errout; 3501 goto errout;
3510 3502
3511 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); 3503 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3512 if (err < 0) { 3504 /* failure implies BUG in inet6_if_nlmsg_size() */
3513 kfree_skb(skb); 3505 BUG_ON(err < 0);
3514 goto errout;
3515 }
3516 3506
3517 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3507 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3518errout: 3508errout:
@@ -3520,22 +3510,26 @@ errout:
3520 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err); 3510 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
3521} 3511}
3522 3512
3523/* Maximum length of prefix_cacheinfo attributes */ 3513static inline size_t inet6_prefix_nlmsg_size(void)
3524#define INET6_PREFIX_RTA_SPACE \ 3514{
3525 RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \ 3515 return NLMSG_ALIGN(sizeof(struct prefixmsg))
3526 RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */ 3516 + nla_total_size(sizeof(struct in6_addr))
3517 + nla_total_size(sizeof(struct prefix_cacheinfo));
3518}
3527 3519
3528static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 3520static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3529 struct prefix_info *pinfo, u32 pid, u32 seq, 3521 struct prefix_info *pinfo, u32 pid, u32 seq,
3530 int event, unsigned int flags) 3522 int event, unsigned int flags)
3531{ 3523{
3532 struct prefixmsg *pmsg; 3524 struct prefixmsg *pmsg;
3533 struct nlmsghdr *nlh; 3525 struct nlmsghdr *nlh;
3534 unsigned char *b = skb->tail;
3535 struct prefix_cacheinfo ci; 3526 struct prefix_cacheinfo ci;
3536 3527
3537 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); 3528 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
3538 pmsg = NLMSG_DATA(nlh); 3529 if (nlh == NULL)
3530 return -ENOBUFS;
3531
3532 pmsg = nlmsg_data(nlh);
3539 pmsg->prefix_family = AF_INET6; 3533 pmsg->prefix_family = AF_INET6;
3540 pmsg->prefix_pad1 = 0; 3534 pmsg->prefix_pad1 = 0;
3541 pmsg->prefix_pad2 = 0; 3535 pmsg->prefix_pad2 = 0;
@@ -3543,44 +3537,37 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3543 pmsg->prefix_len = pinfo->prefix_len; 3537 pmsg->prefix_len = pinfo->prefix_len;
3544 pmsg->prefix_type = pinfo->type; 3538 pmsg->prefix_type = pinfo->type;
3545 pmsg->prefix_pad3 = 0; 3539 pmsg->prefix_pad3 = 0;
3546
3547 pmsg->prefix_flags = 0; 3540 pmsg->prefix_flags = 0;
3548 if (pinfo->onlink) 3541 if (pinfo->onlink)
3549 pmsg->prefix_flags |= IF_PREFIX_ONLINK; 3542 pmsg->prefix_flags |= IF_PREFIX_ONLINK;
3550 if (pinfo->autoconf) 3543 if (pinfo->autoconf)
3551 pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; 3544 pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;
3552 3545
3553 RTA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix); 3546 NLA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix);
3554 3547
3555 ci.preferred_time = ntohl(pinfo->prefered); 3548 ci.preferred_time = ntohl(pinfo->prefered);
3556 ci.valid_time = ntohl(pinfo->valid); 3549 ci.valid_time = ntohl(pinfo->valid);
3557 RTA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci); 3550 NLA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci);
3558 3551
3559 nlh->nlmsg_len = skb->tail - b; 3552 return nlmsg_end(skb, nlh);
3560 return skb->len;
3561 3553
3562nlmsg_failure: 3554nla_put_failure:
3563rtattr_failure: 3555 return nlmsg_cancel(skb, nlh);
3564 skb_trim(skb, b - skb->data);
3565 return -1;
3566} 3556}
3567 3557
3568static void inet6_prefix_notify(int event, struct inet6_dev *idev, 3558static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3569 struct prefix_info *pinfo) 3559 struct prefix_info *pinfo)
3570{ 3560{
3571 struct sk_buff *skb; 3561 struct sk_buff *skb;
3572 int payload = sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE;
3573 int err = -ENOBUFS; 3562 int err = -ENOBUFS;
3574 3563
3575 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3564 skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
3576 if (skb == NULL) 3565 if (skb == NULL)
3577 goto errout; 3566 goto errout;
3578 3567
3579 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); 3568 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3580 if (err < 0) { 3569 /* failure implies BUG in inet6_prefix_nlmsg_size() */
3581 kfree_skb(skb); 3570 BUG_ON(err < 0);
3582 goto errout;
3583 }
3584 3571
3585 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); 3572 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3586errout: 3573errout:
@@ -3982,10 +3969,9 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
3982 struct addrconf_sysctl_table *t; 3969 struct addrconf_sysctl_table *t;
3983 char *dev_name = NULL; 3970 char *dev_name = NULL;
3984 3971
3985 t = kmalloc(sizeof(*t), GFP_KERNEL); 3972 t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
3986 if (t == NULL) 3973 if (t == NULL)
3987 return; 3974 return;
3988 memcpy(t, &addrconf_sysctl, sizeof(*t));
3989 for (i=0; t->addrconf_vars[i].data; i++) { 3975 for (i=0; t->addrconf_vars[i].data; i++) {
3990 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf; 3976 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
3991 t->addrconf_vars[i].de = NULL; 3977 t->addrconf_vars[i].de = NULL;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 858cae29581c..87c8f54872b7 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -49,6 +49,7 @@
49#include <net/ip.h> 49#include <net/ip.h>
50#include <net/ipv6.h> 50#include <net/ipv6.h>
51#include <net/udp.h> 51#include <net/udp.h>
52#include <net/udplite.h>
52#include <net/tcp.h> 53#include <net/tcp.h>
53#include <net/ipip.h> 54#include <net/ipip.h>
54#include <net/protocol.h> 55#include <net/protocol.h>
@@ -221,7 +222,7 @@ lookup_protocol:
221 * the user to assign a number at socket 222 * the user to assign a number at socket
222 * creation time automatically shares. 223 * creation time automatically shares.
223 */ 224 */
224 inet->sport = ntohs(inet->num); 225 inet->sport = htons(inet->num);
225 sk->sk_prot->hash(sk); 226 sk->sk_prot->hash(sk);
226 } 227 }
227 if (sk->sk_prot->init) { 228 if (sk->sk_prot->init) {
@@ -341,7 +342,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
341 sk->sk_userlocks |= SOCK_BINDADDR_LOCK; 342 sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
342 if (snum) 343 if (snum)
343 sk->sk_userlocks |= SOCK_BINDPORT_LOCK; 344 sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
344 inet->sport = ntohs(inet->num); 345 inet->sport = htons(inet->num);
345 inet->dport = 0; 346 inet->dport = 0;
346 inet->daddr = 0; 347 inet->daddr = 0;
347out: 348out:
@@ -678,7 +679,7 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
678 if (np->rxopt.all) { 679 if (np->rxopt.all) {
679 if ((opt->hop && (np->rxopt.bits.hopopts || 680 if ((opt->hop && (np->rxopt.bits.hopopts ||
680 np->rxopt.bits.ohopopts)) || 681 np->rxopt.bits.ohopopts)) ||
681 ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && 682 ((IPV6_FLOWINFO_MASK & *(__be32*)skb->nh.raw) &&
682 np->rxopt.bits.rxflow) || 683 np->rxopt.bits.rxflow) ||
683 (opt->srcrt && (np->rxopt.bits.srcrt || 684 (opt->srcrt && (np->rxopt.bits.srcrt ||
684 np->rxopt.bits.osrcrt)) || 685 np->rxopt.bits.osrcrt)) ||
@@ -737,8 +738,13 @@ static int __init init_ipv6_mibs(void)
737 if (snmp6_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib), 738 if (snmp6_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),
738 __alignof__(struct udp_mib)) < 0) 739 __alignof__(struct udp_mib)) < 0)
739 goto err_udp_mib; 740 goto err_udp_mib;
741 if (snmp6_mib_init((void **)udplite_stats_in6, sizeof (struct udp_mib),
742 __alignof__(struct udp_mib)) < 0)
743 goto err_udplite_mib;
740 return 0; 744 return 0;
741 745
746err_udplite_mib:
747 snmp6_mib_free((void **)udp_stats_in6);
742err_udp_mib: 748err_udp_mib:
743 snmp6_mib_free((void **)icmpv6_statistics); 749 snmp6_mib_free((void **)icmpv6_statistics);
744err_icmp_mib: 750err_icmp_mib:
@@ -753,6 +759,7 @@ static void cleanup_ipv6_mibs(void)
753 snmp6_mib_free((void **)ipv6_statistics); 759 snmp6_mib_free((void **)ipv6_statistics);
754 snmp6_mib_free((void **)icmpv6_statistics); 760 snmp6_mib_free((void **)icmpv6_statistics);
755 snmp6_mib_free((void **)udp_stats_in6); 761 snmp6_mib_free((void **)udp_stats_in6);
762 snmp6_mib_free((void **)udplite_stats_in6);
756} 763}
757 764
758static int __init inet6_init(void) 765static int __init inet6_init(void)
@@ -780,10 +787,14 @@ static int __init inet6_init(void)
780 if (err) 787 if (err)
781 goto out_unregister_tcp_proto; 788 goto out_unregister_tcp_proto;
782 789
783 err = proto_register(&rawv6_prot, 1); 790 err = proto_register(&udplitev6_prot, 1);
784 if (err) 791 if (err)
785 goto out_unregister_udp_proto; 792 goto out_unregister_udp_proto;
786 793
794 err = proto_register(&rawv6_prot, 1);
795 if (err)
796 goto out_unregister_udplite_proto;
797
787 798
788 /* Register the socket-side information for inet6_create. */ 799 /* Register the socket-side information for inet6_create. */
789 for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) 800 for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
@@ -837,6 +848,8 @@ static int __init inet6_init(void)
837 goto proc_tcp6_fail; 848 goto proc_tcp6_fail;
838 if (udp6_proc_init()) 849 if (udp6_proc_init())
839 goto proc_udp6_fail; 850 goto proc_udp6_fail;
851 if (udplite6_proc_init())
852 goto proc_udplite6_fail;
840 if (ipv6_misc_proc_init()) 853 if (ipv6_misc_proc_init())
841 goto proc_misc6_fail; 854 goto proc_misc6_fail;
842 855
@@ -862,6 +875,7 @@ static int __init inet6_init(void)
862 875
863 /* Init v6 transport protocols. */ 876 /* Init v6 transport protocols. */
864 udpv6_init(); 877 udpv6_init();
878 udplitev6_init();
865 tcpv6_init(); 879 tcpv6_init();
866 880
867 ipv6_packet_init(); 881 ipv6_packet_init();
@@ -879,6 +893,8 @@ proc_if6_fail:
879proc_anycast6_fail: 893proc_anycast6_fail:
880 ipv6_misc_proc_exit(); 894 ipv6_misc_proc_exit();
881proc_misc6_fail: 895proc_misc6_fail:
896 udplite6_proc_exit();
897proc_udplite6_fail:
882 udp6_proc_exit(); 898 udp6_proc_exit();
883proc_udp6_fail: 899proc_udp6_fail:
884 tcp6_proc_exit(); 900 tcp6_proc_exit();
@@ -902,6 +918,8 @@ out_unregister_sock:
902 sock_unregister(PF_INET6); 918 sock_unregister(PF_INET6);
903out_unregister_raw_proto: 919out_unregister_raw_proto:
904 proto_unregister(&rawv6_prot); 920 proto_unregister(&rawv6_prot);
921out_unregister_udplite_proto:
922 proto_unregister(&udplitev6_prot);
905out_unregister_udp_proto: 923out_unregister_udp_proto:
906 proto_unregister(&udpv6_prot); 924 proto_unregister(&udpv6_prot);
907out_unregister_tcp_proto: 925out_unregister_tcp_proto:
@@ -919,6 +937,7 @@ static void __exit inet6_exit(void)
919 ac6_proc_exit(); 937 ac6_proc_exit();
920 ipv6_misc_proc_exit(); 938 ipv6_misc_proc_exit();
921 udp6_proc_exit(); 939 udp6_proc_exit();
940 udplite6_proc_exit();
922 tcp6_proc_exit(); 941 tcp6_proc_exit();
923 raw6_proc_exit(); 942 raw6_proc_exit();
924#endif 943#endif
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index b0d83e8e4252..12c5a4dec09e 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -354,10 +354,9 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
354 if (!pskb_may_pull(skb, ah_hlen)) 354 if (!pskb_may_pull(skb, ah_hlen))
355 goto out; 355 goto out;
356 356
357 tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC); 357 tmp_hdr = kmemdup(skb->nh.raw, hdr_len, GFP_ATOMIC);
358 if (!tmp_hdr) 358 if (!tmp_hdr)
359 goto out; 359 goto out;
360 memcpy(tmp_hdr, skb->nh.raw, hdr_len);
361 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN)) 360 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
362 goto free_out; 361 goto free_out;
363 skb->nh.ipv6h->priority = 0; 362 skb->nh.ipv6h->priority = 0;
@@ -397,7 +396,7 @@ out:
397} 396}
398 397
399static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 398static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
400 int type, int code, int offset, __u32 info) 399 int type, int code, int offset, __be32 info)
401{ 400{
402 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 401 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
403 struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); 402 struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 7206747022fc..5c94fea90e97 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -207,7 +207,7 @@ out:
207} 207}
208 208
209void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 209void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
210 u16 port, u32 info, u8 *payload) 210 __be16 port, u32 info, u8 *payload)
211{ 211{
212 struct ipv6_pinfo *np = inet6_sk(sk); 212 struct ipv6_pinfo *np = inet6_sk(sk);
213 struct icmp6hdr *icmph = (struct icmp6hdr *)skb->h.raw; 213 struct icmp6hdr *icmph = (struct icmp6hdr *)skb->h.raw;
@@ -318,13 +318,13 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
318 ipv6_addr_copy(&sin->sin6_addr, 318 ipv6_addr_copy(&sin->sin6_addr,
319 (struct in6_addr *)(skb->nh.raw + serr->addr_offset)); 319 (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
320 if (np->sndflow) 320 if (np->sndflow)
321 sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK; 321 sin->sin6_flowinfo = *(__be32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
322 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 322 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
323 sin->sin6_scope_id = IP6CB(skb)->iif; 323 sin->sin6_scope_id = IP6CB(skb)->iif;
324 } else { 324 } else {
325 ipv6_addr_set(&sin->sin6_addr, 0, 0, 325 ipv6_addr_set(&sin->sin6_addr, 0, 0,
326 htonl(0xffff), 326 htonl(0xffff),
327 *(u32*)(skb->nh.raw + serr->addr_offset)); 327 *(__be32*)(skb->nh.raw + serr->addr_offset));
328 } 328 }
329 } 329 }
330 330
@@ -397,12 +397,12 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
397 } 397 }
398 398
399 if (np->rxopt.bits.rxtclass) { 399 if (np->rxopt.bits.rxtclass) {
400 int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff; 400 int tclass = (ntohl(*(__be32 *)skb->nh.ipv6h) >> 20) & 0xff;
401 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass); 401 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
402 } 402 }
403 403
404 if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) { 404 if (np->rxopt.bits.rxflow && (*(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
405 u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK; 405 __be32 flowinfo = *(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
406 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo); 406 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
407 } 407 }
408 408
@@ -560,12 +560,12 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
560 } 560 }
561 561
562 if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) { 562 if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) {
563 if ((fl->fl6_flowlabel^*(u32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) { 563 if ((fl->fl6_flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
564 err = -EINVAL; 564 err = -EINVAL;
565 goto exit_f; 565 goto exit_f;
566 } 566 }
567 } 567 }
568 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg); 568 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
569 break; 569 break;
570 570
571 case IPV6_2292HOPOPTS: 571 case IPV6_2292HOPOPTS:
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index e78680a9985b..25dcf69cd807 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -256,7 +256,7 @@ static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
256} 256}
257 257
258static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 258static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
259 int type, int code, int offset, __u32 info) 259 int type, int code, int offset, __be32 info)
260{ 260{
261 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 261 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
262 struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset); 262 struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 88c96b10684c..0711f92d6a12 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -284,10 +284,12 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
284#ifdef CONFIG_IPV6_MIP6 284#ifdef CONFIG_IPV6_MIP6
285 __u16 dstbuf; 285 __u16 dstbuf;
286#endif 286#endif
287 struct dst_entry *dst;
287 288
288 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 289 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
289 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 290 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
290 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 291 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
292 IPSTATS_MIB_INHDRERRORS);
291 kfree_skb(skb); 293 kfree_skb(skb);
292 return -1; 294 return -1;
293 } 295 }
@@ -298,7 +300,9 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
298 dstbuf = opt->dst1; 300 dstbuf = opt->dst1;
299#endif 301#endif
300 302
303 dst = dst_clone(skb->dst);
301 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { 304 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
305 dst_release(dst);
302 skb = *skbp; 306 skb = *skbp;
303 skb->h.raw += ((skb->h.raw[1]+1)<<3); 307 skb->h.raw += ((skb->h.raw[1]+1)<<3);
304 opt = IP6CB(skb); 308 opt = IP6CB(skb);
@@ -310,7 +314,8 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
310 return 1; 314 return 1;
311 } 315 }
312 316
313 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 317 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
318 dst_release(dst);
314 return -1; 319 return -1;
315} 320}
316 321
@@ -365,7 +370,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
365 370
366 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 371 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
367 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 372 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
368 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 373 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
374 IPSTATS_MIB_INHDRERRORS);
369 kfree_skb(skb); 375 kfree_skb(skb);
370 return -1; 376 return -1;
371 } 377 }
@@ -374,7 +380,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
374 380
375 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || 381 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
376 skb->pkt_type != PACKET_HOST) { 382 skb->pkt_type != PACKET_HOST) {
377 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 383 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
384 IPSTATS_MIB_INADDRERRORS);
378 kfree_skb(skb); 385 kfree_skb(skb);
379 return -1; 386 return -1;
380 } 387 }
@@ -388,7 +395,8 @@ looped_back:
388 * processed by own 395 * processed by own
389 */ 396 */
390 if (!addr) { 397 if (!addr) {
391 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 398 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
399 IPSTATS_MIB_INADDRERRORS);
392 kfree_skb(skb); 400 kfree_skb(skb);
393 return -1; 401 return -1;
394 } 402 }
@@ -410,7 +418,8 @@ looped_back:
410 switch (hdr->type) { 418 switch (hdr->type) {
411 case IPV6_SRCRT_TYPE_0: 419 case IPV6_SRCRT_TYPE_0:
412 if (hdr->hdrlen & 0x01) { 420 if (hdr->hdrlen & 0x01) {
413 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 421 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
422 IPSTATS_MIB_INHDRERRORS);
414 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); 423 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
415 return -1; 424 return -1;
416 } 425 }
@@ -419,14 +428,16 @@ looped_back:
419 case IPV6_SRCRT_TYPE_2: 428 case IPV6_SRCRT_TYPE_2:
420 /* Silently discard invalid RTH type 2 */ 429 /* Silently discard invalid RTH type 2 */
421 if (hdr->hdrlen != 2 || hdr->segments_left != 1) { 430 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
422 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 431 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
432 IPSTATS_MIB_INHDRERRORS);
423 kfree_skb(skb); 433 kfree_skb(skb);
424 return -1; 434 return -1;
425 } 435 }
426 break; 436 break;
427#endif 437#endif
428 default: 438 default:
429 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 439 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
440 IPSTATS_MIB_INHDRERRORS);
430 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); 441 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
431 return -1; 442 return -1;
432 } 443 }
@@ -439,7 +450,8 @@ looped_back:
439 n = hdr->hdrlen >> 1; 450 n = hdr->hdrlen >> 1;
440 451
441 if (hdr->segments_left > n) { 452 if (hdr->segments_left > n) {
442 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 453 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
454 IPSTATS_MIB_INHDRERRORS);
443 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); 455 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
444 return -1; 456 return -1;
445 } 457 }
@@ -449,12 +461,14 @@ looped_back:
449 */ 461 */
450 if (skb_cloned(skb)) { 462 if (skb_cloned(skb)) {
451 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); 463 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
452 kfree_skb(skb);
453 /* the copy is a forwarded packet */ 464 /* the copy is a forwarded packet */
454 if (skb2 == NULL) { 465 if (skb2 == NULL) {
455 IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS); 466 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
467 IPSTATS_MIB_OUTDISCARDS);
468 kfree_skb(skb);
456 return -1; 469 return -1;
457 } 470 }
471 kfree_skb(skb);
458 *skbp = skb = skb2; 472 *skbp = skb = skb2;
459 opt = IP6CB(skb2); 473 opt = IP6CB(skb2);
460 hdr = (struct ipv6_rt_hdr *) skb2->h.raw; 474 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
@@ -475,12 +489,14 @@ looped_back:
475 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 489 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
476 (xfrm_address_t *)&skb->nh.ipv6h->saddr, 490 (xfrm_address_t *)&skb->nh.ipv6h->saddr,
477 IPPROTO_ROUTING) < 0) { 491 IPPROTO_ROUTING) < 0) {
478 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 492 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
493 IPSTATS_MIB_INADDRERRORS);
479 kfree_skb(skb); 494 kfree_skb(skb);
480 return -1; 495 return -1;
481 } 496 }
482 if (!ipv6_chk_home_addr(addr)) { 497 if (!ipv6_chk_home_addr(addr)) {
483 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 498 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
499 IPSTATS_MIB_INADDRERRORS);
484 kfree_skb(skb); 500 kfree_skb(skb);
485 return -1; 501 return -1;
486 } 502 }
@@ -491,7 +507,8 @@ looped_back:
491 } 507 }
492 508
493 if (ipv6_addr_is_multicast(addr)) { 509 if (ipv6_addr_is_multicast(addr)) {
494 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 510 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
511 IPSTATS_MIB_INADDRERRORS);
495 kfree_skb(skb); 512 kfree_skb(skb);
496 return -1; 513 return -1;
497 } 514 }
@@ -510,7 +527,8 @@ looped_back:
510 527
511 if (skb->dst->dev->flags&IFF_LOOPBACK) { 528 if (skb->dst->dev->flags&IFF_LOOPBACK) {
512 if (skb->nh.ipv6h->hop_limit <= 1) { 529 if (skb->nh.ipv6h->hop_limit <= 1) {
513 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 530 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
531 IPSTATS_MIB_INHDRERRORS);
514 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 532 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
515 0, skb->dev); 533 0, skb->dev);
516 kfree_skb(skb); 534 kfree_skb(skb);
@@ -632,24 +650,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
632 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { 650 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
633 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 651 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
634 skb->nh.raw[optoff+1]); 652 skb->nh.raw[optoff+1]);
635 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 653 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
654 IPSTATS_MIB_INHDRERRORS);
636 goto drop; 655 goto drop;
637 } 656 }
638 657
639 pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); 658 pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2));
640 if (pkt_len <= IPV6_MAXPLEN) { 659 if (pkt_len <= IPV6_MAXPLEN) {
641 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 660 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
642 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); 661 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
643 return 0; 662 return 0;
644 } 663 }
645 if (skb->nh.ipv6h->payload_len) { 664 if (skb->nh.ipv6h->payload_len) {
646 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 665 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
647 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); 666 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
648 return 0; 667 return 0;
649 } 668 }
650 669
651 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { 670 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
652 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); 671 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
653 goto drop; 672 goto drop;
654 } 673 }
655 674
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 315bc1fbec3f..21cbbbddaf4d 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -77,7 +77,7 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp)
77 if (hp == NULL) 77 if (hp == NULL)
78 return -1; 78 return -1;
79 if (nexthdr == NEXTHDR_FRAGMENT) { 79 if (nexthdr == NEXTHDR_FRAGMENT) {
80 unsigned short _frag_off, *fp; 80 __be16 _frag_off, *fp;
81 fp = skb_header_pointer(skb, 81 fp = skb_header_pointer(skb,
82 start+offsetof(struct frag_hdr, 82 start+offsetof(struct frag_hdr,
83 frag_off), 83 frag_off),
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 1896ecb52899..0862809ffcf7 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -25,10 +25,6 @@ struct fib6_rule
25 struct fib_rule common; 25 struct fib_rule common;
26 struct rt6key src; 26 struct rt6key src;
27 struct rt6key dst; 27 struct rt6key dst;
28#ifdef CONFIG_IPV6_ROUTE_FWMARK
29 u32 fwmark;
30 u32 fwmask;
31#endif
32 u8 tclass; 28 u8 tclass;
33}; 29};
34 30
@@ -67,7 +63,7 @@ struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
67 fib_rule_put(arg.rule); 63 fib_rule_put(arg.rule);
68 64
69 if (arg.result) 65 if (arg.result)
70 return (struct dst_entry *) arg.result; 66 return arg.result;
71 67
72 dst_hold(&ip6_null_entry.u.dst); 68 dst_hold(&ip6_null_entry.u.dst);
73 return &ip6_null_entry.u.dst; 69 return &ip6_null_entry.u.dst;
@@ -130,22 +126,13 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
130 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) 126 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
131 return 0; 127 return 0;
132 128
133#ifdef CONFIG_IPV6_ROUTE_FWMARK
134 if ((r->fwmark ^ fl->fl6_fwmark) & r->fwmask)
135 return 0;
136#endif
137
138 return 1; 129 return 1;
139} 130}
140 131
141static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { 132static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
142 [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 133 FRA_GENERIC_POLICY,
143 [FRA_PRIORITY] = { .type = NLA_U32 },
144 [FRA_SRC] = { .len = sizeof(struct in6_addr) }, 134 [FRA_SRC] = { .len = sizeof(struct in6_addr) },
145 [FRA_DST] = { .len = sizeof(struct in6_addr) }, 135 [FRA_DST] = { .len = sizeof(struct in6_addr) },
146 [FRA_FWMARK] = { .type = NLA_U32 },
147 [FRA_FWMASK] = { .type = NLA_U32 },
148 [FRA_TABLE] = { .type = NLA_U32 },
149}; 136};
150 137
151static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, 138static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
@@ -155,8 +142,7 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
155 int err = -EINVAL; 142 int err = -EINVAL;
156 struct fib6_rule *rule6 = (struct fib6_rule *) rule; 143 struct fib6_rule *rule6 = (struct fib6_rule *) rule;
157 144
158 if (frh->src_len > 128 || frh->dst_len > 128 || 145 if (frh->src_len > 128 || frh->dst_len > 128)
159 (frh->tos & ~IPV6_FLOWINFO_MASK))
160 goto errout; 146 goto errout;
161 147
162 if (rule->action == FR_ACT_TO_TBL) { 148 if (rule->action == FR_ACT_TO_TBL) {
@@ -177,23 +163,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
177 nla_memcpy(&rule6->dst.addr, tb[FRA_DST], 163 nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
178 sizeof(struct in6_addr)); 164 sizeof(struct in6_addr));
179 165
180#ifdef CONFIG_IPV6_ROUTE_FWMARK
181 if (tb[FRA_FWMARK]) {
182 rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
183 if (rule6->fwmark) {
184 /*
185 * if the mark value is non-zero,
186 * all bits are compared by default
187 * unless a mask is explicitly specified.
188 */
189 rule6->fwmask = 0xFFFFFFFF;
190 }
191 }
192
193 if (tb[FRA_FWMASK])
194 rule6->fwmask = nla_get_u32(tb[FRA_FWMASK]);
195#endif
196
197 rule6->src.plen = frh->src_len; 166 rule6->src.plen = frh->src_len;
198 rule6->dst.plen = frh->dst_len; 167 rule6->dst.plen = frh->dst_len;
199 rule6->tclass = frh->tos; 168 rule6->tclass = frh->tos;
@@ -225,14 +194,6 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
225 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) 194 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
226 return 0; 195 return 0;
227 196
228#ifdef CONFIG_IPV6_ROUTE_FWMARK
229 if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
230 return 0;
231
232 if (tb[FRA_FWMASK] && (rule6->fwmask != nla_get_u32(tb[FRA_FWMASK])))
233 return 0;
234#endif
235
236 return 1; 197 return 1;
237} 198}
238 199
@@ -254,14 +215,6 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
254 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr), 215 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
255 &rule6->src.addr); 216 &rule6->src.addr);
256 217
257#ifdef CONFIG_IPV6_ROUTE_FWMARK
258 if (rule6->fwmark)
259 NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);
260
261 if (rule6->fwmask || rule6->fwmark)
262 NLA_PUT_U32(skb, FRA_FWMASK, rule6->fwmask);
263#endif
264
265 return 0; 218 return 0;
266 219
267nla_put_failure: 220nla_put_failure:
@@ -278,6 +231,12 @@ static u32 fib6_rule_default_pref(void)
278 return 0x3FFF; 231 return 0x3FFF;
279} 232}
280 233
234static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
235{
236 return nla_total_size(16) /* dst */
237 + nla_total_size(16); /* src */
238}
239
281static struct fib_rules_ops fib6_rules_ops = { 240static struct fib_rules_ops fib6_rules_ops = {
282 .family = AF_INET6, 241 .family = AF_INET6,
283 .rule_size = sizeof(struct fib6_rule), 242 .rule_size = sizeof(struct fib6_rule),
@@ -287,6 +246,7 @@ static struct fib_rules_ops fib6_rules_ops = {
287 .compare = fib6_rule_compare, 246 .compare = fib6_rule_compare,
288 .fill = fib6_rule_fill, 247 .fill = fib6_rule_fill,
289 .default_pref = fib6_rule_default_pref, 248 .default_pref = fib6_rule_default_pref,
249 .nlmsg_payload = fib6_rule_nlmsg_payload,
290 .nlgroup = RTNLGRP_IPV6_RULE, 250 .nlgroup = RTNLGRP_IPV6_RULE,
291 .policy = fib6_rule_policy, 251 .policy = fib6_rule_policy,
292 .rules_list = &fib6_rules, 252 .rules_list = &fib6_rules,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4ec876066b3f..3dcc4b7f41b4 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -177,7 +177,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
177 */ 177 */
178 dst = ip6_route_output(sk, fl); 178 dst = ip6_route_output(sk, fl);
179 if (dst->error) { 179 if (dst->error) {
180 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 180 IP6_INC_STATS(ip6_dst_idev(dst),
181 IPSTATS_MIB_OUTNOROUTES);
181 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { 182 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
182 res = 1; 183 res = 1;
183 } else { 184 } else {
@@ -233,7 +234,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
233 len, fl->proto, 234 len, fl->proto,
234 skb->csum); 235 skb->csum);
235 } else { 236 } else {
236 u32 tmp_csum = 0; 237 __wsum tmp_csum = 0;
237 238
238 skb_queue_walk(&sk->sk_write_queue, skb) { 239 skb_queue_walk(&sk->sk_write_queue, skb) {
239 tmp_csum = csum_add(tmp_csum, skb->csum); 240 tmp_csum = csum_add(tmp_csum, skb->csum);
@@ -241,13 +242,11 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
241 242
242 tmp_csum = csum_partial((char *)icmp6h, 243 tmp_csum = csum_partial((char *)icmp6h,
243 sizeof(struct icmp6hdr), tmp_csum); 244 sizeof(struct icmp6hdr), tmp_csum);
244 tmp_csum = csum_ipv6_magic(&fl->fl6_src, 245 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
245 &fl->fl6_dst, 246 &fl->fl6_dst,
246 len, fl->proto, tmp_csum); 247 len, fl->proto,
247 icmp6h->icmp6_cksum = tmp_csum; 248 tmp_csum);
248 } 249 }
249 if (icmp6h->icmp6_cksum == 0)
250 icmp6h->icmp6_cksum = -1;
251 ip6_push_pending_frames(sk); 250 ip6_push_pending_frames(sk);
252out: 251out:
253 return err; 252 return err;
@@ -263,7 +262,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
263{ 262{
264 struct icmpv6_msg *msg = (struct icmpv6_msg *) from; 263 struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
265 struct sk_buff *org_skb = msg->skb; 264 struct sk_buff *org_skb = msg->skb;
266 __u32 csum = 0; 265 __wsum csum = 0;
267 266
268 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, 267 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
269 to, len, csum); 268 to, len, csum);
@@ -555,7 +554,7 @@ out:
555 icmpv6_xmit_unlock(); 554 icmpv6_xmit_unlock();
556} 555}
557 556
558static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info) 557static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
559{ 558{
560 struct in6_addr *saddr, *daddr; 559 struct in6_addr *saddr, *daddr;
561 struct inet6_protocol *ipprot; 560 struct inet6_protocol *ipprot;
@@ -637,8 +636,8 @@ static int icmpv6_rcv(struct sk_buff **pskb)
637 break; 636 break;
638 /* fall through */ 637 /* fall through */
639 case CHECKSUM_NONE: 638 case CHECKSUM_NONE:
640 skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len, 639 skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
641 IPPROTO_ICMPV6, 0); 640 IPPROTO_ICMPV6, 0));
642 if (__skb_checksum_complete(skb)) { 641 if (__skb_checksum_complete(skb)) {
643 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n", 642 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n",
644 NIP6(*saddr), NIP6(*daddr)); 643 NIP6(*saddr), NIP6(*daddr));
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 827f41d1478b..c700302ad51a 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -52,20 +52,20 @@ EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
52/* 52/*
53 * request_sock (formerly open request) hash tables. 53 * request_sock (formerly open request) hash tables.
54 */ 54 */
55static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport, 55static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
56 const u32 rnd, const u16 synq_hsize) 56 const u32 rnd, const u16 synq_hsize)
57{ 57{
58 u32 a = raddr->s6_addr32[0]; 58 u32 a = (__force u32)raddr->s6_addr32[0];
59 u32 b = raddr->s6_addr32[1]; 59 u32 b = (__force u32)raddr->s6_addr32[1];
60 u32 c = raddr->s6_addr32[2]; 60 u32 c = (__force u32)raddr->s6_addr32[2];
61 61
62 a += JHASH_GOLDEN_RATIO; 62 a += JHASH_GOLDEN_RATIO;
63 b += JHASH_GOLDEN_RATIO; 63 b += JHASH_GOLDEN_RATIO;
64 c += rnd; 64 c += rnd;
65 __jhash_mix(a, b, c); 65 __jhash_mix(a, b, c);
66 66
67 a += raddr->s6_addr32[3]; 67 a += (__force u32)raddr->s6_addr32[3];
68 b += (u32)rport; 68 b += (__force u32)rport;
69 __jhash_mix(a, b, c); 69 __jhash_mix(a, b, c);
70 70
71 return c & (synq_hsize - 1); 71 return c & (synq_hsize - 1);
@@ -73,7 +73,7 @@ static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport,
73 73
74struct request_sock *inet6_csk_search_req(const struct sock *sk, 74struct request_sock *inet6_csk_search_req(const struct sock *sk,
75 struct request_sock ***prevp, 75 struct request_sock ***prevp,
76 const __u16 rport, 76 const __be16 rport,
77 const struct in6_addr *raddr, 77 const struct in6_addr *raddr,
78 const struct in6_addr *laddr, 78 const struct in6_addr *laddr,
79 const int iif) 79 const int iif)
@@ -139,9 +139,8 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
139 139
140EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); 140EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
141 141
142int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) 142int inet6_csk_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok)
143{ 143{
144 struct sock *sk = skb->sk;
145 struct inet_sock *inet = inet_sk(sk); 144 struct inet_sock *inet = inet_sk(sk);
146 struct ipv6_pinfo *np = inet6_sk(sk); 145 struct ipv6_pinfo *np = inet6_sk(sk);
147 struct flowi fl; 146 struct flowi fl;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 8accd1fbeeda..b7e5bae0e347 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -57,7 +57,7 @@ EXPORT_SYMBOL(__inet6_hash);
57 */ 57 */
58struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo, 58struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
59 const struct in6_addr *saddr, 59 const struct in6_addr *saddr,
60 const u16 sport, 60 const __be16 sport,
61 const struct in6_addr *daddr, 61 const struct in6_addr *daddr,
62 const u16 hnum, 62 const u16 hnum,
63 const int dif) 63 const int dif)
@@ -146,8 +146,8 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
146EXPORT_SYMBOL_GPL(inet6_lookup_listener); 146EXPORT_SYMBOL_GPL(inet6_lookup_listener);
147 147
148struct sock *inet6_lookup(struct inet_hashinfo *hashinfo, 148struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
149 const struct in6_addr *saddr, const u16 sport, 149 const struct in6_addr *saddr, const __be16 sport,
150 const struct in6_addr *daddr, const u16 dport, 150 const struct in6_addr *daddr, const __be16 dport,
151 const int dif) 151 const int dif)
152{ 152{
153 struct sock *sk; 153 struct sock *sk;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index f98ca30d7c1f..bf526115e518 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -139,9 +139,9 @@ static __inline__ u32 fib6_new_sernum(void)
139 * test bit 139 * test bit
140 */ 140 */
141 141
142static __inline__ int addr_bit_set(void *token, int fn_bit) 142static __inline__ __be32 addr_bit_set(void *token, int fn_bit)
143{ 143{
144 __u32 *addr = token; 144 __be32 *addr = token;
145 145
146 return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5]; 146 return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5];
147} 147}
@@ -434,7 +434,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
434 struct fib6_node *pn = NULL; 434 struct fib6_node *pn = NULL;
435 struct rt6key *key; 435 struct rt6key *key;
436 int bit; 436 int bit;
437 int dir = 0; 437 __be32 dir = 0;
438 __u32 sernum = fib6_new_sernum(); 438 __u32 sernum = fib6_new_sernum();
439 439
440 RT6_TRACE("fib6_add_1\n"); 440 RT6_TRACE("fib6_add_1\n");
@@ -829,7 +829,7 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
829 struct lookup_args *args) 829 struct lookup_args *args)
830{ 830{
831 struct fib6_node *fn; 831 struct fib6_node *fn;
832 int dir; 832 __be32 dir;
833 833
834 if (unlikely(args->offset == 0)) 834 if (unlikely(args->offset == 0))
835 return NULL; 835 return NULL;
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 6d4533b58dca..624fae251f4e 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -61,7 +61,7 @@ static DEFINE_RWLOCK(ip6_fl_lock);
61static DEFINE_RWLOCK(ip6_sk_fl_lock); 61static DEFINE_RWLOCK(ip6_sk_fl_lock);
62 62
63 63
64static __inline__ struct ip6_flowlabel * __fl_lookup(u32 label) 64static __inline__ struct ip6_flowlabel * __fl_lookup(__be32 label)
65{ 65{
66 struct ip6_flowlabel *fl; 66 struct ip6_flowlabel *fl;
67 67
@@ -72,7 +72,7 @@ static __inline__ struct ip6_flowlabel * __fl_lookup(u32 label)
72 return NULL; 72 return NULL;
73} 73}
74 74
75static struct ip6_flowlabel * fl_lookup(u32 label) 75static struct ip6_flowlabel * fl_lookup(__be32 label)
76{ 76{
77 struct ip6_flowlabel *fl; 77 struct ip6_flowlabel *fl;
78 78
@@ -153,7 +153,7 @@ static void ip6_fl_gc(unsigned long dummy)
153 write_unlock(&ip6_fl_lock); 153 write_unlock(&ip6_fl_lock);
154} 154}
155 155
156static int fl_intern(struct ip6_flowlabel *fl, __u32 label) 156static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
157{ 157{
158 fl->label = label & IPV6_FLOWLABEL_MASK; 158 fl->label = label & IPV6_FLOWLABEL_MASK;
159 159
@@ -182,7 +182,7 @@ static int fl_intern(struct ip6_flowlabel *fl, __u32 label)
182 182
183/* Socket flowlabel lists */ 183/* Socket flowlabel lists */
184 184
185struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, u32 label) 185struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label)
186{ 186{
187 struct ipv6_fl_socklist *sfl; 187 struct ipv6_fl_socklist *sfl;
188 struct ipv6_pinfo *np = inet6_sk(sk); 188 struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6b8e6d76a58b..ad0b8abcdf4b 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -60,14 +60,22 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
60{ 60{
61 struct ipv6hdr *hdr; 61 struct ipv6hdr *hdr;
62 u32 pkt_len; 62 u32 pkt_len;
63 struct inet6_dev *idev;
63 64
64 if (skb->pkt_type == PACKET_OTHERHOST) 65 if (skb->pkt_type == PACKET_OTHERHOST) {
65 goto drop; 66 kfree_skb(skb);
67 return 0;
68 }
69
70 rcu_read_lock();
66 71
67 IP6_INC_STATS_BH(IPSTATS_MIB_INRECEIVES); 72 idev = __in6_dev_get(skb->dev);
73
74 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES);
68 75
69 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 76 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
70 IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); 77 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS);
78 rcu_read_unlock();
71 goto out; 79 goto out;
72 } 80 }
73 81
@@ -84,7 +92,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
84 * arrived via the sending interface (ethX), because of the 92 * arrived via the sending interface (ethX), because of the
85 * nature of scoping architecture. --yoshfuji 93 * nature of scoping architecture. --yoshfuji
86 */ 94 */
87 IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex; 95 IP6CB(skb)->iif = skb->dst ? ip6_dst_idev(skb->dst)->dev->ifindex : dev->ifindex;
88 96
89 if (unlikely(!pskb_may_pull(skb, sizeof(*hdr)))) 97 if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
90 goto err; 98 goto err;
@@ -104,7 +112,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
104 if (pkt_len + sizeof(struct ipv6hdr) > skb->len) 112 if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
105 goto truncated; 113 goto truncated;
106 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { 114 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
107 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 115 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
108 goto drop; 116 goto drop;
109 } 117 }
110 hdr = skb->nh.ipv6h; 118 hdr = skb->nh.ipv6h;
@@ -112,17 +120,21 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
112 120
113 if (hdr->nexthdr == NEXTHDR_HOP) { 121 if (hdr->nexthdr == NEXTHDR_HOP) {
114 if (ipv6_parse_hopopts(&skb) < 0) { 122 if (ipv6_parse_hopopts(&skb) < 0) {
115 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 123 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
124 rcu_read_unlock();
116 return 0; 125 return 0;
117 } 126 }
118 } 127 }
119 128
129 rcu_read_unlock();
130
120 return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); 131 return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
121truncated: 132truncated:
122 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); 133 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS);
123err: 134err:
124 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 135 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
125drop: 136drop:
137 rcu_read_unlock();
126 kfree_skb(skb); 138 kfree_skb(skb);
127out: 139out:
128 return 0; 140 return 0;
@@ -140,6 +152,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
140 unsigned int nhoff; 152 unsigned int nhoff;
141 int nexthdr; 153 int nexthdr;
142 u8 hash; 154 u8 hash;
155 struct inet6_dev *idev;
143 156
144 /* 157 /*
145 * Parse extension headers 158 * Parse extension headers
@@ -147,6 +160,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
147 160
148 rcu_read_lock(); 161 rcu_read_lock();
149resubmit: 162resubmit:
163 idev = ip6_dst_idev(skb->dst);
150 if (!pskb_pull(skb, skb->h.raw - skb->data)) 164 if (!pskb_pull(skb, skb->h.raw - skb->data))
151 goto discard; 165 goto discard;
152 nhoff = IP6CB(skb)->nhoff; 166 nhoff = IP6CB(skb)->nhoff;
@@ -185,24 +199,24 @@ resubmit:
185 if (ret > 0) 199 if (ret > 0)
186 goto resubmit; 200 goto resubmit;
187 else if (ret == 0) 201 else if (ret == 0)
188 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); 202 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS);
189 } else { 203 } else {
190 if (!raw_sk) { 204 if (!raw_sk) {
191 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 205 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
192 IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); 206 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS);
193 icmpv6_send(skb, ICMPV6_PARAMPROB, 207 icmpv6_send(skb, ICMPV6_PARAMPROB,
194 ICMPV6_UNK_NEXTHDR, nhoff, 208 ICMPV6_UNK_NEXTHDR, nhoff,
195 skb->dev); 209 skb->dev);
196 } 210 }
197 } else 211 } else
198 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); 212 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS);
199 kfree_skb(skb); 213 kfree_skb(skb);
200 } 214 }
201 rcu_read_unlock(); 215 rcu_read_unlock();
202 return 0; 216 return 0;
203 217
204discard: 218discard:
205 IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); 219 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS);
206 rcu_read_unlock(); 220 rcu_read_unlock();
207 kfree_skb(skb); 221 kfree_skb(skb);
208 return 0; 222 return 0;
@@ -219,7 +233,7 @@ int ip6_mc_input(struct sk_buff *skb)
219 struct ipv6hdr *hdr; 233 struct ipv6hdr *hdr;
220 int deliver; 234 int deliver;
221 235
222 IP6_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); 236 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
223 237
224 hdr = skb->nh.ipv6h; 238 hdr = skb->nh.ipv6h;
225 deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || 239 deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 66716911962e..e05ecbb1412d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -88,7 +88,7 @@ static inline int ip6_output_finish(struct sk_buff *skb)
88 } else if (dst->neighbour) 88 } else if (dst->neighbour)
89 return dst->neighbour->output(skb); 89 return dst->neighbour->output(skb);
90 90
91 IP6_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); 91 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
92 kfree_skb(skb); 92 kfree_skb(skb);
93 return -EINVAL; 93 return -EINVAL;
94 94
@@ -118,6 +118,7 @@ static int ip6_output2(struct sk_buff *skb)
118 118
119 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) { 119 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
120 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; 120 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
121 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
121 122
122 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && 123 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
123 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr, 124 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
@@ -133,13 +134,13 @@ static int ip6_output2(struct sk_buff *skb)
133 ip6_dev_loopback_xmit); 134 ip6_dev_loopback_xmit);
134 135
135 if (skb->nh.ipv6h->hop_limit == 0) { 136 if (skb->nh.ipv6h->hop_limit == 0) {
136 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 137 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
137 kfree_skb(skb); 138 kfree_skb(skb);
138 return 0; 139 return 0;
139 } 140 }
140 } 141 }
141 142
142 IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); 143 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
143 } 144 }
144 145
145 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); 146 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
@@ -182,12 +183,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
182 183
183 if (skb_headroom(skb) < head_room) { 184 if (skb_headroom(skb) < head_room) {
184 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); 185 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
185 kfree_skb(skb); 186 if (skb2 == NULL) {
186 skb = skb2; 187 IP6_INC_STATS(ip6_dst_idev(skb->dst),
187 if (skb == NULL) { 188 IPSTATS_MIB_OUTDISCARDS);
188 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 189 kfree_skb(skb);
189 return -ENOBUFS; 190 return -ENOBUFS;
190 } 191 }
192 kfree_skb(skb);
193 skb = skb2;
191 if (sk) 194 if (sk)
192 skb_set_owner_w(skb, sk); 195 skb_set_owner_w(skb, sk);
193 } 196 }
@@ -217,7 +220,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
217 if (tclass < 0) 220 if (tclass < 0)
218 tclass = 0; 221 tclass = 0;
219 222
220 *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; 223 *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
221 224
222 hdr->payload_len = htons(seg_len); 225 hdr->payload_len = htons(seg_len);
223 hdr->nexthdr = proto; 226 hdr->nexthdr = proto;
@@ -230,7 +233,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
230 233
231 mtu = dst_mtu(dst); 234 mtu = dst_mtu(dst);
232 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { 235 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
233 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 236 IP6_INC_STATS(ip6_dst_idev(skb->dst),
237 IPSTATS_MIB_OUTREQUESTS);
234 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, 238 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
235 dst_output); 239 dst_output);
236 } 240 }
@@ -239,7 +243,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
239 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 243 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
240 skb->dev = dst->dev; 244 skb->dev = dst->dev;
241 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 245 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
242 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 246 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
243 kfree_skb(skb); 247 kfree_skb(skb);
244 return -EMSGSIZE; 248 return -EMSGSIZE;
245} 249}
@@ -267,7 +271,7 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
267 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr)); 271 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
268 skb->nh.ipv6h = hdr; 272 skb->nh.ipv6h = hdr;
269 273
270 *(u32*)hdr = htonl(0x60000000); 274 *(__be32*)hdr = htonl(0x60000000);
271 275
272 hdr->payload_len = htons(len); 276 hdr->payload_len = htons(len);
273 hdr->nexthdr = proto; 277 hdr->nexthdr = proto;
@@ -373,7 +377,7 @@ int ip6_forward(struct sk_buff *skb)
373 goto error; 377 goto error;
374 378
375 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 379 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
376 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 380 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
377 goto drop; 381 goto drop;
378 } 382 }
379 383
@@ -406,7 +410,7 @@ int ip6_forward(struct sk_buff *skb)
406 skb->dev = dst->dev; 410 skb->dev = dst->dev;
407 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 411 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
408 0, skb->dev); 412 0, skb->dev);
409 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 413 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
410 414
411 kfree_skb(skb); 415 kfree_skb(skb);
412 return -ETIMEDOUT; 416 return -ETIMEDOUT;
@@ -419,13 +423,13 @@ int ip6_forward(struct sk_buff *skb)
419 if (proxied > 0) 423 if (proxied > 0)
420 return ip6_input(skb); 424 return ip6_input(skb);
421 else if (proxied < 0) { 425 else if (proxied < 0) {
422 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 426 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
423 goto drop; 427 goto drop;
424 } 428 }
425 } 429 }
426 430
427 if (!xfrm6_route_forward(skb)) { 431 if (!xfrm6_route_forward(skb)) {
428 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 432 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
429 goto drop; 433 goto drop;
430 } 434 }
431 dst = skb->dst; 435 dst = skb->dst;
@@ -464,14 +468,14 @@ int ip6_forward(struct sk_buff *skb)
464 /* Again, force OUTPUT device used as source address */ 468 /* Again, force OUTPUT device used as source address */
465 skb->dev = dst->dev; 469 skb->dev = dst->dev;
466 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); 470 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev);
467 IP6_INC_STATS_BH(IPSTATS_MIB_INTOOBIGERRORS); 471 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
468 IP6_INC_STATS_BH(IPSTATS_MIB_FRAGFAILS); 472 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS);
469 kfree_skb(skb); 473 kfree_skb(skb);
470 return -EMSGSIZE; 474 return -EMSGSIZE;
471 } 475 }
472 476
473 if (skb_cow(skb, dst->dev->hard_header_len)) { 477 if (skb_cow(skb, dst->dev->hard_header_len)) {
474 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 478 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
475 goto drop; 479 goto drop;
476 } 480 }
477 481
@@ -481,11 +485,11 @@ int ip6_forward(struct sk_buff *skb)
481 485
482 hdr->hop_limit--; 486 hdr->hop_limit--;
483 487
484 IP6_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); 488 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
485 return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish); 489 return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
486 490
487error: 491error:
488 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 492 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
489drop: 493drop:
490 kfree_skb(skb); 494 kfree_skb(skb);
491 return -EINVAL; 495 return -EINVAL;
@@ -499,12 +503,12 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
499 dst_release(to->dst); 503 dst_release(to->dst);
500 to->dst = dst_clone(from->dst); 504 to->dst = dst_clone(from->dst);
501 to->dev = from->dev; 505 to->dev = from->dev;
506 to->mark = from->mark;
502 507
503#ifdef CONFIG_NET_SCHED 508#ifdef CONFIG_NET_SCHED
504 to->tc_index = from->tc_index; 509 to->tc_index = from->tc_index;
505#endif 510#endif
506#ifdef CONFIG_NETFILTER 511#ifdef CONFIG_NETFILTER
507 to->nfmark = from->nfmark;
508 /* Connection association is same as pre-frag packet */ 512 /* Connection association is same as pre-frag packet */
509 nf_conntrack_put(to->nfct); 513 nf_conntrack_put(to->nfct);
510 to->nfct = from->nfct; 514 to->nfct = from->nfct;
@@ -571,7 +575,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
571 struct ipv6hdr *tmp_hdr; 575 struct ipv6hdr *tmp_hdr;
572 struct frag_hdr *fh; 576 struct frag_hdr *fh;
573 unsigned int mtu, hlen, left, len; 577 unsigned int mtu, hlen, left, len;
574 u32 frag_id = 0; 578 __be32 frag_id = 0;
575 int ptr, offset = 0, err=0; 579 int ptr, offset = 0, err=0;
576 u8 *prevhdr, nexthdr = 0; 580 u8 *prevhdr, nexthdr = 0;
577 581
@@ -620,14 +624,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
620 skb_shinfo(skb)->frag_list = NULL; 624 skb_shinfo(skb)->frag_list = NULL;
621 /* BUILD HEADER */ 625 /* BUILD HEADER */
622 626
623 tmp_hdr = kmalloc(hlen, GFP_ATOMIC); 627 tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC);
624 if (!tmp_hdr) { 628 if (!tmp_hdr) {
625 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 629 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
626 return -ENOMEM; 630 return -ENOMEM;
627 } 631 }
628 632
629 *prevhdr = NEXTHDR_FRAGMENT; 633 *prevhdr = NEXTHDR_FRAGMENT;
630 memcpy(tmp_hdr, skb->nh.raw, hlen);
631 __skb_pull(skb, hlen); 634 __skb_pull(skb, hlen);
632 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); 635 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
633 skb->nh.raw = __skb_push(skb, hlen); 636 skb->nh.raw = __skb_push(skb, hlen);
@@ -643,7 +646,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
643 skb->data_len = first_len - skb_headlen(skb); 646 skb->data_len = first_len - skb_headlen(skb);
644 skb->len = first_len; 647 skb->len = first_len;
645 skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr)); 648 skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr));
646 649
650 dst_hold(&rt->u.dst);
647 651
648 for (;;) { 652 for (;;) {
649 /* Prepare header of the next frame, 653 /* Prepare header of the next frame,
@@ -667,7 +671,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
667 671
668 err = output(skb); 672 err = output(skb);
669 if(!err) 673 if(!err)
670 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); 674 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES);
671 675
672 if (err || !frag) 676 if (err || !frag)
673 break; 677 break;
@@ -680,7 +684,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
680 kfree(tmp_hdr); 684 kfree(tmp_hdr);
681 685
682 if (err == 0) { 686 if (err == 0) {
683 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); 687 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS);
688 dst_release(&rt->u.dst);
684 return 0; 689 return 0;
685 } 690 }
686 691
@@ -690,7 +695,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
690 frag = skb; 695 frag = skb;
691 } 696 }
692 697
693 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 698 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS);
699 dst_release(&rt->u.dst);
694 return err; 700 return err;
695 } 701 }
696 702
@@ -723,7 +729,8 @@ slow_path:
723 729
724 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { 730 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
725 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 731 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
726 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 732 IP6_INC_STATS(ip6_dst_idev(skb->dst),
733 IPSTATS_MIB_FRAGFAILS);
727 err = -ENOMEM; 734 err = -ENOMEM;
728 goto fail; 735 goto fail;
729 } 736 }
@@ -784,15 +791,17 @@ slow_path:
784 if (err) 791 if (err)
785 goto fail; 792 goto fail;
786 793
787 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); 794 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES);
788 } 795 }
796 IP6_INC_STATS(ip6_dst_idev(skb->dst),
797 IPSTATS_MIB_FRAGOKS);
789 kfree_skb(skb); 798 kfree_skb(skb);
790 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
791 return err; 799 return err;
792 800
793fail: 801fail:
802 IP6_INC_STATS(ip6_dst_idev(skb->dst),
803 IPSTATS_MIB_FRAGFAILS);
794 kfree_skb(skb); 804 kfree_skb(skb);
795 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
796 return err; 805 return err;
797} 806}
798 807
@@ -1265,7 +1274,7 @@ alloc_new_skb:
1265 return 0; 1274 return 0;
1266error: 1275error:
1267 inet->cork.length -= length; 1276 inet->cork.length -= length;
1268 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1277 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1269 return err; 1278 return err;
1270} 1279}
1271 1280
@@ -1311,7 +1320,7 @@ int ip6_push_pending_frames(struct sock *sk)
1311 1320
1312 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); 1321 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr));
1313 1322
1314 *(u32*)hdr = fl->fl6_flowlabel | 1323 *(__be32*)hdr = fl->fl6_flowlabel |
1315 htonl(0x60000000 | ((int)np->cork.tclass << 20)); 1324 htonl(0x60000000 | ((int)np->cork.tclass << 20));
1316 1325
1317 if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) 1326 if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
@@ -1326,7 +1335,7 @@ int ip6_push_pending_frames(struct sock *sk)
1326 skb->priority = sk->sk_priority; 1335 skb->priority = sk->sk_priority;
1327 1336
1328 skb->dst = dst_clone(&rt->u.dst); 1337 skb->dst = dst_clone(&rt->u.dst);
1329 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1338 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
1330 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); 1339 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
1331 if (err) { 1340 if (err) {
1332 if (err > 0) 1341 if (err > 0)
@@ -1357,7 +1366,8 @@ void ip6_flush_pending_frames(struct sock *sk)
1357 struct sk_buff *skb; 1366 struct sk_buff *skb;
1358 1367
1359 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { 1368 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1360 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1369 IP6_INC_STATS(ip6_dst_idev(skb->dst),
1370 IPSTATS_MIB_OUTDISCARDS);
1361 kfree_skb(skb); 1371 kfree_skb(skb);
1362 } 1372 }
1363 1373
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index b9f40290d12a..8d918348f5bb 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL");
66 66
67#define HASH_SIZE 32 67#define HASH_SIZE 32
68 68
69#define HASH(addr) (((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \ 69#define HASH(addr) ((__force u32)((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \
70 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ 70 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
71 (HASH_SIZE - 1)) 71 (HASH_SIZE - 1))
72 72
@@ -215,11 +215,10 @@ ip6ip6_tnl_unlink(struct ip6_tnl *t)
215 * Create tunnel matching given parameters. 215 * Create tunnel matching given parameters.
216 * 216 *
217 * Return: 217 * Return:
218 * 0 on success 218 * created tunnel or NULL
219 **/ 219 **/
220 220
221static int 221static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p)
222ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
223{ 222{
224 struct net_device *dev; 223 struct net_device *dev;
225 struct ip6_tnl *t; 224 struct ip6_tnl *t;
@@ -236,11 +235,11 @@ ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
236 break; 235 break;
237 } 236 }
238 if (i == IP6_TNL_MAX) 237 if (i == IP6_TNL_MAX)
239 return -ENOBUFS; 238 goto failed;
240 } 239 }
241 dev = alloc_netdev(sizeof (*t), name, ip6ip6_tnl_dev_setup); 240 dev = alloc_netdev(sizeof (*t), name, ip6ip6_tnl_dev_setup);
242 if (dev == NULL) 241 if (dev == NULL)
243 return -ENOMEM; 242 goto failed;
244 243
245 t = netdev_priv(dev); 244 t = netdev_priv(dev);
246 dev->init = ip6ip6_tnl_dev_init; 245 dev->init = ip6ip6_tnl_dev_init;
@@ -248,13 +247,13 @@ ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
248 247
249 if ((err = register_netdevice(dev)) < 0) { 248 if ((err = register_netdevice(dev)) < 0) {
250 free_netdev(dev); 249 free_netdev(dev);
251 return err; 250 goto failed;
252 } 251 }
253 dev_hold(dev); 252 dev_hold(dev);
254
255 ip6ip6_tnl_link(t); 253 ip6ip6_tnl_link(t);
256 *pt = t; 254 return t;
257 return 0; 255failed:
256 return NULL;
258} 257}
259 258
260/** 259/**
@@ -268,32 +267,23 @@ ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
268 * tunnel device is created and registered for use. 267 * tunnel device is created and registered for use.
269 * 268 *
270 * Return: 269 * Return:
271 * 0 if tunnel located or created, 270 * matching tunnel or NULL
272 * -EINVAL if parameters incorrect,
273 * -ENODEV if no matching tunnel available
274 **/ 271 **/
275 272
276static int 273static struct ip6_tnl *ip6ip6_tnl_locate(struct ip6_tnl_parm *p, int create)
277ip6ip6_tnl_locate(struct ip6_tnl_parm *p, struct ip6_tnl **pt, int create)
278{ 274{
279 struct in6_addr *remote = &p->raddr; 275 struct in6_addr *remote = &p->raddr;
280 struct in6_addr *local = &p->laddr; 276 struct in6_addr *local = &p->laddr;
281 struct ip6_tnl *t; 277 struct ip6_tnl *t;
282 278
283 if (p->proto != IPPROTO_IPV6)
284 return -EINVAL;
285
286 for (t = *ip6ip6_bucket(p); t; t = t->next) { 279 for (t = *ip6ip6_bucket(p); t; t = t->next) {
287 if (ipv6_addr_equal(local, &t->parms.laddr) && 280 if (ipv6_addr_equal(local, &t->parms.laddr) &&
288 ipv6_addr_equal(remote, &t->parms.raddr)) { 281 ipv6_addr_equal(remote, &t->parms.raddr))
289 *pt = t; 282 return t;
290 return (create ? -EEXIST : 0);
291 }
292 } 283 }
293 if (!create) 284 if (!create)
294 return -ENODEV; 285 return NULL;
295 286 return ip6_tnl_create(p);
296 return ip6_tnl_create(p, pt);
297} 287}
298 288
299/** 289/**
@@ -391,7 +381,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
391 381
392static int 382static int
393ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 383ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
394 int type, int code, int offset, __u32 info) 384 int type, int code, int offset, __be32 info)
395{ 385{
396 struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data; 386 struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data;
397 struct ip6_tnl *t; 387 struct ip6_tnl *t;
@@ -434,12 +424,9 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
434 } 424 }
435 break; 425 break;
436 case ICMPV6_PARAMPROB: 426 case ICMPV6_PARAMPROB:
437 /* ignore if parameter problem not caused by a tunnel 427 teli = 0;
438 encapsulation limit sub-option */ 428 if (code == ICMPV6_HDR_FIELD)
439 if (code != ICMPV6_HDR_FIELD) { 429 teli = parse_tlv_tnl_enc_lim(skb, skb->data);
440 break;
441 }
442 teli = parse_tlv_tnl_enc_lim(skb, skb->data);
443 430
444 if (teli && teli == ntohl(info) - 2) { 431 if (teli && teli == ntohl(info) - 2) {
445 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; 432 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
@@ -451,6 +438,10 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
451 "tunnel!\n", t->parms.name); 438 "tunnel!\n", t->parms.name);
452 rel_msg = 1; 439 rel_msg = 1;
453 } 440 }
441 } else if (net_ratelimit()) {
442 printk(KERN_WARNING
443 "%s: Recipient unable to parse tunneled "
444 "packet!\n ", t->parms.name);
454 } 445 }
455 break; 446 break;
456 case ICMPV6_PKT_TOOBIG: 447 case ICMPV6_PKT_TOOBIG:
@@ -470,6 +461,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
470 if (rel_msg && pskb_may_pull(skb, offset + sizeof (*ipv6h))) { 461 if (rel_msg && pskb_may_pull(skb, offset + sizeof (*ipv6h))) {
471 struct rt6_info *rt; 462 struct rt6_info *rt;
472 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 463 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
464
473 if (!skb2) 465 if (!skb2)
474 goto out; 466 goto out;
475 467
@@ -504,6 +496,27 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
504 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) 496 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
505 IP6_ECN_set_ce(inner_iph); 497 IP6_ECN_set_ce(inner_iph);
506} 498}
499static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
500{
501 struct ip6_tnl_parm *p = &t->parms;
502 int ret = 0;
503
504 if (p->flags & IP6_TNL_F_CAP_RCV) {
505 struct net_device *ldev = NULL;
506
507 if (p->link)
508 ldev = dev_get_by_index(p->link);
509
510 if ((ipv6_addr_is_multicast(&p->laddr) ||
511 likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
512 likely(!ipv6_chk_addr(&p->raddr, NULL, 0)))
513 ret = 1;
514
515 if (ldev)
516 dev_put(ldev);
517 }
518 return ret;
519}
507 520
508/** 521/**
509 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally 522 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally
@@ -528,7 +541,7 @@ ip6ip6_rcv(struct sk_buff *skb)
528 goto discard; 541 goto discard;
529 } 542 }
530 543
531 if (!(t->parms.flags & IP6_TNL_F_CAP_RCV)) { 544 if (!ip6_tnl_rcv_ctl(t)) {
532 t->stat.rx_dropped++; 545 t->stat.rx_dropped++;
533 read_unlock(&ip6ip6_lock); 546 read_unlock(&ip6ip6_lock);
534 goto discard; 547 goto discard;
@@ -560,31 +573,23 @@ discard:
560 return 0; 573 return 0;
561} 574}
562 575
563static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) 576struct ipv6_tel_txoption {
564{ 577 struct ipv6_txoptions ops;
565 struct ipv6_tlv_tnl_enc_lim *tel; 578 __u8 dst_opt[8];
566 struct ipv6_txoptions *opt; 579};
567 __u8 *raw;
568
569 int opt_len = sizeof(*opt) + 8;
570
571 if (!(opt = kzalloc(opt_len, GFP_ATOMIC))) {
572 return NULL;
573 }
574 opt->tot_len = opt_len;
575 opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1);
576 opt->opt_nflen = 8;
577 580
578 tel = (struct ipv6_tlv_tnl_enc_lim *) (opt->dst0opt + 1); 581static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
579 tel->type = IPV6_TLV_TNL_ENCAP_LIMIT; 582{
580 tel->length = 1; 583 memset(opt, 0, sizeof(struct ipv6_tel_txoption));
581 tel->encap_limit = encap_limit;
582 584
583 raw = (__u8 *) opt->dst0opt; 585 opt->dst_opt[2] = IPV6_TLV_TNL_ENCAP_LIMIT;
584 raw[5] = IPV6_TLV_PADN; 586 opt->dst_opt[3] = 1;
585 raw[6] = 1; 587 opt->dst_opt[4] = encap_limit;
588 opt->dst_opt[5] = IPV6_TLV_PADN;
589 opt->dst_opt[6] = 1;
586 590
587 return opt; 591 opt->ops.dst0opt = (struct ipv6_opt_hdr *) opt->dst_opt;
592 opt->ops.opt_nflen = 8;
588} 593}
589 594
590/** 595/**
@@ -607,6 +612,34 @@ ip6ip6_tnl_addr_conflict(struct ip6_tnl *t, struct ipv6hdr *hdr)
607 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); 612 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
608} 613}
609 614
615static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
616{
617 struct ip6_tnl_parm *p = &t->parms;
618 int ret = 0;
619
620 if (p->flags & IP6_TNL_F_CAP_XMIT) {
621 struct net_device *ldev = NULL;
622
623 if (p->link)
624 ldev = dev_get_by_index(p->link);
625
626 if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
627 printk(KERN_WARNING
628 "%s xmit: Local address not yet configured!\n",
629 p->name);
630 else if (!ipv6_addr_is_multicast(&p->raddr) &&
631 unlikely(ipv6_chk_addr(&p->raddr, NULL, 0)))
632 printk(KERN_WARNING
633 "%s xmit: Routing loop! "
634 "Remote address found on this node!\n",
635 p->name);
636 else
637 ret = 1;
638 if (ldev)
639 dev_put(ldev);
640 }
641 return ret;
642}
610/** 643/**
611 * ip6ip6_tnl_xmit - encapsulate packet and send 644 * ip6ip6_tnl_xmit - encapsulate packet and send
612 * @skb: the outgoing socket buffer 645 * @skb: the outgoing socket buffer
@@ -626,8 +659,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
626 struct ip6_tnl *t = netdev_priv(dev); 659 struct ip6_tnl *t = netdev_priv(dev);
627 struct net_device_stats *stats = &t->stat; 660 struct net_device_stats *stats = &t->stat;
628 struct ipv6hdr *ipv6h = skb->nh.ipv6h; 661 struct ipv6hdr *ipv6h = skb->nh.ipv6h;
629 struct ipv6_txoptions *opt = NULL;
630 int encap_limit = -1; 662 int encap_limit = -1;
663 struct ipv6_tel_txoption opt;
631 __u16 offset; 664 __u16 offset;
632 struct flowi fl; 665 struct flowi fl;
633 struct dst_entry *dst; 666 struct dst_entry *dst;
@@ -644,10 +677,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
644 goto tx_err; 677 goto tx_err;
645 } 678 }
646 if (skb->protocol != htons(ETH_P_IPV6) || 679 if (skb->protocol != htons(ETH_P_IPV6) ||
647 !(t->parms.flags & IP6_TNL_F_CAP_XMIT) || 680 !ip6_tnl_xmit_ctl(t) || ip6ip6_tnl_addr_conflict(t, ipv6h))
648 ip6ip6_tnl_addr_conflict(t, ipv6h)) {
649 goto tx_err; 681 goto tx_err;
650 } 682
651 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) { 683 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
652 struct ipv6_tlv_tnl_enc_lim *tel; 684 struct ipv6_tlv_tnl_enc_lim *tel;
653 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset]; 685 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
@@ -657,20 +689,17 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
657 goto tx_err; 689 goto tx_err;
658 } 690 }
659 encap_limit = tel->encap_limit - 1; 691 encap_limit = tel->encap_limit - 1;
660 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) { 692 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
661 encap_limit = t->parms.encap_limit; 693 encap_limit = t->parms.encap_limit;
662 } 694
663 memcpy(&fl, &t->fl, sizeof (fl)); 695 memcpy(&fl, &t->fl, sizeof (fl));
664 proto = fl.proto; 696 proto = fl.proto;
665 697
666 dsfield = ipv6_get_dsfield(ipv6h); 698 dsfield = ipv6_get_dsfield(ipv6h);
667 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) 699 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
668 fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_TCLASS_MASK); 700 fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
669 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)) 701 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL))
670 fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_FLOWLABEL_MASK); 702 fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
671
672 if (encap_limit >= 0 && (opt = create_tel(encap_limit)) == NULL)
673 goto tx_err;
674 703
675 if ((dst = ip6_tnl_dst_check(t)) != NULL) 704 if ((dst = ip6_tnl_dst_check(t)) != NULL)
676 dst_hold(dst); 705 dst_hold(dst);
@@ -692,7 +721,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
692 goto tx_err_dst_release; 721 goto tx_err_dst_release;
693 } 722 }
694 mtu = dst_mtu(dst) - sizeof (*ipv6h); 723 mtu = dst_mtu(dst) - sizeof (*ipv6h);
695 if (opt) { 724 if (encap_limit >= 0) {
696 max_headroom += 8; 725 max_headroom += 8;
697 mtu -= 8; 726 mtu -= 8;
698 } 727 }
@@ -730,12 +759,13 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
730 759
731 skb->h.raw = skb->nh.raw; 760 skb->h.raw = skb->nh.raw;
732 761
733 if (opt) 762 if (encap_limit >= 0) {
734 ipv6_push_nfrag_opts(skb, opt, &proto, NULL); 763 init_tel_txopt(&opt, encap_limit);
735 764 ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
765 }
736 skb->nh.raw = skb_push(skb, sizeof(struct ipv6hdr)); 766 skb->nh.raw = skb_push(skb, sizeof(struct ipv6hdr));
737 ipv6h = skb->nh.ipv6h; 767 ipv6h = skb->nh.ipv6h;
738 *(u32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000); 768 *(__be32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000);
739 dsfield = INET_ECN_encapsulate(0, dsfield); 769 dsfield = INET_ECN_encapsulate(0, dsfield);
740 ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); 770 ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
741 ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 771 ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
@@ -748,7 +778,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
748 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, 778 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
749 skb->dst->dev, dst_output); 779 skb->dst->dev, dst_output);
750 780
751 if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { 781 if (net_xmit_eval(err) == 0) {
752 stats->tx_bytes += pkt_len; 782 stats->tx_bytes += pkt_len;
753 stats->tx_packets++; 783 stats->tx_packets++;
754 } else { 784 } else {
@@ -756,9 +786,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
756 stats->tx_aborted_errors++; 786 stats->tx_aborted_errors++;
757 } 787 }
758 ip6_tnl_dst_store(t, dst); 788 ip6_tnl_dst_store(t, dst);
759
760 kfree(opt);
761
762 t->recursion--; 789 t->recursion--;
763 return 0; 790 return 0;
764tx_err_link_failure: 791tx_err_link_failure:
@@ -766,7 +793,6 @@ tx_err_link_failure:
766 dst_link_failure(skb); 793 dst_link_failure(skb);
767tx_err_dst_release: 794tx_err_dst_release:
768 dst_release(dst); 795 dst_release(dst);
769 kfree(opt);
770tx_err: 796tx_err:
771 stats->tx_errors++; 797 stats->tx_errors++;
772 stats->tx_dropped++; 798 stats->tx_dropped++;
@@ -778,39 +804,19 @@ tx_err:
778static void ip6_tnl_set_cap(struct ip6_tnl *t) 804static void ip6_tnl_set_cap(struct ip6_tnl *t)
779{ 805{
780 struct ip6_tnl_parm *p = &t->parms; 806 struct ip6_tnl_parm *p = &t->parms;
781 struct in6_addr *laddr = &p->laddr; 807 int ltype = ipv6_addr_type(&p->laddr);
782 struct in6_addr *raddr = &p->raddr; 808 int rtype = ipv6_addr_type(&p->raddr);
783 int ltype = ipv6_addr_type(laddr);
784 int rtype = ipv6_addr_type(raddr);
785 809
786 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV); 810 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV);
787 811
788 if (ltype != IPV6_ADDR_ANY && rtype != IPV6_ADDR_ANY && 812 if (ltype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
789 ((ltype|rtype) & 813 rtype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
790 (IPV6_ADDR_UNICAST| 814 !((ltype|rtype) & IPV6_ADDR_LOOPBACK) &&
791 IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL| 815 (!((ltype|rtype) & IPV6_ADDR_LINKLOCAL) || p->link)) {
792 IPV6_ADDR_MAPPED|IPV6_ADDR_RESERVED)) == IPV6_ADDR_UNICAST) { 816 if (ltype&IPV6_ADDR_UNICAST)
793 struct net_device *ldev = NULL; 817 p->flags |= IP6_TNL_F_CAP_XMIT;
794 int l_ok = 1; 818 if (rtype&IPV6_ADDR_UNICAST)
795 int r_ok = 1; 819 p->flags |= IP6_TNL_F_CAP_RCV;
796
797 if (p->link)
798 ldev = dev_get_by_index(p->link);
799
800 if (ltype&IPV6_ADDR_UNICAST && !ipv6_chk_addr(laddr, ldev, 0))
801 l_ok = 0;
802
803 if (rtype&IPV6_ADDR_UNICAST && ipv6_chk_addr(raddr, NULL, 0))
804 r_ok = 0;
805
806 if (l_ok && r_ok) {
807 if (ltype&IPV6_ADDR_UNICAST)
808 p->flags |= IP6_TNL_F_CAP_XMIT;
809 if (rtype&IPV6_ADDR_UNICAST)
810 p->flags |= IP6_TNL_F_CAP_RCV;
811 }
812 if (ldev)
813 dev_put(ldev);
814 } 820 }
815} 821}
816 822
@@ -844,8 +850,11 @@ static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
844 dev->iflink = p->link; 850 dev->iflink = p->link;
845 851
846 if (p->flags & IP6_TNL_F_CAP_XMIT) { 852 if (p->flags & IP6_TNL_F_CAP_XMIT) {
853 int strict = (ipv6_addr_type(&p->raddr) &
854 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
855
847 struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr, 856 struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
848 p->link, 0); 857 p->link, strict);
849 858
850 if (rt == NULL) 859 if (rt == NULL)
851 return; 860 return;
@@ -920,26 +929,20 @@ static int
920ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 929ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
921{ 930{
922 int err = 0; 931 int err = 0;
923 int create;
924 struct ip6_tnl_parm p; 932 struct ip6_tnl_parm p;
925 struct ip6_tnl *t = NULL; 933 struct ip6_tnl *t = NULL;
926 934
927 switch (cmd) { 935 switch (cmd) {
928 case SIOCGETTUNNEL: 936 case SIOCGETTUNNEL:
929 if (dev == ip6ip6_fb_tnl_dev) { 937 if (dev == ip6ip6_fb_tnl_dev) {
930 if (copy_from_user(&p, 938 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
931 ifr->ifr_ifru.ifru_data,
932 sizeof (p))) {
933 err = -EFAULT; 939 err = -EFAULT;
934 break; 940 break;
935 } 941 }
936 if ((err = ip6ip6_tnl_locate(&p, &t, 0)) == -ENODEV) 942 t = ip6ip6_tnl_locate(&p, 0);
937 t = netdev_priv(dev); 943 }
938 else if (err) 944 if (t == NULL)
939 break;
940 } else
941 t = netdev_priv(dev); 945 t = netdev_priv(dev);
942
943 memcpy(&p, &t->parms, sizeof (p)); 946 memcpy(&p, &t->parms, sizeof (p));
944 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { 947 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
945 err = -EFAULT; 948 err = -EFAULT;
@@ -948,35 +951,36 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
948 case SIOCADDTUNNEL: 951 case SIOCADDTUNNEL:
949 case SIOCCHGTUNNEL: 952 case SIOCCHGTUNNEL:
950 err = -EPERM; 953 err = -EPERM;
951 create = (cmd == SIOCADDTUNNEL);
952 if (!capable(CAP_NET_ADMIN)) 954 if (!capable(CAP_NET_ADMIN))
953 break; 955 break;
954 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) { 956 err = -EFAULT;
955 err = -EFAULT; 957 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
956 break; 958 break;
957 } 959 err = -EINVAL;
958 if (!create && dev != ip6ip6_fb_tnl_dev) { 960 if (p.proto != IPPROTO_IPV6)
959 t = netdev_priv(dev);
960 }
961 if (!t && (err = ip6ip6_tnl_locate(&p, &t, create))) {
962 break; 961 break;
963 } 962 t = ip6ip6_tnl_locate(&p, cmd == SIOCADDTUNNEL);
964 if (cmd == SIOCCHGTUNNEL) { 963 if (dev != ip6ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
965 if (t->dev != dev) { 964 if (t != NULL) {
966 err = -EEXIST; 965 if (t->dev != dev) {
967 break; 966 err = -EEXIST;
968 } 967 break;
968 }
969 } else
970 t = netdev_priv(dev);
971
969 ip6ip6_tnl_unlink(t); 972 ip6ip6_tnl_unlink(t);
970 err = ip6ip6_tnl_change(t, &p); 973 err = ip6ip6_tnl_change(t, &p);
971 ip6ip6_tnl_link(t); 974 ip6ip6_tnl_link(t);
972 netdev_state_change(dev); 975 netdev_state_change(dev);
973 } 976 }
974 if (copy_to_user(ifr->ifr_ifru.ifru_data, 977 if (t) {
975 &t->parms, sizeof (p))) {
976 err = -EFAULT;
977 } else {
978 err = 0; 978 err = 0;
979 } 979 if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof (p)))
980 err = -EFAULT;
981
982 } else
983 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
980 break; 984 break;
981 case SIOCDELTUNNEL: 985 case SIOCDELTUNNEL:
982 err = -EPERM; 986 err = -EPERM;
@@ -984,22 +988,18 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
984 break; 988 break;
985 989
986 if (dev == ip6ip6_fb_tnl_dev) { 990 if (dev == ip6ip6_fb_tnl_dev) {
987 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, 991 err = -EFAULT;
988 sizeof (p))) { 992 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
989 err = -EFAULT;
990 break; 993 break;
991 } 994 err = -ENOENT;
992 err = ip6ip6_tnl_locate(&p, &t, 0); 995 if ((t = ip6ip6_tnl_locate(&p, 0)) == NULL)
993 if (err)
994 break; 996 break;
995 if (t == netdev_priv(ip6ip6_fb_tnl_dev)) { 997 err = -EPERM;
996 err = -EPERM; 998 if (t->dev == ip6ip6_fb_tnl_dev)
997 break; 999 break;
998 } 1000 dev = t->dev;
999 } else {
1000 t = netdev_priv(dev);
1001 } 1001 }
1002 err = unregister_netdevice(t->dev); 1002 err = unregister_netdevice(dev);
1003 break; 1003 break;
1004 default: 1004 default:
1005 err = -EINVAL; 1005 err = -EINVAL;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 71f59f18ede8..511730b67e97 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -176,7 +176,7 @@ out_ok:
176} 176}
177 177
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, __be32 info)
180{ 180{
181 __be32 spi; 181 __be32 spi;
182 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 182 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index de6b91981b30..1eafcfc95e81 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -51,6 +51,7 @@
51#include <net/inet_common.h> 51#include <net/inet_common.h>
52#include <net/tcp.h> 52#include <net/tcp.h>
53#include <net/udp.h> 53#include <net/udp.h>
54#include <net/udplite.h>
54#include <net/xfrm.h> 55#include <net/xfrm.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
@@ -239,6 +240,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
239 struct sk_buff *pktopt; 240 struct sk_buff *pktopt;
240 241
241 if (sk->sk_protocol != IPPROTO_UDP && 242 if (sk->sk_protocol != IPPROTO_UDP &&
243 sk->sk_protocol != IPPROTO_UDPLITE &&
242 sk->sk_protocol != IPPROTO_TCP) 244 sk->sk_protocol != IPPROTO_TCP)
243 break; 245 break;
244 246
@@ -276,11 +278,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
276 sk->sk_family = PF_INET; 278 sk->sk_family = PF_INET;
277 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 279 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
278 } else { 280 } else {
281 struct proto *prot = &udp_prot;
282
283 if (sk->sk_protocol == IPPROTO_UDPLITE)
284 prot = &udplite_prot;
279 local_bh_disable(); 285 local_bh_disable();
280 sock_prot_dec_use(sk->sk_prot); 286 sock_prot_dec_use(sk->sk_prot);
281 sock_prot_inc_use(&udp_prot); 287 sock_prot_inc_use(prot);
282 local_bh_enable(); 288 local_bh_enable();
283 sk->sk_prot = &udp_prot; 289 sk->sk_prot = prot;
284 sk->sk_socket->ops = &inet_dgram_ops; 290 sk->sk_socket->ops = &inet_dgram_ops;
285 sk->sk_family = PF_INET; 291 sk->sk_family = PF_INET;
286 } 292 }
@@ -813,6 +819,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
813 switch (optname) { 819 switch (optname) {
814 case IPV6_ADDRFORM: 820 case IPV6_ADDRFORM:
815 if (sk->sk_protocol != IPPROTO_UDP && 821 if (sk->sk_protocol != IPPROTO_UDP &&
822 sk->sk_protocol != IPPROTO_UDPLITE &&
816 sk->sk_protocol != IPPROTO_TCP) 823 sk->sk_protocol != IPPROTO_TCP)
817 return -EINVAL; 824 return -EINVAL;
818 if (sk->sk_state != TCP_ESTABLISHED) 825 if (sk->sk_state != TCP_ESTABLISHED)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3b114e3fa2f8..a1c231a04ac2 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -83,7 +83,7 @@
83struct mld2_grec { 83struct mld2_grec {
84 __u8 grec_type; 84 __u8 grec_type;
85 __u8 grec_auxwords; 85 __u8 grec_auxwords;
86 __u16 grec_nsrcs; 86 __be16 grec_nsrcs;
87 struct in6_addr grec_mca; 87 struct in6_addr grec_mca;
88 struct in6_addr grec_src[0]; 88 struct in6_addr grec_src[0];
89}; 89};
@@ -91,18 +91,18 @@ struct mld2_grec {
91struct mld2_report { 91struct mld2_report {
92 __u8 type; 92 __u8 type;
93 __u8 resv1; 93 __u8 resv1;
94 __u16 csum; 94 __sum16 csum;
95 __u16 resv2; 95 __be16 resv2;
96 __u16 ngrec; 96 __be16 ngrec;
97 struct mld2_grec grec[0]; 97 struct mld2_grec grec[0];
98}; 98};
99 99
100struct mld2_query { 100struct mld2_query {
101 __u8 type; 101 __u8 type;
102 __u8 code; 102 __u8 code;
103 __u16 csum; 103 __sum16 csum;
104 __u16 mrc; 104 __be16 mrc;
105 __u16 resv1; 105 __be16 resv1;
106 struct in6_addr mca; 106 struct in6_addr mca;
107#if defined(__LITTLE_ENDIAN_BITFIELD) 107#if defined(__LITTLE_ENDIAN_BITFIELD)
108 __u8 qrv:3, 108 __u8 qrv:3,
@@ -116,7 +116,7 @@ struct mld2_query {
116#error "Please fix <asm/byteorder.h>" 116#error "Please fix <asm/byteorder.h>"
117#endif 117#endif
118 __u8 qqic; 118 __u8 qqic;
119 __u16 nsrcs; 119 __be16 nsrcs;
120 struct in6_addr srcs[0]; 120 struct in6_addr srcs[0];
121}; 121};
122 122
@@ -1465,7 +1465,7 @@ static void mld_sendpack(struct sk_buff *skb)
1465 struct inet6_dev *idev = in6_dev_get(skb->dev); 1465 struct inet6_dev *idev = in6_dev_get(skb->dev);
1466 int err; 1466 int err;
1467 1467
1468 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1468 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1469 payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - 1469 payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
1470 sizeof(struct ipv6hdr); 1470 sizeof(struct ipv6hdr);
1471 mldlen = skb->tail - skb->h.raw; 1471 mldlen = skb->tail - skb->h.raw;
@@ -1477,9 +1477,9 @@ static void mld_sendpack(struct sk_buff *skb)
1477 mld_dev_queue_xmit); 1477 mld_dev_queue_xmit);
1478 if (!err) { 1478 if (!err) {
1479 ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); 1479 ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
1480 IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); 1480 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
1481 } else 1481 } else
1482 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1482 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
1483 1483
1484 if (likely(idev != NULL)) 1484 if (likely(idev != NULL))
1485 in6_dev_put(idev); 1485 in6_dev_put(idev);
@@ -1763,7 +1763,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1763 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1763 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1764 IPV6_TLV_PADN, 0 }; 1764 IPV6_TLV_PADN, 0 };
1765 1765
1766 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1766 rcu_read_lock();
1767 IP6_INC_STATS(__in6_dev_get(dev),
1768 IPSTATS_MIB_OUTREQUESTS);
1769 rcu_read_unlock();
1767 snd_addr = addr; 1770 snd_addr = addr;
1768 if (type == ICMPV6_MGM_REDUCTION) { 1771 if (type == ICMPV6_MGM_REDUCTION) {
1769 snd_addr = &all_routers; 1772 snd_addr = &all_routers;
@@ -1777,7 +1780,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1777 skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err); 1780 skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
1778 1781
1779 if (skb == NULL) { 1782 if (skb == NULL) {
1780 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1783 rcu_read_lock();
1784 IP6_INC_STATS(__in6_dev_get(dev),
1785 IPSTATS_MIB_OUTDISCARDS);
1786 rcu_read_unlock();
1781 return; 1787 return;
1782 } 1788 }
1783 1789
@@ -1816,9 +1822,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1816 else 1822 else
1817 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES); 1823 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES);
1818 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1824 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1819 IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); 1825 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
1820 } else 1826 } else
1821 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1827 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
1822 1828
1823 if (likely(idev != NULL)) 1829 if (likely(idev != NULL))
1824 in6_dev_put(idev); 1830 in6_dev_put(idev);
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 7ccdc8fc5a31..be7dd7db65d7 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -262,10 +262,10 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct
262 sel.proto = fl->proto; 262 sel.proto = fl->proto;
263 sel.dport = xfrm_flowi_dport(fl); 263 sel.dport = xfrm_flowi_dport(fl);
264 if (sel.dport) 264 if (sel.dport)
265 sel.dport_mask = ~((__u16)0); 265 sel.dport_mask = htons(~0);
266 sel.sport = xfrm_flowi_sport(fl); 266 sel.sport = xfrm_flowi_sport(fl);
267 if (sel.sport) 267 if (sel.sport)
268 sel.sport_mask = ~((__u16)0); 268 sel.sport_mask = htons(~0);
269 sel.ifindex = fl->oif; 269 sel.ifindex = fl->oif;
270 270
271 err = km_report(IPPROTO_DSTOPTS, &sel, 271 err = km_report(IPPROTO_DSTOPTS, &sel,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 73eb8c33e9f0..56ea92837307 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -472,7 +472,9 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
472 inc_opt = 0; 472 inc_opt = 0;
473 } 473 }
474 474
475 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 475 skb = sock_alloc_send_skb(sk,
476 (MAX_HEADER + sizeof(struct ipv6hdr) +
477 len + LL_RESERVED_SPACE(dev)),
476 1, &err); 478 1, &err);
477 479
478 if (skb == NULL) { 480 if (skb == NULL) {
@@ -513,7 +515,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
513 515
514 skb->dst = dst; 516 skb->dst = dst;
515 idev = in6_dev_get(dst->dev); 517 idev = in6_dev_get(dst->dev);
516 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 518 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
517 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 519 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
518 if (!err) { 520 if (!err) {
519 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS); 521 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
@@ -561,7 +563,9 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
561 if (send_llinfo) 563 if (send_llinfo)
562 len += ndisc_opt_addr_space(dev); 564 len += ndisc_opt_addr_space(dev);
563 565
564 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 566 skb = sock_alloc_send_skb(sk,
567 (MAX_HEADER + sizeof(struct ipv6hdr) +
568 len + LL_RESERVED_SPACE(dev)),
565 1, &err); 569 1, &err);
566 if (skb == NULL) { 570 if (skb == NULL) {
567 ND_PRINTK0(KERN_ERR 571 ND_PRINTK0(KERN_ERR
@@ -597,7 +601,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
597 /* send it! */ 601 /* send it! */
598 skb->dst = dst; 602 skb->dst = dst;
599 idev = in6_dev_get(dst->dev); 603 idev = in6_dev_get(dst->dev);
600 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 604 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
601 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 605 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
602 if (!err) { 606 if (!err) {
603 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS); 607 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
@@ -636,7 +640,9 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
636 if (dev->addr_len) 640 if (dev->addr_len)
637 len += ndisc_opt_addr_space(dev); 641 len += ndisc_opt_addr_space(dev);
638 642
639 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 643 skb = sock_alloc_send_skb(sk,
644 (MAX_HEADER + sizeof(struct ipv6hdr) +
645 len + LL_RESERVED_SPACE(dev)),
640 1, &err); 646 1, &err);
641 if (skb == NULL) { 647 if (skb == NULL) {
642 ND_PRINTK0(KERN_ERR 648 ND_PRINTK0(KERN_ERR
@@ -670,7 +676,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
670 /* send it! */ 676 /* send it! */
671 skb->dst = dst; 677 skb->dst = dst;
672 idev = in6_dev_get(dst->dev); 678 idev = in6_dev_get(dst->dev);
673 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 679 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
674 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 680 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
675 if (!err) { 681 if (!err) {
676 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS); 682 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
@@ -1261,10 +1267,11 @@ skip_defrtr:
1261 } 1267 }
1262 1268
1263 if (ndopts.nd_opts_mtu) { 1269 if (ndopts.nd_opts_mtu) {
1270 __be32 n;
1264 u32 mtu; 1271 u32 mtu;
1265 1272
1266 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu)); 1273 memcpy(&n, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1267 mtu = ntohl(mtu); 1274 mtu = ntohl(n);
1268 1275
1269 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) { 1276 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1270 ND_PRINTK2(KERN_WARNING 1277 ND_PRINTK2(KERN_WARNING
@@ -1446,7 +1453,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1446 rd_len &= ~0x7; 1453 rd_len &= ~0x7;
1447 len += rd_len; 1454 len += rd_len;
1448 1455
1449 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 1456 buff = sock_alloc_send_skb(sk,
1457 (MAX_HEADER + sizeof(struct ipv6hdr) +
1458 len + LL_RESERVED_SPACE(dev)),
1450 1, &err); 1459 1, &err);
1451 if (buff == NULL) { 1460 if (buff == NULL) {
1452 ND_PRINTK0(KERN_ERR 1461 ND_PRINTK0(KERN_ERR
@@ -1504,7 +1513,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1504 1513
1505 buff->dst = dst; 1514 buff->dst = dst;
1506 idev = in6_dev_get(dst->dev); 1515 idev = in6_dev_get(dst->dev);
1507 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1516 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1508 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); 1517 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1509 if (!err) { 1518 if (!err) {
1510 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS); 1519 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 580b1aba6722..f6294e5bcb31 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -31,7 +31,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
31#endif 31#endif
32 32
33 if (dst->error) { 33 if (dst->error) {
34 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 34 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
35 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); 35 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
36 dst_release(dst); 36 dst_release(dst);
37 return -EINVAL; 37 return -EINVAL;
@@ -80,11 +80,11 @@ static int nf_ip6_reroute(struct sk_buff **pskb, const struct nf_info *info)
80 return 0; 80 return 0;
81} 81}
82 82
83unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, 83__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
84 unsigned int dataoff, u_int8_t protocol) 84 unsigned int dataoff, u_int8_t protocol)
85{ 85{
86 struct ipv6hdr *ip6h = skb->nh.ipv6h; 86 struct ipv6hdr *ip6h = skb->nh.ipv6h;
87 unsigned int csum = 0; 87 __sum16 csum = 0;
88 88
89 switch (skb->ip_summed) { 89 switch (skb->ip_summed) {
90 case CHECKSUM_COMPLETE: 90 case CHECKSUM_COMPLETE:
@@ -100,12 +100,13 @@ unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
100 } 100 }
101 /* fall through */ 101 /* fall through */
102 case CHECKSUM_NONE: 102 case CHECKSUM_NONE:
103 skb->csum = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, 103 skb->csum = ~csum_unfold(
104 csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
104 skb->len - dataoff, 105 skb->len - dataoff,
105 protocol, 106 protocol,
106 csum_sub(0, 107 csum_sub(0,
107 skb_checksum(skb, 0, 108 skb_checksum(skb, 0,
108 dataoff, 0))); 109 dataoff, 0))));
109 csum = __skb_checksum_complete(skb); 110 csum = __skb_checksum_complete(skb);
110 } 111 }
111 return csum; 112 return csum;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index d7c45a9c15fe..fc3e5eb4bc3f 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -6,7 +6,7 @@ menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
6 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL 6 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
7 7
8config NF_CONNTRACK_IPV6 8config NF_CONNTRACK_IPV6
9 tristate "IPv6 support for new connection tracking (EXPERIMENTAL)" 9 tristate "IPv6 connection tracking support (EXPERIMENTAL)"
10 depends on EXPERIMENTAL && NF_CONNTRACK 10 depends on EXPERIMENTAL && NF_CONNTRACK
11 ---help--- 11 ---help---
12 Connection tracking keeps a record of what packets have passed 12 Connection tracking keeps a record of what packets have passed
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 9fec832ee08b..d4d9f182441a 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -241,7 +241,7 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
241 pmsg->data_len = data_len; 241 pmsg->data_len = data_len;
242 pmsg->timestamp_sec = entry->skb->tstamp.off_sec; 242 pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
243 pmsg->timestamp_usec = entry->skb->tstamp.off_usec; 243 pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
244 pmsg->mark = entry->skb->nfmark; 244 pmsg->mark = entry->skb->mark;
245 pmsg->hook = entry->info->hook; 245 pmsg->hook = entry->info->hook;
246 pmsg->hw_protocol = entry->skb->protocol; 246 pmsg->hw_protocol = entry->skb->protocol;
247 247
@@ -620,6 +620,7 @@ static ctl_table ipq_root_table[] = {
620 { .ctl_name = 0 } 620 { .ctl_name = 0 }
621}; 621};
622 622
623#ifdef CONFIG_PROC_FS
623static int 624static int
624ipq_get_info(char *buffer, char **start, off_t offset, int length) 625ipq_get_info(char *buffer, char **start, off_t offset, int length)
625{ 626{
@@ -653,6 +654,7 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
653 len = 0; 654 len = 0;
654 return len; 655 return len;
655} 656}
657#endif /* CONFIG_PROC_FS */
656 658
657static struct nf_queue_handler nfqh = { 659static struct nf_queue_handler nfqh = {
658 .name = "ip6_queue", 660 .name = "ip6_queue",
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 204e02162d49..f63fb86d7c7b 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1481,7 +1481,8 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
1481 if (hp == NULL) 1481 if (hp == NULL)
1482 return -EBADMSG; 1482 return -EBADMSG;
1483 if (nexthdr == NEXTHDR_FRAGMENT) { 1483 if (nexthdr == NEXTHDR_FRAGMENT) {
1484 unsigned short _frag_off, *fp; 1484 unsigned short _frag_off;
1485 __be16 *fp;
1485 fp = skb_header_pointer(skb, 1486 fp = skb_header_pointer(skb,
1486 start+offsetof(struct frag_hdr, 1487 start+offsetof(struct frag_hdr,
1487 frag_off), 1488 frag_off),
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 0cf537d30185..33b1faa90d74 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -69,9 +69,9 @@ static void dump_packet(const struct nf_loginfo *info,
69 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ 69 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
70 printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", 70 printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
71 ntohs(ih->payload_len) + sizeof(struct ipv6hdr), 71 ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
72 (ntohl(*(u_int32_t *)ih) & 0x0ff00000) >> 20, 72 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
73 ih->hop_limit, 73 ih->hop_limit,
74 (ntohl(*(u_int32_t *)ih) & 0x000fffff)); 74 (ntohl(*(__be32 *)ih) & 0x000fffff));
75 75
76 fragment = 0; 76 fragment = 0;
77 ptr = ip6hoff + sizeof(struct ipv6hdr); 77 ptr = ip6hoff + sizeof(struct ipv6hdr);
@@ -270,11 +270,15 @@ static void dump_packet(const struct nf_loginfo *info,
270 } 270 }
271 break; 271 break;
272 } 272 }
273 case IPPROTO_UDP: { 273 case IPPROTO_UDP:
274 case IPPROTO_UDPLITE: {
274 struct udphdr _udph, *uh; 275 struct udphdr _udph, *uh;
275 276
276 /* Max length: 10 "PROTO=UDP " */ 277 if (currenthdr == IPPROTO_UDP)
277 printk("PROTO=UDP "); 278 /* Max length: 10 "PROTO=UDP " */
279 printk("PROTO=UDP " );
280 else /* Max length: 14 "PROTO=UDPLITE " */
281 printk("PROTO=UDPLITE ");
278 282
279 if (fragment) 283 if (fragment)
280 break; 284 break;
@@ -436,13 +440,8 @@ ip6t_log_target(struct sk_buff **pskb,
436 li.u.log.level = loginfo->level; 440 li.u.log.level = loginfo->level;
437 li.u.log.logflags = loginfo->logflags; 441 li.u.log.logflags = loginfo->logflags;
438 442
439 if (loginfo->logflags & IP6T_LOG_NFLOG) 443 ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
440 nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, 444 loginfo->prefix);
441 "%s", loginfo->prefix);
442 else
443 ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
444 loginfo->prefix);
445
446 return IP6T_CONTINUE; 445 return IP6T_CONTINUE;
447} 446}
448 447
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 386ea260e767..6250e86a6ddc 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -149,11 +149,10 @@ ip6t_local_hook(unsigned int hook,
149 int (*okfn)(struct sk_buff *)) 149 int (*okfn)(struct sk_buff *))
150{ 150{
151 151
152 unsigned long nfmark;
153 unsigned int ret; 152 unsigned int ret;
154 struct in6_addr saddr, daddr; 153 struct in6_addr saddr, daddr;
155 u_int8_t hop_limit; 154 u_int8_t hop_limit;
156 u_int32_t flowlabel; 155 u_int32_t flowlabel, mark;
157 156
158#if 0 157#if 0
159 /* root is playing with raw sockets. */ 158 /* root is playing with raw sockets. */
@@ -165,10 +164,10 @@ ip6t_local_hook(unsigned int hook,
165 } 164 }
166#endif 165#endif
167 166
168 /* save source/dest address, nfmark, hoplimit, flowlabel, priority, */ 167 /* save source/dest address, mark, hoplimit, flowlabel, priority, */
169 memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr)); 168 memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
170 memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr)); 169 memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
171 nfmark = (*pskb)->nfmark; 170 mark = (*pskb)->mark;
172 hop_limit = (*pskb)->nh.ipv6h->hop_limit; 171 hop_limit = (*pskb)->nh.ipv6h->hop_limit;
173 172
174 /* flowlabel and prio (includes version, which shouldn't change either */ 173 /* flowlabel and prio (includes version, which shouldn't change either */
@@ -179,7 +178,7 @@ ip6t_local_hook(unsigned int hook,
179 if (ret != NF_DROP && ret != NF_STOLEN 178 if (ret != NF_DROP && ret != NF_STOLEN
180 && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr)) 179 && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr))
181 || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr)) 180 || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr))
182 || (*pskb)->nfmark != nfmark 181 || (*pskb)->mark != mark
183 || (*pskb)->nh.ipv6h->hop_limit != hop_limit)) 182 || (*pskb)->nh.ipv6h->hop_limit != hop_limit))
184 return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP; 183 return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP;
185 184
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e5e53fff9e38..a20615ffccff 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -33,7 +33,7 @@
33#include <linux/netfilter_ipv6.h> 33#include <linux/netfilter_ipv6.h>
34#include <net/netfilter/nf_conntrack.h> 34#include <net/netfilter/nf_conntrack.h>
35#include <net/netfilter/nf_conntrack_helper.h> 35#include <net/netfilter/nf_conntrack_helper.h>
36#include <net/netfilter/nf_conntrack_protocol.h> 36#include <net/netfilter/nf_conntrack_l4proto.h>
37#include <net/netfilter/nf_conntrack_l3proto.h> 37#include <net/netfilter/nf_conntrack_l3proto.h>
38#include <net/netfilter/nf_conntrack_core.h> 38#include <net/netfilter/nf_conntrack_core.h>
39 39
@@ -43,8 +43,6 @@
43#define DEBUGP(format, args...) 43#define DEBUGP(format, args...)
44#endif 44#endif
45 45
46DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
47
48static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 46static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
49 struct nf_conntrack_tuple *tuple) 47 struct nf_conntrack_tuple *tuple)
50{ 48{
@@ -211,11 +209,6 @@ out:
211 return nf_conntrack_confirm(pskb); 209 return nf_conntrack_confirm(pskb);
212} 210}
213 211
214extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
215extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
216 struct net_device *in,
217 struct net_device *out,
218 int (*okfn)(struct sk_buff *));
219static unsigned int ipv6_defrag(unsigned int hooknum, 212static unsigned int ipv6_defrag(unsigned int hooknum,
220 struct sk_buff **pskb, 213 struct sk_buff **pskb,
221 const struct net_device *in, 214 const struct net_device *in,
@@ -331,26 +324,7 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = {
331}; 324};
332 325
333#ifdef CONFIG_SYSCTL 326#ifdef CONFIG_SYSCTL
334 327static ctl_table nf_ct_ipv6_sysctl_table[] = {
335/* From nf_conntrack_proto_icmpv6.c */
336extern unsigned int nf_ct_icmpv6_timeout;
337
338/* From nf_conntrack_reasm.c */
339extern unsigned int nf_ct_frag6_timeout;
340extern unsigned int nf_ct_frag6_low_thresh;
341extern unsigned int nf_ct_frag6_high_thresh;
342
343static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
344
345static ctl_table nf_ct_sysctl_table[] = {
346 {
347 .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
348 .procname = "nf_conntrack_icmpv6_timeout",
349 .data = &nf_ct_icmpv6_timeout,
350 .maxlen = sizeof(unsigned int),
351 .mode = 0644,
352 .proc_handler = &proc_dointvec_jiffies,
353 },
354 { 328 {
355 .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT, 329 .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
356 .procname = "nf_conntrack_frag6_timeout", 330 .procname = "nf_conntrack_frag6_timeout",
@@ -377,26 +351,6 @@ static ctl_table nf_ct_sysctl_table[] = {
377 }, 351 },
378 { .ctl_name = 0 } 352 { .ctl_name = 0 }
379}; 353};
380
381static ctl_table nf_ct_netfilter_table[] = {
382 {
383 .ctl_name = NET_NETFILTER,
384 .procname = "netfilter",
385 .mode = 0555,
386 .child = nf_ct_sysctl_table,
387 },
388 { .ctl_name = 0 }
389};
390
391static ctl_table nf_ct_net_table[] = {
392 {
393 .ctl_name = CTL_NET,
394 .procname = "net",
395 .mode = 0555,
396 .child = nf_ct_netfilter_table,
397 },
398 { .ctl_name = 0 }
399};
400#endif 354#endif
401 355
402#if defined(CONFIG_NF_CT_NETLINK) || \ 356#if defined(CONFIG_NF_CT_NETLINK) || \
@@ -454,16 +408,14 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
454 .tuple_to_nfattr = ipv6_tuple_to_nfattr, 408 .tuple_to_nfattr = ipv6_tuple_to_nfattr,
455 .nfattr_to_tuple = ipv6_nfattr_to_tuple, 409 .nfattr_to_tuple = ipv6_nfattr_to_tuple,
456#endif 410#endif
411#ifdef CONFIG_SYSCTL
412 .ctl_table_path = nf_net_netfilter_sysctl_path,
413 .ctl_table = nf_ct_ipv6_sysctl_table,
414#endif
457 .get_features = ipv6_get_features, 415 .get_features = ipv6_get_features,
458 .me = THIS_MODULE, 416 .me = THIS_MODULE,
459}; 417};
460 418
461extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
462extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
463extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6;
464extern int nf_ct_frag6_init(void);
465extern void nf_ct_frag6_cleanup(void);
466
467MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); 419MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
468MODULE_LICENSE("GPL"); 420MODULE_LICENSE("GPL");
469MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); 421MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
@@ -479,19 +431,19 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
479 printk("nf_conntrack_ipv6: can't initialize frag6.\n"); 431 printk("nf_conntrack_ipv6: can't initialize frag6.\n");
480 return ret; 432 return ret;
481 } 433 }
482 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6); 434 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
483 if (ret < 0) { 435 if (ret < 0) {
484 printk("nf_conntrack_ipv6: can't register tcp.\n"); 436 printk("nf_conntrack_ipv6: can't register tcp.\n");
485 goto cleanup_frag6; 437 goto cleanup_frag6;
486 } 438 }
487 439
488 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp6); 440 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
489 if (ret < 0) { 441 if (ret < 0) {
490 printk("nf_conntrack_ipv6: can't register udp.\n"); 442 printk("nf_conntrack_ipv6: can't register udp.\n");
491 goto cleanup_tcp; 443 goto cleanup_tcp;
492 } 444 }
493 445
494 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmpv6); 446 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6);
495 if (ret < 0) { 447 if (ret < 0) {
496 printk("nf_conntrack_ipv6: can't register icmpv6.\n"); 448 printk("nf_conntrack_ipv6: can't register icmpv6.\n");
497 goto cleanup_udp; 449 goto cleanup_udp;
@@ -510,28 +462,16 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
510 "hook.\n"); 462 "hook.\n");
511 goto cleanup_ipv6; 463 goto cleanup_ipv6;
512 } 464 }
513#ifdef CONFIG_SYSCTL
514 nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
515 if (nf_ct_ipv6_sysctl_header == NULL) {
516 printk("nf_conntrack: can't register to sysctl.\n");
517 ret = -ENOMEM;
518 goto cleanup_hooks;
519 }
520#endif
521 return ret; 465 return ret;
522 466
523#ifdef CONFIG_SYSCTL
524 cleanup_hooks:
525 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
526#endif
527 cleanup_ipv6: 467 cleanup_ipv6:
528 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); 468 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
529 cleanup_icmpv6: 469 cleanup_icmpv6:
530 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6); 470 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
531 cleanup_udp: 471 cleanup_udp:
532 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6); 472 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
533 cleanup_tcp: 473 cleanup_tcp:
534 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); 474 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
535 cleanup_frag6: 475 cleanup_frag6:
536 nf_ct_frag6_cleanup(); 476 nf_ct_frag6_cleanup();
537 return ret; 477 return ret;
@@ -540,14 +480,11 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
540static void __exit nf_conntrack_l3proto_ipv6_fini(void) 480static void __exit nf_conntrack_l3proto_ipv6_fini(void)
541{ 481{
542 synchronize_net(); 482 synchronize_net();
543#ifdef CONFIG_SYSCTL
544 unregister_sysctl_table(nf_ct_ipv6_sysctl_header);
545#endif
546 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); 483 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
547 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); 484 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
548 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6); 485 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
549 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6); 486 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
550 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); 487 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
551 nf_ct_frag6_cleanup(); 488 nf_ct_frag6_cleanup();
552} 489}
553 490
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 34d447208ffd..3905cacc69af 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -29,11 +29,11 @@
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/netfilter_ipv6.h> 30#include <linux/netfilter_ipv6.h>
31#include <net/netfilter/nf_conntrack_tuple.h> 31#include <net/netfilter/nf_conntrack_tuple.h>
32#include <net/netfilter/nf_conntrack_protocol.h> 32#include <net/netfilter/nf_conntrack_l4proto.h>
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 __read_mostly = 30*HZ; 36static unsigned 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
@@ -142,9 +142,6 @@ static int icmpv6_new(struct nf_conn *conntrack,
142 return 1; 142 return 1;
143} 143}
144 144
145extern int
146nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, int len);
147extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
148static int 145static int
149icmpv6_error_message(struct sk_buff *skb, 146icmpv6_error_message(struct sk_buff *skb,
150 unsigned int icmp6off, 147 unsigned int icmp6off,
@@ -155,7 +152,7 @@ icmpv6_error_message(struct sk_buff *skb,
155 struct nf_conntrack_tuple_hash *h; 152 struct nf_conntrack_tuple_hash *h;
156 struct icmp6hdr _hdr, *hp; 153 struct icmp6hdr _hdr, *hp;
157 unsigned int inip6off; 154 unsigned int inip6off;
158 struct nf_conntrack_protocol *inproto; 155 struct nf_conntrack_l4proto *inproto;
159 u_int8_t inprotonum; 156 u_int8_t inprotonum;
160 unsigned int inprotoff; 157 unsigned int inprotoff;
161 158
@@ -185,7 +182,7 @@ icmpv6_error_message(struct sk_buff *skb,
185 return -NF_ACCEPT; 182 return -NF_ACCEPT;
186 } 183 }
187 184
188 inproto = __nf_ct_proto_find(PF_INET6, inprotonum); 185 inproto = __nf_ct_l4proto_find(PF_INET6, inprotonum);
189 186
190 /* Are they talking about one of our connections? */ 187 /* Are they talking about one of our connections? */
191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, 188 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
@@ -290,7 +287,7 @@ static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
290 tuple->dst.u.icmp.code = 287 tuple->dst.u.icmp.code =
291 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]); 288 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]);
292 tuple->src.u.icmp.id = 289 tuple->src.u.icmp.id =
293 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]); 290 *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]);
294 291
295 if (tuple->dst.u.icmp.type < 128 292 if (tuple->dst.u.icmp.type < 128
296 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) 293 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap)
@@ -301,10 +298,27 @@ static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
301} 298}
302#endif 299#endif
303 300
304struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 = 301#ifdef CONFIG_SYSCTL
302static struct ctl_table_header *icmpv6_sysctl_header;
303static struct ctl_table icmpv6_sysctl_table[] = {
304 {
305 .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
306 .procname = "nf_conntrack_icmpv6_timeout",
307 .data = &nf_ct_icmpv6_timeout,
308 .maxlen = sizeof(unsigned int),
309 .mode = 0644,
310 .proc_handler = &proc_dointvec_jiffies,
311 },
312 {
313 .ctl_name = 0
314 }
315};
316#endif /* CONFIG_SYSCTL */
317
318struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
305{ 319{
306 .l3proto = PF_INET6, 320 .l3proto = PF_INET6,
307 .proto = IPPROTO_ICMPV6, 321 .l4proto = IPPROTO_ICMPV6,
308 .name = "icmpv6", 322 .name = "icmpv6",
309 .pkt_to_tuple = icmpv6_pkt_to_tuple, 323 .pkt_to_tuple = icmpv6_pkt_to_tuple,
310 .invert_tuple = icmpv6_invert_tuple, 324 .invert_tuple = icmpv6_invert_tuple,
@@ -318,6 +332,10 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
318 .tuple_to_nfattr = icmpv6_tuple_to_nfattr, 332 .tuple_to_nfattr = icmpv6_tuple_to_nfattr,
319 .nfattr_to_tuple = icmpv6_nfattr_to_tuple, 333 .nfattr_to_tuple = icmpv6_nfattr_to_tuple,
320#endif 334#endif
335#ifdef CONFIG_SYSCTL
336 .ctl_table_header = &icmpv6_sysctl_header,
337 .ctl_table = icmpv6_sysctl_table,
338#endif
321}; 339};
322 340
323EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6); 341EXPORT_SYMBOL(nf_conntrack_l4proto_icmpv6);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index bf93c1ea6be9..37e5fca923aa 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -72,7 +72,7 @@ struct nf_ct_frag6_queue
72 struct hlist_node list; 72 struct hlist_node list;
73 struct list_head lru_list; /* lru list member */ 73 struct list_head lru_list; /* lru list member */
74 74
75 __u32 id; /* fragment id */ 75 __be32 id; /* fragment id */
76 struct in6_addr saddr; 76 struct in6_addr saddr;
77 struct in6_addr daddr; 77 struct in6_addr daddr;
78 78
@@ -115,28 +115,28 @@ static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
115 write_unlock(&nf_ct_frag6_lock); 115 write_unlock(&nf_ct_frag6_lock);
116} 116}
117 117
118static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr, 118static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
119 struct in6_addr *daddr) 119 struct in6_addr *daddr)
120{ 120{
121 u32 a, b, c; 121 u32 a, b, c;
122 122
123 a = saddr->s6_addr32[0]; 123 a = (__force u32)saddr->s6_addr32[0];
124 b = saddr->s6_addr32[1]; 124 b = (__force u32)saddr->s6_addr32[1];
125 c = saddr->s6_addr32[2]; 125 c = (__force u32)saddr->s6_addr32[2];
126 126
127 a += JHASH_GOLDEN_RATIO; 127 a += JHASH_GOLDEN_RATIO;
128 b += JHASH_GOLDEN_RATIO; 128 b += JHASH_GOLDEN_RATIO;
129 c += nf_ct_frag6_hash_rnd; 129 c += nf_ct_frag6_hash_rnd;
130 __jhash_mix(a, b, c); 130 __jhash_mix(a, b, c);
131 131
132 a += saddr->s6_addr32[3]; 132 a += (__force u32)saddr->s6_addr32[3];
133 b += daddr->s6_addr32[0]; 133 b += (__force u32)daddr->s6_addr32[0];
134 c += daddr->s6_addr32[1]; 134 c += (__force u32)daddr->s6_addr32[1];
135 __jhash_mix(a, b, c); 135 __jhash_mix(a, b, c);
136 136
137 a += daddr->s6_addr32[2]; 137 a += (__force u32)daddr->s6_addr32[2];
138 b += daddr->s6_addr32[3]; 138 b += (__force u32)daddr->s6_addr32[3];
139 c += id; 139 c += (__force u32)id;
140 __jhash_mix(a, b, c); 140 __jhash_mix(a, b, c);
141 141
142 return c & (FRAG6Q_HASHSZ - 1); 142 return c & (FRAG6Q_HASHSZ - 1);
@@ -338,7 +338,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
338 338
339 339
340static struct nf_ct_frag6_queue * 340static struct nf_ct_frag6_queue *
341nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst) 341nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, struct in6_addr *dst)
342{ 342{
343 struct nf_ct_frag6_queue *fq; 343 struct nf_ct_frag6_queue *fq;
344 344
@@ -366,7 +366,7 @@ oom:
366} 366}
367 367
368static __inline__ struct nf_ct_frag6_queue * 368static __inline__ struct nf_ct_frag6_queue *
369fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 369fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
370{ 370{
371 struct nf_ct_frag6_queue *fq; 371 struct nf_ct_frag6_queue *fq;
372 struct hlist_node *n; 372 struct hlist_node *n;
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index efee7a6301a8..35249d8487bb 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -49,6 +49,8 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
49 fold_prot_inuse(&tcpv6_prot)); 49 fold_prot_inuse(&tcpv6_prot));
50 seq_printf(seq, "UDP6: inuse %d\n", 50 seq_printf(seq, "UDP6: inuse %d\n",
51 fold_prot_inuse(&udpv6_prot)); 51 fold_prot_inuse(&udpv6_prot));
52 seq_printf(seq, "UDPLITE6: inuse %d\n",
53 fold_prot_inuse(&udplitev6_prot));
52 seq_printf(seq, "RAW6: inuse %d\n", 54 seq_printf(seq, "RAW6: inuse %d\n",
53 fold_prot_inuse(&rawv6_prot)); 55 fold_prot_inuse(&rawv6_prot));
54 seq_printf(seq, "FRAG6: inuse %d memory %d\n", 56 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
@@ -133,6 +135,14 @@ static struct snmp_mib snmp6_udp6_list[] = {
133 SNMP_MIB_SENTINEL 135 SNMP_MIB_SENTINEL
134}; 136};
135 137
138static struct snmp_mib snmp6_udplite6_list[] = {
139 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
140 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
141 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
142 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
143 SNMP_MIB_SENTINEL
144};
145
136static unsigned long 146static unsigned long
137fold_field(void *mib[], int offt) 147fold_field(void *mib[], int offt)
138{ 148{
@@ -161,11 +171,13 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
161 171
162 if (idev) { 172 if (idev) {
163 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); 173 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
174 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
164 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); 175 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
165 } else { 176 } else {
166 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); 177 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
167 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); 178 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
168 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); 179 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
180 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
169 } 181 }
170 return 0; 182 return 0;
171} 183}
@@ -281,6 +293,9 @@ int snmp6_alloc_dev(struct inet6_dev *idev)
281 if (!idev || !idev->dev) 293 if (!idev || !idev->dev)
282 return -EINVAL; 294 return -EINVAL;
283 295
296 if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ipstats_mib),
297 __alignof__(struct ipstats_mib)) < 0)
298 goto err_ip;
284 if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib), 299 if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
285 __alignof__(struct icmpv6_mib)) < 0) 300 __alignof__(struct icmpv6_mib)) < 0)
286 goto err_icmp; 301 goto err_icmp;
@@ -288,12 +303,15 @@ int snmp6_alloc_dev(struct inet6_dev *idev)
288 return 0; 303 return 0;
289 304
290err_icmp: 305err_icmp:
306 snmp6_mib_free((void **)idev->stats.ipv6);
307err_ip:
291 return err; 308 return err;
292} 309}
293 310
294int snmp6_free_dev(struct inet6_dev *idev) 311int snmp6_free_dev(struct inet6_dev *idev)
295{ 312{
296 snmp6_mib_free((void **)idev->stats.icmpv6); 313 snmp6_mib_free((void **)idev->stats.icmpv6);
314 snmp6_mib_free((void **)idev->stats.ipv6);
297 return 0; 315 return 0;
298} 316}
299 317
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d6dedc4aec77..c2e629d6aea4 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -220,7 +220,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
220 struct inet_sock *inet = inet_sk(sk); 220 struct inet_sock *inet = inet_sk(sk);
221 struct ipv6_pinfo *np = inet6_sk(sk); 221 struct ipv6_pinfo *np = inet6_sk(sk);
222 struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr; 222 struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
223 __u32 v4addr = 0; 223 __be32 v4addr = 0;
224 int addr_type; 224 int addr_type;
225 int err; 225 int err;
226 226
@@ -290,7 +290,7 @@ out:
290 290
291void rawv6_err(struct sock *sk, struct sk_buff *skb, 291void rawv6_err(struct sock *sk, struct sk_buff *skb,
292 struct inet6_skb_parm *opt, 292 struct inet6_skb_parm *opt,
293 int type, int code, int offset, u32 info) 293 int type, int code, int offset, __be32 info)
294{ 294{
295 struct inet_sock *inet = inet_sk(sk); 295 struct inet_sock *inet = inet_sk(sk);
296 struct ipv6_pinfo *np = inet6_sk(sk); 296 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -370,9 +370,9 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
370 skb->ip_summed = CHECKSUM_UNNECESSARY; 370 skb->ip_summed = CHECKSUM_UNNECESSARY;
371 } 371 }
372 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 372 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
373 skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr, 373 skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
374 &skb->nh.ipv6h->daddr, 374 &skb->nh.ipv6h->daddr,
375 skb->len, inet->num, 0); 375 skb->len, inet->num, 0));
376 376
377 if (inet->hdrincl) { 377 if (inet->hdrincl) {
378 if (skb_checksum_complete(skb)) { 378 if (skb_checksum_complete(skb)) {
@@ -479,8 +479,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
479 int offset; 479 int offset;
480 int len; 480 int len;
481 int total_len; 481 int total_len;
482 u32 tmp_csum; 482 __wsum tmp_csum;
483 u16 csum; 483 __sum16 csum;
484 484
485 if (!rp->checksum) 485 if (!rp->checksum)
486 goto send; 486 goto send;
@@ -530,16 +530,15 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
530 530
531 /* in case cksum was not initialized */ 531 /* in case cksum was not initialized */
532 if (unlikely(csum)) 532 if (unlikely(csum))
533 tmp_csum = csum_sub(tmp_csum, csum); 533 tmp_csum = csum_sub(tmp_csum, csum_unfold(csum));
534 534
535 tmp_csum = csum_ipv6_magic(&fl->fl6_src, 535 csum = csum_ipv6_magic(&fl->fl6_src,
536 &fl->fl6_dst, 536 &fl->fl6_dst,
537 total_len, fl->proto, tmp_csum); 537 total_len, fl->proto, tmp_csum);
538 538
539 if (tmp_csum == 0) 539 if (csum == 0 && fl->proto == IPPROTO_UDP)
540 tmp_csum = -1; 540 csum = CSUM_MANGLED_0;
541 541
542 csum = tmp_csum;
543 if (skb_store_bits(skb, offset, &csum, 2)) 542 if (skb_store_bits(skb, offset, &csum, 2))
544 BUG(); 543 BUG();
545 544
@@ -586,7 +585,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
586 if (err) 585 if (err)
587 goto error_fault; 586 goto error_fault;
588 587
589 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 588 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
590 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 589 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
591 dst_output); 590 dst_output);
592 if (err > 0) 591 if (err > 0)
@@ -600,7 +599,7 @@ error_fault:
600 err = -EFAULT; 599 err = -EFAULT;
601 kfree_skb(skb); 600 kfree_skb(skb);
602error: 601error:
603 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 602 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
604 return err; 603 return err;
605} 604}
606 605
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index f39bbedd1327..6f9a9046510f 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -47,6 +47,7 @@
47#include <net/snmp.h> 47#include <net/snmp.h>
48 48
49#include <net/ipv6.h> 49#include <net/ipv6.h>
50#include <net/ip6_route.h>
50#include <net/protocol.h> 51#include <net/protocol.h>
51#include <net/transp_v6.h> 52#include <net/transp_v6.h>
52#include <net/rawv6.h> 53#include <net/rawv6.h>
@@ -76,7 +77,7 @@ struct frag_queue
76 struct hlist_node list; 77 struct hlist_node list;
77 struct list_head lru_list; /* lru list member */ 78 struct list_head lru_list; /* lru list member */
78 79
79 __u32 id; /* fragment id */ 80 __be32 id; /* fragment id */
80 struct in6_addr saddr; 81 struct in6_addr saddr;
81 struct in6_addr daddr; 82 struct in6_addr daddr;
82 83
@@ -124,28 +125,28 @@ static __inline__ void fq_unlink(struct frag_queue *fq)
124 * callers should be careful not to use the hash value outside the ipfrag_lock 125 * callers should be careful not to use the hash value outside the ipfrag_lock
125 * as doing so could race with ipfrag_hash_rnd being recalculated. 126 * as doing so could race with ipfrag_hash_rnd being recalculated.
126 */ 127 */
127static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr, 128static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
128 struct in6_addr *daddr) 129 struct in6_addr *daddr)
129{ 130{
130 u32 a, b, c; 131 u32 a, b, c;
131 132
132 a = saddr->s6_addr32[0]; 133 a = (__force u32)saddr->s6_addr32[0];
133 b = saddr->s6_addr32[1]; 134 b = (__force u32)saddr->s6_addr32[1];
134 c = saddr->s6_addr32[2]; 135 c = (__force u32)saddr->s6_addr32[2];
135 136
136 a += JHASH_GOLDEN_RATIO; 137 a += JHASH_GOLDEN_RATIO;
137 b += JHASH_GOLDEN_RATIO; 138 b += JHASH_GOLDEN_RATIO;
138 c += ip6_frag_hash_rnd; 139 c += ip6_frag_hash_rnd;
139 __jhash_mix(a, b, c); 140 __jhash_mix(a, b, c);
140 141
141 a += saddr->s6_addr32[3]; 142 a += (__force u32)saddr->s6_addr32[3];
142 b += daddr->s6_addr32[0]; 143 b += (__force u32)daddr->s6_addr32[0];
143 c += daddr->s6_addr32[1]; 144 c += (__force u32)daddr->s6_addr32[1];
144 __jhash_mix(a, b, c); 145 __jhash_mix(a, b, c);
145 146
146 a += daddr->s6_addr32[2]; 147 a += (__force u32)daddr->s6_addr32[2];
147 b += daddr->s6_addr32[3]; 148 b += (__force u32)daddr->s6_addr32[3];
148 c += id; 149 c += (__force u32)id;
149 __jhash_mix(a, b, c); 150 __jhash_mix(a, b, c);
150 151
151 return c & (IP6Q_HASHSZ - 1); 152 return c & (IP6Q_HASHSZ - 1);
@@ -257,7 +258,7 @@ static __inline__ void fq_kill(struct frag_queue *fq)
257 } 258 }
258} 259}
259 260
260static void ip6_evictor(void) 261static void ip6_evictor(struct inet6_dev *idev)
261{ 262{
262 struct frag_queue *fq; 263 struct frag_queue *fq;
263 struct list_head *tmp; 264 struct list_head *tmp;
@@ -284,14 +285,14 @@ static void ip6_evictor(void)
284 spin_unlock(&fq->lock); 285 spin_unlock(&fq->lock);
285 286
286 fq_put(fq, &work); 287 fq_put(fq, &work);
287 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 288 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
288 } 289 }
289} 290}
290 291
291static void ip6_frag_expire(unsigned long data) 292static void ip6_frag_expire(unsigned long data)
292{ 293{
293 struct frag_queue *fq = (struct frag_queue *) data; 294 struct frag_queue *fq = (struct frag_queue *) data;
294 struct net_device *dev; 295 struct net_device *dev = NULL;
295 296
296 spin_lock(&fq->lock); 297 spin_lock(&fq->lock);
297 298
@@ -300,17 +301,19 @@ static void ip6_frag_expire(unsigned long data)
300 301
301 fq_kill(fq); 302 fq_kill(fq);
302 303
303 IP6_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT); 304 dev = dev_get_by_index(fq->iif);
304 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 305 if (!dev)
306 goto out;
307
308 rcu_read_lock();
309 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
310 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
311 rcu_read_unlock();
305 312
306 /* Don't send error if the first segment did not arrive. */ 313 /* Don't send error if the first segment did not arrive. */
307 if (!(fq->last_in&FIRST_IN) || !fq->fragments) 314 if (!(fq->last_in&FIRST_IN) || !fq->fragments)
308 goto out; 315 goto out;
309 316
310 dev = dev_get_by_index(fq->iif);
311 if (!dev)
312 goto out;
313
314 /* 317 /*
315 But use as source device on which LAST ARRIVED 318 But use as source device on which LAST ARRIVED
316 segment was received. And do not use fq->dev 319 segment was received. And do not use fq->dev
@@ -318,8 +321,9 @@ static void ip6_frag_expire(unsigned long data)
318 */ 321 */
319 fq->fragments->dev = dev; 322 fq->fragments->dev = dev;
320 icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); 323 icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev);
321 dev_put(dev);
322out: 324out:
325 if (dev)
326 dev_put(dev);
323 spin_unlock(&fq->lock); 327 spin_unlock(&fq->lock);
324 fq_put(fq, NULL); 328 fq_put(fq, NULL);
325} 329}
@@ -366,7 +370,8 @@ static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
366 370
367 371
368static struct frag_queue * 372static struct frag_queue *
369ip6_frag_create(u32 id, struct in6_addr *src, struct in6_addr *dst) 373ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
374 struct inet6_dev *idev)
370{ 375{
371 struct frag_queue *fq; 376 struct frag_queue *fq;
372 377
@@ -386,12 +391,13 @@ ip6_frag_create(u32 id, struct in6_addr *src, struct in6_addr *dst)
386 return ip6_frag_intern(fq); 391 return ip6_frag_intern(fq);
387 392
388oom: 393oom:
389 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 394 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
390 return NULL; 395 return NULL;
391} 396}
392 397
393static __inline__ struct frag_queue * 398static __inline__ struct frag_queue *
394fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 399fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
400 struct inet6_dev *idev)
395{ 401{
396 struct frag_queue *fq; 402 struct frag_queue *fq;
397 struct hlist_node *n; 403 struct hlist_node *n;
@@ -410,7 +416,7 @@ fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
410 } 416 }
411 read_unlock(&ip6_frag_lock); 417 read_unlock(&ip6_frag_lock);
412 418
413 return ip6_frag_create(id, src, dst); 419 return ip6_frag_create(id, src, dst, idev);
414} 420}
415 421
416 422
@@ -428,7 +434,8 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
428 ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1))); 434 ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
429 435
430 if ((unsigned int)end > IPV6_MAXPLEN) { 436 if ((unsigned int)end > IPV6_MAXPLEN) {
431 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 437 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
438 IPSTATS_MIB_INHDRERRORS);
432 icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); 439 icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
433 return; 440 return;
434 } 441 }
@@ -455,7 +462,8 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
455 /* RFC2460 says always send parameter problem in 462 /* RFC2460 says always send parameter problem in
456 * this case. -DaveM 463 * this case. -DaveM
457 */ 464 */
458 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 465 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
466 IPSTATS_MIB_INHDRERRORS);
459 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 467 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
460 offsetof(struct ipv6hdr, payload_len)); 468 offsetof(struct ipv6hdr, payload_len));
461 return; 469 return;
@@ -571,7 +579,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
571 return; 579 return;
572 580
573err: 581err:
574 IP6_INC_STATS(IPSTATS_MIB_REASMFAILS); 582 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
575 kfree_skb(skb); 583 kfree_skb(skb);
576} 584}
577 585
@@ -665,7 +673,9 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
665 if (head->ip_summed == CHECKSUM_COMPLETE) 673 if (head->ip_summed == CHECKSUM_COMPLETE)
666 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); 674 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
667 675
668 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 676 rcu_read_lock();
677 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
678 rcu_read_unlock();
669 fq->fragments = NULL; 679 fq->fragments = NULL;
670 return 1; 680 return 1;
671 681
@@ -677,7 +687,9 @@ out_oom:
677 if (net_ratelimit()) 687 if (net_ratelimit())
678 printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); 688 printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
679out_fail: 689out_fail:
680 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 690 rcu_read_lock();
691 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
692 rcu_read_unlock();
681 return -1; 693 return -1;
682} 694}
683 695
@@ -691,16 +703,16 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
691 703
692 hdr = skb->nh.ipv6h; 704 hdr = skb->nh.ipv6h;
693 705
694 IP6_INC_STATS_BH(IPSTATS_MIB_REASMREQDS); 706 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS);
695 707
696 /* Jumbo payload inhibits frag. header */ 708 /* Jumbo payload inhibits frag. header */
697 if (hdr->payload_len==0) { 709 if (hdr->payload_len==0) {
698 IP6_INC_STATS(IPSTATS_MIB_INHDRERRORS); 710 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
699 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); 711 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
700 return -1; 712 return -1;
701 } 713 }
702 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) { 714 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
703 IP6_INC_STATS(IPSTATS_MIB_INHDRERRORS); 715 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
704 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); 716 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
705 return -1; 717 return -1;
706 } 718 }
@@ -711,16 +723,17 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
711 if (!(fhdr->frag_off & htons(0xFFF9))) { 723 if (!(fhdr->frag_off & htons(0xFFF9))) {
712 /* It is not a fragmented frame */ 724 /* It is not a fragmented frame */
713 skb->h.raw += sizeof(struct frag_hdr); 725 skb->h.raw += sizeof(struct frag_hdr);
714 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 726 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
715 727
716 IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw; 728 IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw;
717 return 1; 729 return 1;
718 } 730 }
719 731
720 if (atomic_read(&ip6_frag_mem) > sysctl_ip6frag_high_thresh) 732 if (atomic_read(&ip6_frag_mem) > sysctl_ip6frag_high_thresh)
721 ip6_evictor(); 733 ip6_evictor(ip6_dst_idev(skb->dst));
722 734
723 if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr)) != NULL) { 735 if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr,
736 ip6_dst_idev(skb->dst))) != NULL) {
724 int ret = -1; 737 int ret = -1;
725 738
726 spin_lock(&fq->lock); 739 spin_lock(&fq->lock);
@@ -736,7 +749,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
736 return ret; 749 return ret;
737 } 750 }
738 751
739 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 752 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
740 kfree_skb(skb); 753 kfree_skb(skb);
741 return -1; 754 return -1;
742} 755}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b39ae99122d5..9f80518aacbd 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -440,7 +440,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
440 if (pref == ICMPV6_ROUTER_PREF_INVALID) 440 if (pref == ICMPV6_ROUTER_PREF_INVALID)
441 pref = ICMPV6_ROUTER_PREF_MEDIUM; 441 pref = ICMPV6_ROUTER_PREF_MEDIUM;
442 442
443 lifetime = htonl(rinfo->lifetime); 443 lifetime = ntohl(rinfo->lifetime);
444 if (lifetime == 0xffffffff) { 444 if (lifetime == 0xffffffff) {
445 /* infinity */ 445 /* infinity */
446 } else if (lifetime > 0x7fffffff/HZ) { 446 } else if (lifetime > 0x7fffffff/HZ) {
@@ -711,12 +711,10 @@ void ip6_route_input(struct sk_buff *skb)
711 .ip6_u = { 711 .ip6_u = {
712 .daddr = iph->daddr, 712 .daddr = iph->daddr,
713 .saddr = iph->saddr, 713 .saddr = iph->saddr,
714#ifdef CONFIG_IPV6_ROUTE_FWMARK 714 .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
715 .fwmark = skb->nfmark,
716#endif
717 .flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK,
718 }, 715 },
719 }, 716 },
717 .mark = skb->mark,
720 .proto = iph->nexthdr, 718 .proto = iph->nexthdr,
721 }; 719 };
722 720
@@ -942,7 +940,7 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
942 fib6_force_start_gc(); 940 fib6_force_start_gc();
943 941
944out: 942out:
945 return (struct dst_entry *)rt; 943 return &rt->u.dst;
946} 944}
947 945
948int ndisc_dst_gc(int *more) 946int ndisc_dst_gc(int *more)
@@ -1225,7 +1223,7 @@ out:
1225 if (idev) 1223 if (idev)
1226 in6_dev_put(idev); 1224 in6_dev_put(idev);
1227 if (rt) 1225 if (rt)
1228 dst_free((struct dst_entry *) rt); 1226 dst_free(&rt->u.dst);
1229 return err; 1227 return err;
1230} 1228}
1231 1229
@@ -1751,9 +1749,9 @@ static inline int ip6_pkt_drop(struct sk_buff *skb, int code)
1751{ 1749{
1752 int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); 1750 int type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
1753 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) 1751 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED)
1754 IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); 1752 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS);
1755 1753
1756 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 1754 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTNOROUTES);
1757 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1755 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev);
1758 kfree_skb(skb); 1756 kfree_skb(skb);
1759 return 0; 1757 return 0;
@@ -1824,7 +1822,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1824 rt->rt6i_flags |= RTF_LOCAL; 1822 rt->rt6i_flags |= RTF_LOCAL;
1825 rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); 1823 rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
1826 if (rt->rt6i_nexthop == NULL) { 1824 if (rt->rt6i_nexthop == NULL) {
1827 dst_free((struct dst_entry *) rt); 1825 dst_free(&rt->u.dst);
1828 return ERR_PTR(-ENOMEM); 1826 return ERR_PTR(-ENOMEM);
1829 } 1827 }
1830 1828
@@ -2008,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
2008 return ip6_route_add(&cfg); 2006 return ip6_route_add(&cfg);
2009} 2007}
2010 2008
2009static inline size_t rt6_nlmsg_size(void)
2010{
2011 return NLMSG_ALIGN(sizeof(struct rtmsg))
2012 + nla_total_size(16) /* RTA_SRC */
2013 + nla_total_size(16) /* RTA_DST */
2014 + nla_total_size(16) /* RTA_GATEWAY */
2015 + nla_total_size(16) /* RTA_PREFSRC */
2016 + nla_total_size(4) /* RTA_TABLE */
2017 + nla_total_size(4) /* RTA_IIF */
2018 + nla_total_size(4) /* RTA_OIF */
2019 + nla_total_size(4) /* RTA_PRIORITY */
2020 + nla_total_size(sizeof(struct rta_cacheinfo));
2021}
2022
2011static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, 2023static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2012 struct in6_addr *dst, struct in6_addr *src, 2024 struct in6_addr *dst, struct in6_addr *src,
2013 int iif, int type, u32 pid, u32 seq, 2025 int iif, int type, u32 pid, u32 seq,
@@ -2015,7 +2027,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2015{ 2027{
2016 struct rtmsg *rtm; 2028 struct rtmsg *rtm;
2017 struct nlmsghdr *nlh; 2029 struct nlmsghdr *nlh;
2018 struct rta_cacheinfo ci; 2030 long expires;
2019 u32 table; 2031 u32 table;
2020 2032
2021 if (prefix) { /* user wants prefix routes only */ 2033 if (prefix) { /* user wants prefix routes only */
@@ -2089,18 +2101,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2089 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); 2101 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
2090 2102
2091 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); 2103 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
2092 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2104
2093 if (rt->rt6i_expires) 2105 expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0;
2094 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); 2106 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0,
2095 else 2107 expires, rt->u.dst.error) < 0)
2096 ci.rta_expires = 0; 2108 goto nla_put_failure;
2097 ci.rta_used = rt->u.dst.__use;
2098 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
2099 ci.rta_error = rt->u.dst.error;
2100 ci.rta_id = 0;
2101 ci.rta_ts = 0;
2102 ci.rta_tsage = 0;
2103 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
2104 2109
2105 return nlmsg_end(skb, nlh); 2110 return nlmsg_end(skb, nlh);
2106 2111
@@ -2202,7 +2207,6 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2202 struct sk_buff *skb; 2207 struct sk_buff *skb;
2203 u32 pid = 0, seq = 0; 2208 u32 pid = 0, seq = 0;
2204 struct nlmsghdr *nlh = NULL; 2209 struct nlmsghdr *nlh = NULL;
2205 int payload = sizeof(struct rtmsg) + 256;
2206 int err = -ENOBUFS; 2210 int err = -ENOBUFS;
2207 2211
2208 if (info) { 2212 if (info) {
@@ -2212,15 +2216,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2212 seq = nlh->nlmsg_seq; 2216 seq = nlh->nlmsg_seq;
2213 } 2217 }
2214 2218
2215 skb = nlmsg_new(nlmsg_total_size(payload), gfp_any()); 2219 skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
2216 if (skb == NULL) 2220 if (skb == NULL)
2217 goto errout; 2221 goto errout;
2218 2222
2219 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); 2223 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2220 if (err < 0) { 2224 /* failure implies BUG in rt6_nlmsg_size() */
2221 kfree_skb(skb); 2225 BUG_ON(err < 0);
2222 goto errout;
2223 }
2224 2226
2225 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); 2227 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
2226errout: 2228errout:
@@ -2248,7 +2250,6 @@ struct rt6_proc_arg
2248static int rt6_info_route(struct rt6_info *rt, void *p_arg) 2250static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2249{ 2251{
2250 struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg; 2252 struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
2251 int i;
2252 2253
2253 if (arg->skip < arg->offset / RT6_INFO_LEN) { 2254 if (arg->skip < arg->offset / RT6_INFO_LEN) {
2254 arg->skip++; 2255 arg->skip++;
@@ -2258,38 +2259,28 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2258 if (arg->len >= arg->length) 2259 if (arg->len >= arg->length)
2259 return 0; 2260 return 0;
2260 2261
2261 for (i=0; i<16; i++) { 2262 arg->len += sprintf(arg->buffer + arg->len,
2262 sprintf(arg->buffer + arg->len, "%02x", 2263 NIP6_SEQFMT " %02x ",
2263 rt->rt6i_dst.addr.s6_addr[i]); 2264 NIP6(rt->rt6i_dst.addr),
2264 arg->len += 2;
2265 }
2266 arg->len += sprintf(arg->buffer + arg->len, " %02x ",
2267 rt->rt6i_dst.plen); 2265 rt->rt6i_dst.plen);
2268 2266
2269#ifdef CONFIG_IPV6_SUBTREES 2267#ifdef CONFIG_IPV6_SUBTREES
2270 for (i=0; i<16; i++) { 2268 arg->len += sprintf(arg->buffer + arg->len,
2271 sprintf(arg->buffer + arg->len, "%02x", 2269 NIP6_SEQFMT " %02x ",
2272 rt->rt6i_src.addr.s6_addr[i]); 2270 NIP6(rt->rt6i_src.addr),
2273 arg->len += 2;
2274 }
2275 arg->len += sprintf(arg->buffer + arg->len, " %02x ",
2276 rt->rt6i_src.plen); 2271 rt->rt6i_src.plen);
2277#else 2272#else
2278 sprintf(arg->buffer + arg->len, 2273 arg->len += sprintf(arg->buffer + arg->len,
2279 "00000000000000000000000000000000 00 "); 2274 "00000000000000000000000000000000 00 ");
2280 arg->len += 36;
2281#endif 2275#endif
2282 2276
2283 if (rt->rt6i_nexthop) { 2277 if (rt->rt6i_nexthop) {
2284 for (i=0; i<16; i++) { 2278 arg->len += sprintf(arg->buffer + arg->len,
2285 sprintf(arg->buffer + arg->len, "%02x", 2279 NIP6_SEQFMT,
2286 rt->rt6i_nexthop->primary_key[i]); 2280 NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
2287 arg->len += 2;
2288 }
2289 } else { 2281 } else {
2290 sprintf(arg->buffer + arg->len, 2282 arg->len += sprintf(arg->buffer + arg->len,
2291 "00000000000000000000000000000000"); 2283 "00000000000000000000000000000000");
2292 arg->len += 32;
2293 } 2284 }
2294 arg->len += sprintf(arg->buffer + arg->len, 2285 arg->len += sprintf(arg->buffer + arg->len,
2295 " %08x %08x %08x %08x %8s\n", 2286 " %08x %08x %08x %08x %8s\n",
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index be699f85b2c7..77b7b0911438 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -60,7 +60,7 @@
60 */ 60 */
61 61
62#define HASH_SIZE 16 62#define HASH_SIZE 16
63#define HASH(addr) ((addr^(addr>>4))&0xF) 63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
64 64
65static int ipip6_fb_tunnel_init(struct net_device *dev); 65static int ipip6_fb_tunnel_init(struct net_device *dev);
66static int ipip6_tunnel_init(struct net_device *dev); 66static int ipip6_tunnel_init(struct net_device *dev);
@@ -76,7 +76,7 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunne
76 76
77static DEFINE_RWLOCK(ipip6_lock); 77static DEFINE_RWLOCK(ipip6_lock);
78 78
79static struct ip_tunnel * ipip6_tunnel_lookup(u32 remote, u32 local) 79static struct ip_tunnel * ipip6_tunnel_lookup(__be32 remote, __be32 local)
80{ 80{
81 unsigned h0 = HASH(remote); 81 unsigned h0 = HASH(remote);
82 unsigned h1 = HASH(local); 82 unsigned h1 = HASH(local);
@@ -102,8 +102,8 @@ static struct ip_tunnel * ipip6_tunnel_lookup(u32 remote, u32 local)
102 102
103static struct ip_tunnel ** ipip6_bucket(struct ip_tunnel *t) 103static struct ip_tunnel ** ipip6_bucket(struct ip_tunnel *t)
104{ 104{
105 u32 remote = t->parms.iph.daddr; 105 __be32 remote = t->parms.iph.daddr;
106 u32 local = t->parms.iph.saddr; 106 __be32 local = t->parms.iph.saddr;
107 unsigned h = 0; 107 unsigned h = 0;
108 int prio = 0; 108 int prio = 0;
109 109
@@ -144,8 +144,8 @@ static void ipip6_tunnel_link(struct ip_tunnel *t)
144 144
145static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) 145static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create)
146{ 146{
147 u32 remote = parms->iph.daddr; 147 __be32 remote = parms->iph.daddr;
148 u32 local = parms->iph.saddr; 148 __be32 local = parms->iph.saddr;
149 struct ip_tunnel *t, **tp, *nt; 149 struct ip_tunnel *t, **tp, *nt;
150 struct net_device *dev; 150 struct net_device *dev;
151 unsigned h = 0; 151 unsigned h = 0;
@@ -405,9 +405,9 @@ out:
405/* Returns the embedded IPv4 address if the IPv6 address 405/* Returns the embedded IPv4 address if the IPv6 address
406 comes from 6to4 (RFC 3056) addr space */ 406 comes from 6to4 (RFC 3056) addr space */
407 407
408static inline u32 try_6to4(struct in6_addr *v6dst) 408static inline __be32 try_6to4(struct in6_addr *v6dst)
409{ 409{
410 u32 dst = 0; 410 __be32 dst = 0;
411 411
412 if (v6dst->s6_addr16[0] == htons(0x2002)) { 412 if (v6dst->s6_addr16[0] == htons(0x2002)) {
413 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */ 413 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
@@ -432,7 +432,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
432 struct net_device *tdev; /* Device to other host */ 432 struct net_device *tdev; /* Device to other host */
433 struct iphdr *iph; /* Our new IP header */ 433 struct iphdr *iph; /* Our new IP header */
434 int max_headroom; /* The extra header space needed */ 434 int max_headroom; /* The extra header space needed */
435 u32 dst = tiph->daddr; 435 __be32 dst = tiph->daddr;
436 int mtu; 436 int mtu;
437 struct in6_addr *addr6; 437 struct in6_addr *addr6;
438 int addr_type; 438 int addr_type;
@@ -809,7 +809,7 @@ static void __exit sit_destroy_tunnels(void)
809 } 809 }
810} 810}
811 811
812void __exit sit_cleanup(void) 812static void __exit sit_cleanup(void)
813{ 813{
814 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 814 inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
815 815
@@ -819,7 +819,7 @@ void __exit sit_cleanup(void)
819 rtnl_unlock(); 819 rtnl_unlock();
820} 820}
821 821
822int __init sit_init(void) 822static int __init sit_init(void)
823{ 823{
824 int err; 824 int err;
825 825
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4c2a7c0cafef..c25e930c2c69 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -66,10 +66,13 @@
66#include <linux/proc_fs.h> 66#include <linux/proc_fs.h>
67#include <linux/seq_file.h> 67#include <linux/seq_file.h>
68 68
69#include <linux/crypto.h>
70#include <linux/scatterlist.h>
71
69/* Socket used for sending RSTs and ACKs */ 72/* Socket used for sending RSTs and ACKs */
70static struct socket *tcp6_socket; 73static struct socket *tcp6_socket;
71 74
72static void tcp_v6_send_reset(struct sk_buff *skb); 75static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
73static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); 76static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
74static void tcp_v6_send_check(struct sock *sk, int len, 77static void tcp_v6_send_check(struct sock *sk, int len,
75 struct sk_buff *skb); 78 struct sk_buff *skb);
@@ -78,6 +81,10 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
78 81
79static struct inet_connection_sock_af_ops ipv6_mapped; 82static struct inet_connection_sock_af_ops ipv6_mapped;
80static struct inet_connection_sock_af_ops ipv6_specific; 83static struct inet_connection_sock_af_ops ipv6_specific;
84#ifdef CONFIG_TCP_MD5SIG
85static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
86static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
87#endif
81 88
82static int tcp_v6_get_port(struct sock *sk, unsigned short snum) 89static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
83{ 90{
@@ -98,27 +105,20 @@ static void tcp_v6_hash(struct sock *sk)
98 } 105 }
99} 106}
100 107
101static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len, 108static __inline__ __sum16 tcp_v6_check(struct tcphdr *th, int len,
102 struct in6_addr *saddr, 109 struct in6_addr *saddr,
103 struct in6_addr *daddr, 110 struct in6_addr *daddr,
104 unsigned long base) 111 __wsum base)
105{ 112{
106 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); 113 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
107} 114}
108 115
109static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) 116static __u32 tcp_v6_init_sequence(struct sk_buff *skb)
110{ 117{
111 if (skb->protocol == htons(ETH_P_IPV6)) { 118 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
112 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32, 119 skb->nh.ipv6h->saddr.s6_addr32,
113 skb->nh.ipv6h->saddr.s6_addr32, 120 skb->h.th->dest,
114 skb->h.th->dest, 121 skb->h.th->source);
115 skb->h.th->source);
116 } else {
117 return secure_tcp_sequence_number(skb->nh.iph->daddr,
118 skb->nh.iph->saddr,
119 skb->h.th->dest,
120 skb->h.th->source);
121 }
122} 122}
123 123
124static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 124static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
@@ -215,6 +215,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
215 215
216 icsk->icsk_af_ops = &ipv6_mapped; 216 icsk->icsk_af_ops = &ipv6_mapped;
217 sk->sk_backlog_rcv = tcp_v4_do_rcv; 217 sk->sk_backlog_rcv = tcp_v4_do_rcv;
218#ifdef CONFIG_TCP_MD5SIG
219 tp->af_specific = &tcp_sock_ipv6_mapped_specific;
220#endif
218 221
219 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); 222 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
220 223
@@ -222,6 +225,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
222 icsk->icsk_ext_hdr_len = exthdrlen; 225 icsk->icsk_ext_hdr_len = exthdrlen;
223 icsk->icsk_af_ops = &ipv6_specific; 226 icsk->icsk_af_ops = &ipv6_specific;
224 sk->sk_backlog_rcv = tcp_v6_do_rcv; 227 sk->sk_backlog_rcv = tcp_v6_do_rcv;
228#ifdef CONFIG_TCP_MD5SIG
229 tp->af_specific = &tcp_sock_ipv6_specific;
230#endif
225 goto failure; 231 goto failure;
226 } else { 232 } else {
227 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF), 233 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
@@ -310,7 +316,7 @@ failure:
310} 316}
311 317
312static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 318static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
313 int type, int code, int offset, __u32 info) 319 int type, int code, int offset, __be32 info)
314{ 320{
315 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 321 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
316 const struct tcphdr *th = (struct tcphdr *)(skb->data+offset); 322 const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
@@ -509,8 +515,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
509 515
510 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); 516 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
511 err = ip6_xmit(sk, skb, &fl, opt, 0); 517 err = ip6_xmit(sk, skb, &fl, opt, 0);
512 if (err == NET_XMIT_CN) 518 err = net_xmit_eval(err);
513 err = 0;
514 } 519 }
515 520
516done: 521done:
@@ -526,7 +531,396 @@ static void tcp_v6_reqsk_destructor(struct request_sock *req)
526 kfree_skb(inet6_rsk(req)->pktopts); 531 kfree_skb(inet6_rsk(req)->pktopts);
527} 532}
528 533
529static struct request_sock_ops tcp6_request_sock_ops = { 534#ifdef CONFIG_TCP_MD5SIG
535static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
536 struct in6_addr *addr)
537{
538 struct tcp_sock *tp = tcp_sk(sk);
539 int i;
540
541 BUG_ON(tp == NULL);
542
543 if (!tp->md5sig_info || !tp->md5sig_info->entries6)
544 return NULL;
545
546 for (i = 0; i < tp->md5sig_info->entries6; i++) {
547 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0)
548 return (struct tcp_md5sig_key *)&tp->md5sig_info->keys6[i];
549 }
550 return NULL;
551}
552
553static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk,
554 struct sock *addr_sk)
555{
556 return tcp_v6_md5_do_lookup(sk, &inet6_sk(addr_sk)->daddr);
557}
558
559static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
560 struct request_sock *req)
561{
562 return tcp_v6_md5_do_lookup(sk, &inet6_rsk(req)->rmt_addr);
563}
564
565static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
566 char *newkey, u8 newkeylen)
567{
568 /* Add key to the list */
569 struct tcp6_md5sig_key *key;
570 struct tcp_sock *tp = tcp_sk(sk);
571 struct tcp6_md5sig_key *keys;
572
573 key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer);
574 if (key) {
575 /* modify existing entry - just update that one */
576 kfree(key->key);
577 key->key = newkey;
578 key->keylen = newkeylen;
579 } else {
580 /* reallocate new list if current one is full. */
581 if (!tp->md5sig_info) {
582 tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info), GFP_ATOMIC);
583 if (!tp->md5sig_info) {
584 kfree(newkey);
585 return -ENOMEM;
586 }
587 }
588 tcp_alloc_md5sig_pool();
589 if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) {
590 keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) *
591 (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
592
593 if (!keys) {
594 tcp_free_md5sig_pool();
595 kfree(newkey);
596 return -ENOMEM;
597 }
598
599 if (tp->md5sig_info->entries6)
600 memmove(keys, tp->md5sig_info->keys6,
601 (sizeof (tp->md5sig_info->keys6[0]) *
602 tp->md5sig_info->entries6));
603
604 kfree(tp->md5sig_info->keys6);
605 tp->md5sig_info->keys6 = keys;
606 tp->md5sig_info->alloced6++;
607 }
608
609 ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr,
610 peer);
611 tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey;
612 tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen;
613
614 tp->md5sig_info->entries6++;
615 }
616 return 0;
617}
618
619static int tcp_v6_md5_add_func(struct sock *sk, struct sock *addr_sk,
620 u8 *newkey, __u8 newkeylen)
621{
622 return tcp_v6_md5_do_add(sk, &inet6_sk(addr_sk)->daddr,
623 newkey, newkeylen);
624}
625
626static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
627{
628 struct tcp_sock *tp = tcp_sk(sk);
629 int i;
630
631 for (i = 0; i < tp->md5sig_info->entries6; i++) {
632 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) {
633 /* Free the key */
634 kfree(tp->md5sig_info->keys6[i].key);
635 tp->md5sig_info->entries6--;
636
637 if (tp->md5sig_info->entries6 == 0) {
638 kfree(tp->md5sig_info->keys6);
639 tp->md5sig_info->keys6 = NULL;
640
641 tcp_free_md5sig_pool();
642
643 return 0;
644 } else {
645 /* shrink the database */
646 if (tp->md5sig_info->entries6 != i)
647 memmove(&tp->md5sig_info->keys6[i],
648 &tp->md5sig_info->keys6[i+1],
649 (tp->md5sig_info->entries6 - i)
650 * sizeof (tp->md5sig_info->keys6[0]));
651 }
652 }
653 }
654 return -ENOENT;
655}
656
657static void tcp_v6_clear_md5_list (struct sock *sk)
658{
659 struct tcp_sock *tp = tcp_sk(sk);
660 int i;
661
662 if (tp->md5sig_info->entries6) {
663 for (i = 0; i < tp->md5sig_info->entries6; i++)
664 kfree(tp->md5sig_info->keys6[i].key);
665 tp->md5sig_info->entries6 = 0;
666 tcp_free_md5sig_pool();
667 }
668
669 kfree(tp->md5sig_info->keys6);
670 tp->md5sig_info->keys6 = NULL;
671 tp->md5sig_info->alloced6 = 0;
672
673 if (tp->md5sig_info->entries4) {
674 for (i = 0; i < tp->md5sig_info->entries4; i++)
675 kfree(tp->md5sig_info->keys4[i].key);
676 tp->md5sig_info->entries4 = 0;
677 tcp_free_md5sig_pool();
678 }
679
680 kfree(tp->md5sig_info->keys4);
681 tp->md5sig_info->keys4 = NULL;
682 tp->md5sig_info->alloced4 = 0;
683}
684
685static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
686 int optlen)
687{
688 struct tcp_md5sig cmd;
689 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr;
690 u8 *newkey;
691
692 if (optlen < sizeof(cmd))
693 return -EINVAL;
694
695 if (copy_from_user(&cmd, optval, sizeof(cmd)))
696 return -EFAULT;
697
698 if (sin6->sin6_family != AF_INET6)
699 return -EINVAL;
700
701 if (!cmd.tcpm_keylen) {
702 if (!tcp_sk(sk)->md5sig_info)
703 return -ENOENT;
704 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED)
705 return tcp_v4_md5_do_del(sk, sin6->sin6_addr.s6_addr32[3]);
706 return tcp_v6_md5_do_del(sk, &sin6->sin6_addr);
707 }
708
709 if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
710 return -EINVAL;
711
712 if (!tcp_sk(sk)->md5sig_info) {
713 struct tcp_sock *tp = tcp_sk(sk);
714 struct tcp_md5sig_info *p;
715
716 p = kzalloc(sizeof(struct tcp_md5sig_info), GFP_KERNEL);
717 if (!p)
718 return -ENOMEM;
719
720 tp->md5sig_info = p;
721 }
722
723 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
724 if (!newkey)
725 return -ENOMEM;
726 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED) {
727 return tcp_v4_md5_do_add(sk, sin6->sin6_addr.s6_addr32[3],
728 newkey, cmd.tcpm_keylen);
729 }
730 return tcp_v6_md5_do_add(sk, &sin6->sin6_addr, newkey, cmd.tcpm_keylen);
731}
732
733static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
734 struct in6_addr *saddr,
735 struct in6_addr *daddr,
736 struct tcphdr *th, int protocol,
737 int tcplen)
738{
739 struct scatterlist sg[4];
740 __u16 data_len;
741 int block = 0;
742 __sum16 cksum;
743 struct tcp_md5sig_pool *hp;
744 struct tcp6_pseudohdr *bp;
745 struct hash_desc *desc;
746 int err;
747 unsigned int nbytes = 0;
748
749 hp = tcp_get_md5sig_pool();
750 if (!hp) {
751 printk(KERN_WARNING "%s(): hash pool not found...\n", __FUNCTION__);
752 goto clear_hash_noput;
753 }
754 bp = &hp->md5_blk.ip6;
755 desc = &hp->md5_desc;
756
757 /* 1. TCP pseudo-header (RFC2460) */
758 ipv6_addr_copy(&bp->saddr, saddr);
759 ipv6_addr_copy(&bp->daddr, daddr);
760 bp->len = htonl(tcplen);
761 bp->protocol = htonl(protocol);
762
763 sg_set_buf(&sg[block++], bp, sizeof(*bp));
764 nbytes += sizeof(*bp);
765
766 /* 2. TCP header, excluding options */
767 cksum = th->check;
768 th->check = 0;
769 sg_set_buf(&sg[block++], th, sizeof(*th));
770 nbytes += sizeof(*th);
771
772 /* 3. TCP segment data (if any) */
773 data_len = tcplen - (th->doff << 2);
774 if (data_len > 0) {
775 u8 *data = (u8 *)th + (th->doff << 2);
776 sg_set_buf(&sg[block++], data, data_len);
777 nbytes += data_len;
778 }
779
780 /* 4. shared key */
781 sg_set_buf(&sg[block++], key->key, key->keylen);
782 nbytes += key->keylen;
783
784 /* Now store the hash into the packet */
785 err = crypto_hash_init(desc);
786 if (err) {
787 printk(KERN_WARNING "%s(): hash_init failed\n", __FUNCTION__);
788 goto clear_hash;
789 }
790 err = crypto_hash_update(desc, sg, nbytes);
791 if (err) {
792 printk(KERN_WARNING "%s(): hash_update failed\n", __FUNCTION__);
793 goto clear_hash;
794 }
795 err = crypto_hash_final(desc, md5_hash);
796 if (err) {
797 printk(KERN_WARNING "%s(): hash_final failed\n", __FUNCTION__);
798 goto clear_hash;
799 }
800
801 /* Reset header, and free up the crypto */
802 tcp_put_md5sig_pool();
803 th->check = cksum;
804out:
805 return 0;
806clear_hash:
807 tcp_put_md5sig_pool();
808clear_hash_noput:
809 memset(md5_hash, 0, 16);
810 goto out;
811}
812
813static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
814 struct sock *sk,
815 struct dst_entry *dst,
816 struct request_sock *req,
817 struct tcphdr *th, int protocol,
818 int tcplen)
819{
820 struct in6_addr *saddr, *daddr;
821
822 if (sk) {
823 saddr = &inet6_sk(sk)->saddr;
824 daddr = &inet6_sk(sk)->daddr;
825 } else {
826 saddr = &inet6_rsk(req)->loc_addr;
827 daddr = &inet6_rsk(req)->rmt_addr;
828 }
829 return tcp_v6_do_calc_md5_hash(md5_hash, key,
830 saddr, daddr,
831 th, protocol, tcplen);
832}
833
834static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
835{
836 __u8 *hash_location = NULL;
837 struct tcp_md5sig_key *hash_expected;
838 struct ipv6hdr *ip6h = skb->nh.ipv6h;
839 struct tcphdr *th = skb->h.th;
840 int length = (th->doff << 2) - sizeof (*th);
841 int genhash;
842 u8 *ptr;
843 u8 newhash[16];
844
845 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
846
847 /* If the TCP option is too short, we can short cut */
848 if (length < TCPOLEN_MD5SIG)
849 return hash_expected ? 1 : 0;
850
851 /* parse options */
852 ptr = (u8*)(th + 1);
853 while (length > 0) {
854 int opcode = *ptr++;
855 int opsize;
856
857 switch(opcode) {
858 case TCPOPT_EOL:
859 goto done_opts;
860 case TCPOPT_NOP:
861 length--;
862 continue;
863 default:
864 opsize = *ptr++;
865 if (opsize < 2 || opsize > length)
866 goto done_opts;
867 if (opcode == TCPOPT_MD5SIG) {
868 hash_location = ptr;
869 goto done_opts;
870 }
871 }
872 ptr += opsize - 2;
873 length -= opsize;
874 }
875
876done_opts:
877 /* do we have a hash as expected? */
878 if (!hash_expected) {
879 if (!hash_location)
880 return 0;
881 if (net_ratelimit()) {
882 printk(KERN_INFO "MD5 Hash NOT expected but found "
883 "(" NIP6_FMT ", %u)->"
884 "(" NIP6_FMT ", %u)\n",
885 NIP6(ip6h->saddr), ntohs(th->source),
886 NIP6(ip6h->daddr), ntohs(th->dest));
887 }
888 return 1;
889 }
890
891 if (!hash_location) {
892 if (net_ratelimit()) {
893 printk(KERN_INFO "MD5 Hash expected but NOT found "
894 "(" NIP6_FMT ", %u)->"
895 "(" NIP6_FMT ", %u)\n",
896 NIP6(ip6h->saddr), ntohs(th->source),
897 NIP6(ip6h->daddr), ntohs(th->dest));
898 }
899 return 1;
900 }
901
902 /* check the signature */
903 genhash = tcp_v6_do_calc_md5_hash(newhash,
904 hash_expected,
905 &ip6h->saddr, &ip6h->daddr,
906 th, sk->sk_protocol,
907 skb->len);
908 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
909 if (net_ratelimit()) {
910 printk(KERN_INFO "MD5 Hash %s for "
911 "(" NIP6_FMT ", %u)->"
912 "(" NIP6_FMT ", %u)\n",
913 genhash ? "failed" : "mismatch",
914 NIP6(ip6h->saddr), ntohs(th->source),
915 NIP6(ip6h->daddr), ntohs(th->dest));
916 }
917 return 1;
918 }
919 return 0;
920}
921#endif
922
923static struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
530 .family = AF_INET6, 924 .family = AF_INET6,
531 .obj_size = sizeof(struct tcp6_request_sock), 925 .obj_size = sizeof(struct tcp6_request_sock),
532 .rtx_syn_ack = tcp_v6_send_synack, 926 .rtx_syn_ack = tcp_v6_send_synack,
@@ -535,9 +929,16 @@ static struct request_sock_ops tcp6_request_sock_ops = {
535 .send_reset = tcp_v6_send_reset 929 .send_reset = tcp_v6_send_reset
536}; 930};
537 931
932#ifdef CONFIG_TCP_MD5SIG
933static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
934 .md5_lookup = tcp_v6_reqsk_md5_lookup,
935};
936#endif
937
538static struct timewait_sock_ops tcp6_timewait_sock_ops = { 938static struct timewait_sock_ops tcp6_timewait_sock_ops = {
539 .twsk_obj_size = sizeof(struct tcp6_timewait_sock), 939 .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
540 .twsk_unique = tcp_twsk_unique, 940 .twsk_unique = tcp_twsk_unique,
941 .twsk_destructor= tcp_twsk_destructor,
541}; 942};
542 943
543static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) 944static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
@@ -547,7 +948,7 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
547 948
548 if (skb->ip_summed == CHECKSUM_PARTIAL) { 949 if (skb->ip_summed == CHECKSUM_PARTIAL) {
549 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); 950 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0);
550 skb->csum = offsetof(struct tcphdr, check); 951 skb->csum_offset = offsetof(struct tcphdr, check);
551 } else { 952 } else {
552 th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 953 th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,
553 csum_partial((char *)th, th->doff<<2, 954 csum_partial((char *)th, th->doff<<2,
@@ -569,16 +970,20 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
569 th->check = 0; 970 th->check = 0;
570 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, 971 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
571 IPPROTO_TCP, 0); 972 IPPROTO_TCP, 0);
572 skb->csum = offsetof(struct tcphdr, check); 973 skb->csum_offset = offsetof(struct tcphdr, check);
573 skb->ip_summed = CHECKSUM_PARTIAL; 974 skb->ip_summed = CHECKSUM_PARTIAL;
574 return 0; 975 return 0;
575} 976}
576 977
577static void tcp_v6_send_reset(struct sk_buff *skb) 978static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
578{ 979{
579 struct tcphdr *th = skb->h.th, *t1; 980 struct tcphdr *th = skb->h.th, *t1;
580 struct sk_buff *buff; 981 struct sk_buff *buff;
581 struct flowi fl; 982 struct flowi fl;
983 int tot_len = sizeof(*th);
984#ifdef CONFIG_TCP_MD5SIG
985 struct tcp_md5sig_key *key;
986#endif
582 987
583 if (th->rst) 988 if (th->rst)
584 return; 989 return;
@@ -586,25 +991,35 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
586 if (!ipv6_unicast_destination(skb)) 991 if (!ipv6_unicast_destination(skb))
587 return; 992 return;
588 993
994#ifdef CONFIG_TCP_MD5SIG
995 if (sk)
996 key = tcp_v6_md5_do_lookup(sk, &skb->nh.ipv6h->daddr);
997 else
998 key = NULL;
999
1000 if (key)
1001 tot_len += TCPOLEN_MD5SIG_ALIGNED;
1002#endif
1003
589 /* 1004 /*
590 * We need to grab some memory, and put together an RST, 1005 * We need to grab some memory, and put together an RST,
591 * and then put it into the queue to be sent. 1006 * and then put it into the queue to be sent.
592 */ 1007 */
593 1008
594 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr), 1009 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
595 GFP_ATOMIC); 1010 GFP_ATOMIC);
596 if (buff == NULL) 1011 if (buff == NULL)
597 return; 1012 return;
598 1013
599 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)); 1014 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
600 1015
601 t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr)); 1016 t1 = (struct tcphdr *) skb_push(buff, tot_len);
602 1017
603 /* Swap the send and the receive. */ 1018 /* Swap the send and the receive. */
604 memset(t1, 0, sizeof(*t1)); 1019 memset(t1, 0, sizeof(*t1));
605 t1->dest = th->source; 1020 t1->dest = th->source;
606 t1->source = th->dest; 1021 t1->source = th->dest;
607 t1->doff = sizeof(*t1)/4; 1022 t1->doff = tot_len / 4;
608 t1->rst = 1; 1023 t1->rst = 1;
609 1024
610 if(th->ack) { 1025 if(th->ack) {
@@ -615,6 +1030,22 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
615 + skb->len - (th->doff<<2)); 1030 + skb->len - (th->doff<<2));
616 } 1031 }
617 1032
1033#ifdef CONFIG_TCP_MD5SIG
1034 if (key) {
1035 __be32 *opt = (__be32*)(t1 + 1);
1036 opt[0] = htonl((TCPOPT_NOP << 24) |
1037 (TCPOPT_NOP << 16) |
1038 (TCPOPT_MD5SIG << 8) |
1039 TCPOLEN_MD5SIG);
1040 tcp_v6_do_calc_md5_hash((__u8*)&opt[1],
1041 key,
1042 &skb->nh.ipv6h->daddr,
1043 &skb->nh.ipv6h->saddr,
1044 t1, IPPROTO_TCP,
1045 tot_len);
1046 }
1047#endif
1048
618 buff->csum = csum_partial((char *)t1, sizeof(*t1), 0); 1049 buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
619 1050
620 memset(&fl, 0, sizeof(fl)); 1051 memset(&fl, 0, sizeof(fl));
@@ -645,15 +1076,37 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
645 kfree_skb(buff); 1076 kfree_skb(buff);
646} 1077}
647 1078
648static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1079static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1080 struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
649{ 1081{
650 struct tcphdr *th = skb->h.th, *t1; 1082 struct tcphdr *th = skb->h.th, *t1;
651 struct sk_buff *buff; 1083 struct sk_buff *buff;
652 struct flowi fl; 1084 struct flowi fl;
653 int tot_len = sizeof(struct tcphdr); 1085 int tot_len = sizeof(struct tcphdr);
1086 __be32 *topt;
1087#ifdef CONFIG_TCP_MD5SIG
1088 struct tcp_md5sig_key *key;
1089 struct tcp_md5sig_key tw_key;
1090#endif
1091
1092#ifdef CONFIG_TCP_MD5SIG
1093 if (!tw && skb->sk) {
1094 key = tcp_v6_md5_do_lookup(skb->sk, &skb->nh.ipv6h->daddr);
1095 } else if (tw && tw->tw_md5_keylen) {
1096 tw_key.key = tw->tw_md5_key;
1097 tw_key.keylen = tw->tw_md5_keylen;
1098 key = &tw_key;
1099 } else {
1100 key = NULL;
1101 }
1102#endif
654 1103
655 if (ts) 1104 if (ts)
656 tot_len += TCPOLEN_TSTAMP_ALIGNED; 1105 tot_len += TCPOLEN_TSTAMP_ALIGNED;
1106#ifdef CONFIG_TCP_MD5SIG
1107 if (key)
1108 tot_len += TCPOLEN_MD5SIG_ALIGNED;
1109#endif
657 1110
658 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, 1111 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
659 GFP_ATOMIC); 1112 GFP_ATOMIC);
@@ -673,15 +1126,29 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
673 t1->ack_seq = htonl(ack); 1126 t1->ack_seq = htonl(ack);
674 t1->ack = 1; 1127 t1->ack = 1;
675 t1->window = htons(win); 1128 t1->window = htons(win);
1129
1130 topt = (__be32 *)(t1 + 1);
676 1131
677 if (ts) { 1132 if (ts) {
678 u32 *ptr = (u32*)(t1 + 1); 1133 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
679 *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 1134 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
680 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); 1135 *topt++ = htonl(tcp_time_stamp);
681 *ptr++ = htonl(tcp_time_stamp); 1136 *topt = htonl(ts);
682 *ptr = htonl(ts);
683 } 1137 }
684 1138
1139#ifdef CONFIG_TCP_MD5SIG
1140 if (key) {
1141 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
1142 (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
1143 tcp_v6_do_calc_md5_hash((__u8 *)topt,
1144 key,
1145 &skb->nh.ipv6h->daddr,
1146 &skb->nh.ipv6h->saddr,
1147 t1, IPPROTO_TCP,
1148 tot_len);
1149 }
1150#endif
1151
685 buff->csum = csum_partial((char *)t1, tot_len, 0); 1152 buff->csum = csum_partial((char *)t1, tot_len, 0);
686 1153
687 memset(&fl, 0, sizeof(fl)); 1154 memset(&fl, 0, sizeof(fl));
@@ -712,9 +1179,9 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
712static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) 1179static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
713{ 1180{
714 struct inet_timewait_sock *tw = inet_twsk(sk); 1181 struct inet_timewait_sock *tw = inet_twsk(sk);
715 const struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1182 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
716 1183
717 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1184 tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
718 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1185 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
719 tcptw->tw_ts_recent); 1186 tcptw->tw_ts_recent);
720 1187
@@ -723,7 +1190,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
723 1190
724static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1191static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
725{ 1192{
726 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1193 tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
727} 1194}
728 1195
729 1196
@@ -794,6 +1261,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
794 if (req == NULL) 1261 if (req == NULL)
795 goto drop; 1262 goto drop;
796 1263
1264#ifdef CONFIG_TCP_MD5SIG
1265 tcp_rsk(req)->af_specific = &tcp_request_sock_ipv6_ops;
1266#endif
1267
797 tcp_clear_options(&tmp_opt); 1268 tcp_clear_options(&tmp_opt);
798 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 1269 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
799 tmp_opt.user_mss = tp->rx_opt.user_mss; 1270 tmp_opt.user_mss = tp->rx_opt.user_mss;
@@ -822,7 +1293,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
822 treq->iif = inet6_iif(skb); 1293 treq->iif = inet6_iif(skb);
823 1294
824 if (isn == 0) 1295 if (isn == 0)
825 isn = tcp_v6_init_sequence(sk,skb); 1296 isn = tcp_v6_init_sequence(skb);
826 1297
827 tcp_rsk(req)->snt_isn = isn; 1298 tcp_rsk(req)->snt_isn = isn;
828 1299
@@ -852,6 +1323,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
852 struct tcp_sock *newtp; 1323 struct tcp_sock *newtp;
853 struct sock *newsk; 1324 struct sock *newsk;
854 struct ipv6_txoptions *opt; 1325 struct ipv6_txoptions *opt;
1326#ifdef CONFIG_TCP_MD5SIG
1327 struct tcp_md5sig_key *key;
1328#endif
855 1329
856 if (skb->protocol == htons(ETH_P_IP)) { 1330 if (skb->protocol == htons(ETH_P_IP)) {
857 /* 1331 /*
@@ -882,6 +1356,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
882 1356
883 inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; 1357 inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
884 newsk->sk_backlog_rcv = tcp_v4_do_rcv; 1358 newsk->sk_backlog_rcv = tcp_v4_do_rcv;
1359#ifdef CONFIG_TCP_MD5SIG
1360 newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
1361#endif
1362
885 newnp->pktoptions = NULL; 1363 newnp->pktoptions = NULL;
886 newnp->opt = NULL; 1364 newnp->opt = NULL;
887 newnp->mcast_oif = inet6_iif(skb); 1365 newnp->mcast_oif = inet6_iif(skb);
@@ -1016,6 +1494,21 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1016 1494
1017 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; 1495 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
1018 1496
1497#ifdef CONFIG_TCP_MD5SIG
1498 /* Copy over the MD5 key from the original socket */
1499 if ((key = tcp_v6_md5_do_lookup(sk, &newnp->daddr)) != NULL) {
1500 /* We're using one, so create a matching key
1501 * on the newsk structure. If we fail to get
1502 * memory, then we end up not copying the key
1503 * across. Shucks.
1504 */
1505 char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
1506 if (newkey != NULL)
1507 tcp_v6_md5_do_add(newsk, &inet6_sk(sk)->daddr,
1508 newkey, key->keylen);
1509 }
1510#endif
1511
1019 __inet6_hash(&tcp_hashinfo, newsk); 1512 __inet6_hash(&tcp_hashinfo, newsk);
1020 inet_inherit_port(&tcp_hashinfo, sk, newsk); 1513 inet_inherit_port(&tcp_hashinfo, sk, newsk);
1021 1514
@@ -1031,7 +1524,7 @@ out:
1031 return NULL; 1524 return NULL;
1032} 1525}
1033 1526
1034static int tcp_v6_checksum_init(struct sk_buff *skb) 1527static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
1035{ 1528{
1036 if (skb->ip_summed == CHECKSUM_COMPLETE) { 1529 if (skb->ip_summed == CHECKSUM_COMPLETE) {
1037 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1530 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
@@ -1041,8 +1534,8 @@ static int tcp_v6_checksum_init(struct sk_buff *skb)
1041 } 1534 }
1042 } 1535 }
1043 1536
1044 skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1537 skb->csum = ~csum_unfold(tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1045 &skb->nh.ipv6h->daddr, 0); 1538 &skb->nh.ipv6h->daddr, 0));
1046 1539
1047 if (skb->len <= 76) { 1540 if (skb->len <= 76) {
1048 return __skb_checksum_complete(skb); 1541 return __skb_checksum_complete(skb);
@@ -1075,6 +1568,11 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1075 if (skb->protocol == htons(ETH_P_IP)) 1568 if (skb->protocol == htons(ETH_P_IP))
1076 return tcp_v4_do_rcv(sk, skb); 1569 return tcp_v4_do_rcv(sk, skb);
1077 1570
1571#ifdef CONFIG_TCP_MD5SIG
1572 if (tcp_v6_inbound_md5_hash (sk, skb))
1573 goto discard;
1574#endif
1575
1078 if (sk_filter(sk, skb)) 1576 if (sk_filter(sk, skb))
1079 goto discard; 1577 goto discard;
1080 1578
@@ -1140,7 +1638,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1140 return 0; 1638 return 0;
1141 1639
1142reset: 1640reset:
1143 tcp_v6_send_reset(skb); 1641 tcp_v6_send_reset(sk, skb);
1144discard: 1642discard:
1145 if (opt_skb) 1643 if (opt_skb)
1146 __kfree_skb(opt_skb); 1644 __kfree_skb(opt_skb);
@@ -1265,7 +1763,7 @@ no_tcp_socket:
1265bad_packet: 1763bad_packet:
1266 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1764 TCP_INC_STATS_BH(TCP_MIB_INERRS);
1267 } else { 1765 } else {
1268 tcp_v6_send_reset(skb); 1766 tcp_v6_send_reset(NULL, skb);
1269 } 1767 }
1270 1768
1271discard_it: 1769discard_it:
@@ -1344,6 +1842,15 @@ static struct inet_connection_sock_af_ops ipv6_specific = {
1344#endif 1842#endif
1345}; 1843};
1346 1844
1845#ifdef CONFIG_TCP_MD5SIG
1846static struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
1847 .md5_lookup = tcp_v6_md5_lookup,
1848 .calc_md5_hash = tcp_v6_calc_md5_hash,
1849 .md5_add = tcp_v6_md5_add_func,
1850 .md5_parse = tcp_v6_parse_md5_keys,
1851};
1852#endif
1853
1347/* 1854/*
1348 * TCP over IPv4 via INET6 API 1855 * TCP over IPv4 via INET6 API
1349 */ 1856 */
@@ -1366,6 +1873,15 @@ static struct inet_connection_sock_af_ops ipv6_mapped = {
1366#endif 1873#endif
1367}; 1874};
1368 1875
1876#ifdef CONFIG_TCP_MD5SIG
1877static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
1878 .md5_lookup = tcp_v4_md5_lookup,
1879 .calc_md5_hash = tcp_v4_calc_md5_hash,
1880 .md5_add = tcp_v6_md5_add_func,
1881 .md5_parse = tcp_v6_parse_md5_keys,
1882};
1883#endif
1884
1369/* NOTE: A lot of things set to zero explicitly by call to 1885/* NOTE: A lot of things set to zero explicitly by call to
1370 * sk_alloc() so need not be done here. 1886 * sk_alloc() so need not be done here.
1371 */ 1887 */
@@ -1405,6 +1921,10 @@ static int tcp_v6_init_sock(struct sock *sk)
1405 sk->sk_write_space = sk_stream_write_space; 1921 sk->sk_write_space = sk_stream_write_space;
1406 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1922 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
1407 1923
1924#ifdef CONFIG_TCP_MD5SIG
1925 tp->af_specific = &tcp_sock_ipv6_specific;
1926#endif
1927
1408 sk->sk_sndbuf = sysctl_tcp_wmem[1]; 1928 sk->sk_sndbuf = sysctl_tcp_wmem[1];
1409 sk->sk_rcvbuf = sysctl_tcp_rmem[1]; 1929 sk->sk_rcvbuf = sysctl_tcp_rmem[1];
1410 1930
@@ -1415,6 +1935,11 @@ static int tcp_v6_init_sock(struct sock *sk)
1415 1935
1416static int tcp_v6_destroy_sock(struct sock *sk) 1936static int tcp_v6_destroy_sock(struct sock *sk)
1417{ 1937{
1938#ifdef CONFIG_TCP_MD5SIG
1939 /* Clean up the MD5 key list */
1940 if (tcp_sk(sk)->md5sig_info)
1941 tcp_v6_clear_md5_list(sk);
1942#endif
1418 tcp_v4_destroy_sock(sk); 1943 tcp_v4_destroy_sock(sk);
1419 return inet6_destroy_sock(sk); 1944 return inet6_destroy_sock(sk);
1420} 1945}
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 0ef9a35798d1..918d07dd1219 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -104,7 +104,7 @@ drop:
104} 104}
105 105
106static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 106static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
107 int type, int code, int offset, __u32 info) 107 int type, int code, int offset, __be32 info)
108{ 108{
109 struct xfrm6_tunnel *handler; 109 struct xfrm6_tunnel *handler;
110 110
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index c83f23e51c46..f52a5c3cc0a3 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -38,26 +38,18 @@
38#include <linux/skbuff.h> 38#include <linux/skbuff.h>
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
40 40
41#include <net/sock.h>
42#include <net/snmp.h>
43
44#include <net/ipv6.h>
45#include <net/ndisc.h> 41#include <net/ndisc.h>
46#include <net/protocol.h> 42#include <net/protocol.h>
47#include <net/transp_v6.h> 43#include <net/transp_v6.h>
48#include <net/ip6_route.h> 44#include <net/ip6_route.h>
49#include <net/addrconf.h>
50#include <net/ip.h>
51#include <net/udp.h>
52#include <net/raw.h> 45#include <net/raw.h>
53#include <net/inet_common.h>
54#include <net/tcp_states.h> 46#include <net/tcp_states.h>
55
56#include <net/ip6_checksum.h> 47#include <net/ip6_checksum.h>
57#include <net/xfrm.h> 48#include <net/xfrm.h>
58 49
59#include <linux/proc_fs.h> 50#include <linux/proc_fs.h>
60#include <linux/seq_file.h> 51#include <linux/seq_file.h>
52#include "udp_impl.h"
61 53
62DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; 54DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
63 55
@@ -66,23 +58,9 @@ static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
66 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal); 58 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
67} 59}
68 60
69static void udp_v6_hash(struct sock *sk) 61static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
70{ 62 struct in6_addr *daddr, __be16 dport,
71 BUG(); 63 int dif, struct hlist_head udptable[])
72}
73
74static void udp_v6_unhash(struct sock *sk)
75{
76 write_lock_bh(&udp_hash_lock);
77 if (sk_del_node_init(sk)) {
78 inet_sk(sk)->num = 0;
79 sock_prot_dec_use(sk->sk_prot);
80 }
81 write_unlock_bh(&udp_hash_lock);
82}
83
84static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
85 struct in6_addr *daddr, u16 dport, int dif)
86{ 64{
87 struct sock *sk, *result = NULL; 65 struct sock *sk, *result = NULL;
88 struct hlist_node *node; 66 struct hlist_node *node;
@@ -90,7 +68,7 @@ static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
90 int badness = -1; 68 int badness = -1;
91 69
92 read_lock(&udp_hash_lock); 70 read_lock(&udp_hash_lock);
93 sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) { 71 sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
94 struct inet_sock *inet = inet_sk(sk); 72 struct inet_sock *inet = inet_sk(sk);
95 73
96 if (inet->num == hnum && sk->sk_family == PF_INET6) { 74 if (inet->num == hnum && sk->sk_family == PF_INET6) {
@@ -132,20 +110,11 @@ static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
132} 110}
133 111
134/* 112/*
135 *
136 */
137
138static void udpv6_close(struct sock *sk, long timeout)
139{
140 sk_common_release(sk);
141}
142
143/*
144 * This should be easy, if there is something there we 113 * This should be easy, if there is something there we
145 * return it, otherwise we block. 114 * return it, otherwise we block.
146 */ 115 */
147 116
148static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, 117int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
149 struct msghdr *msg, size_t len, 118 struct msghdr *msg, size_t len,
150 int noblock, int flags, int *addr_len) 119 int noblock, int flags, int *addr_len)
151{ 120{
@@ -153,7 +122,7 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
153 struct inet_sock *inet = inet_sk(sk); 122 struct inet_sock *inet = inet_sk(sk);
154 struct sk_buff *skb; 123 struct sk_buff *skb;
155 size_t copied; 124 size_t copied;
156 int err; 125 int err, copy_only, is_udplite = IS_UDPLITE(sk);
157 126
158 if (addr_len) 127 if (addr_len)
159 *addr_len=sizeof(struct sockaddr_in6); 128 *addr_len=sizeof(struct sockaddr_in6);
@@ -172,15 +141,21 @@ try_again:
172 msg->msg_flags |= MSG_TRUNC; 141 msg->msg_flags |= MSG_TRUNC;
173 } 142 }
174 143
175 if (skb->ip_summed==CHECKSUM_UNNECESSARY) { 144 /*
176 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 145 * Decide whether to checksum and/or copy data.
177 copied); 146 */
178 } else if (msg->msg_flags&MSG_TRUNC) { 147 copy_only = (skb->ip_summed==CHECKSUM_UNNECESSARY);
179 if (__skb_checksum_complete(skb)) 148
149 if (is_udplite || (!copy_only && msg->msg_flags&MSG_TRUNC)) {
150 if (__udp_lib_checksum_complete(skb))
180 goto csum_copy_err; 151 goto csum_copy_err;
181 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 152 copy_only = 1;
182 copied); 153 }
183 } else { 154
155 if (copy_only)
156 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
157 msg->msg_iov, copied );
158 else {
184 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 159 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
185 if (err == -EINVAL) 160 if (err == -EINVAL)
186 goto csum_copy_err; 161 goto csum_copy_err;
@@ -231,14 +206,15 @@ csum_copy_err:
231 skb_kill_datagram(sk, skb, flags); 206 skb_kill_datagram(sk, skb, flags);
232 207
233 if (flags & MSG_DONTWAIT) { 208 if (flags & MSG_DONTWAIT) {
234 UDP6_INC_STATS_USER(UDP_MIB_INERRORS); 209 UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
235 return -EAGAIN; 210 return -EAGAIN;
236 } 211 }
237 goto try_again; 212 goto try_again;
238} 213}
239 214
240static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 215void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
241 int type, int code, int offset, __u32 info) 216 int type, int code, int offset, __be32 info,
217 struct hlist_head udptable[] )
242{ 218{
243 struct ipv6_pinfo *np; 219 struct ipv6_pinfo *np;
244 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 220 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
@@ -248,8 +224,8 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
248 struct sock *sk; 224 struct sock *sk;
249 int err; 225 int err;
250 226
251 sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb)); 227 sk = __udp6_lib_lookup(daddr, uh->dest,
252 228 saddr, uh->source, inet6_iif(skb), udptable);
253 if (sk == NULL) 229 if (sk == NULL)
254 return; 230 return;
255 231
@@ -270,36 +246,60 @@ out:
270 sock_put(sk); 246 sock_put(sk);
271} 247}
272 248
273static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) 249static __inline__ void udpv6_err(struct sk_buff *skb,
250 struct inet6_skb_parm *opt, int type,
251 int code, int offset, __be32 info )
252{
253 return __udp6_lib_err(skb, opt, type, code, offset, info, udp_hash);
254}
255
256int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
274{ 257{
258 struct udp_sock *up = udp_sk(sk);
275 int rc; 259 int rc;
276 260
277 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { 261 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
278 kfree_skb(skb); 262 goto drop;
279 return -1;
280 }
281 263
282 if (skb_checksum_complete(skb)) { 264 /*
283 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 265 * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
284 kfree_skb(skb); 266 */
285 return 0; 267 if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) {
268
269 if (up->pcrlen == 0) { /* full coverage was set */
270 LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: partial coverage"
271 " %d while full coverage %d requested\n",
272 UDP_SKB_CB(skb)->cscov, skb->len);
273 goto drop;
274 }
275 if (UDP_SKB_CB(skb)->cscov < up->pcrlen) {
276 LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: coverage %d "
277 "too small, need min %d\n",
278 UDP_SKB_CB(skb)->cscov, up->pcrlen);
279 goto drop;
280 }
286 } 281 }
287 282
283 if (udp_lib_checksum_complete(skb))
284 goto drop;
285
288 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { 286 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
289 /* Note that an ENOMEM error is charged twice */ 287 /* Note that an ENOMEM error is charged twice */
290 if (rc == -ENOMEM) 288 if (rc == -ENOMEM)
291 UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS); 289 UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, up->pcflag);
292 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 290 goto drop;
293 kfree_skb(skb);
294 return 0;
295 } 291 }
296 UDP6_INC_STATS_BH(UDP_MIB_INDATAGRAMS); 292 UDP6_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
297 return 0; 293 return 0;
294drop:
295 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, up->pcflag);
296 kfree_skb(skb);
297 return -1;
298} 298}
299 299
300static struct sock *udp_v6_mcast_next(struct sock *sk, 300static struct sock *udp_v6_mcast_next(struct sock *sk,
301 u16 loc_port, struct in6_addr *loc_addr, 301 __be16 loc_port, struct in6_addr *loc_addr,
302 u16 rmt_port, struct in6_addr *rmt_addr, 302 __be16 rmt_port, struct in6_addr *rmt_addr,
303 int dif) 303 int dif)
304{ 304{
305 struct hlist_node *node; 305 struct hlist_node *node;
@@ -338,15 +338,15 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
338 * Note: called only from the BH handler context, 338 * Note: called only from the BH handler context,
339 * so we don't need to lock the hashes. 339 * so we don't need to lock the hashes.
340 */ 340 */
341static void udpv6_mcast_deliver(struct udphdr *uh, 341static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
342 struct in6_addr *saddr, struct in6_addr *daddr, 342 struct in6_addr *daddr, struct hlist_head udptable[])
343 struct sk_buff *skb)
344{ 343{
345 struct sock *sk, *sk2; 344 struct sock *sk, *sk2;
345 const struct udphdr *uh = skb->h.uh;
346 int dif; 346 int dif;
347 347
348 read_lock(&udp_hash_lock); 348 read_lock(&udp_hash_lock);
349 sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); 349 sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
350 dif = inet6_iif(skb); 350 dif = inet6_iif(skb);
351 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); 351 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
352 if (!sk) { 352 if (!sk) {
@@ -364,9 +364,35 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
364 udpv6_queue_rcv_skb(sk, skb); 364 udpv6_queue_rcv_skb(sk, skb);
365out: 365out:
366 read_unlock(&udp_hash_lock); 366 read_unlock(&udp_hash_lock);
367 return 0;
368}
369
370static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh)
371
372{
373 if (uh->check == 0) {
374 /* RFC 2460 section 8.1 says that we SHOULD log
375 this error. Well, it is reasonable.
376 */
377 LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
378 return 1;
379 }
380 if (skb->ip_summed == CHECKSUM_COMPLETE &&
381 !csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
382 skb->len, IPPROTO_UDP, skb->csum ))
383 skb->ip_summed = CHECKSUM_UNNECESSARY;
384
385 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
386 skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
387 &skb->nh.ipv6h->daddr,
388 skb->len, IPPROTO_UDP,
389 0));
390
391 return (UDP_SKB_CB(skb)->partial_cov = 0);
367} 392}
368 393
369static int udpv6_rcv(struct sk_buff **pskb) 394int __udp6_lib_rcv(struct sk_buff **pskb, struct hlist_head udptable[],
395 int is_udplite)
370{ 396{
371 struct sk_buff *skb = *pskb; 397 struct sk_buff *skb = *pskb;
372 struct sock *sk; 398 struct sock *sk;
@@ -383,44 +409,39 @@ static int udpv6_rcv(struct sk_buff **pskb)
383 uh = skb->h.uh; 409 uh = skb->h.uh;
384 410
385 ulen = ntohs(uh->len); 411 ulen = ntohs(uh->len);
412 if (ulen > skb->len)
413 goto short_packet;
386 414
387 /* Check for jumbo payload */ 415 if(! is_udplite ) { /* UDP validates ulen. */
388 if (ulen == 0)
389 ulen = skb->len;
390 416
391 if (ulen > skb->len || ulen < sizeof(*uh)) 417 /* Check for jumbo payload */
392 goto short_packet; 418 if (ulen == 0)
419 ulen = skb->len;
393 420
394 if (uh->check == 0) { 421 if (ulen < sizeof(*uh))
395 /* RFC 2460 section 8.1 says that we SHOULD log 422 goto short_packet;
396 this error. Well, it is reasonable.
397 */
398 LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
399 goto discard;
400 }
401 423
402 if (ulen < skb->len) { 424 if (ulen < skb->len) {
403 if (pskb_trim_rcsum(skb, ulen)) 425 if (pskb_trim_rcsum(skb, ulen))
404 goto discard; 426 goto short_packet;
405 saddr = &skb->nh.ipv6h->saddr; 427 saddr = &skb->nh.ipv6h->saddr;
406 daddr = &skb->nh.ipv6h->daddr; 428 daddr = &skb->nh.ipv6h->daddr;
407 uh = skb->h.uh; 429 uh = skb->h.uh;
408 } 430 }
409 431
410 if (skb->ip_summed == CHECKSUM_COMPLETE && 432 if (udp6_csum_init(skb, uh))
411 !csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) 433 goto discard;
412 skb->ip_summed = CHECKSUM_UNNECESSARY;
413 434
414 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 435 } else { /* UDP-Lite validates cscov. */
415 skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0); 436 if (udplite6_csum_init(skb, uh))
437 goto discard;
438 }
416 439
417 /* 440 /*
418 * Multicast receive code 441 * Multicast receive code
419 */ 442 */
420 if (ipv6_addr_is_multicast(daddr)) { 443 if (ipv6_addr_is_multicast(daddr))
421 udpv6_mcast_deliver(uh, saddr, daddr, skb); 444 return __udp6_lib_mcast_deliver(skb, saddr, daddr, udptable);
422 return 0;
423 }
424 445
425 /* Unicast */ 446 /* Unicast */
426 447
@@ -428,15 +449,16 @@ static int udpv6_rcv(struct sk_buff **pskb)
428 * check socket cache ... must talk to Alan about his plans 449 * check socket cache ... must talk to Alan about his plans
429 * for sock caches... i'll skip this for now. 450 * for sock caches... i'll skip this for now.
430 */ 451 */
431 sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb)); 452 sk = __udp6_lib_lookup(saddr, uh->source,
453 daddr, uh->dest, inet6_iif(skb), udptable);
432 454
433 if (sk == NULL) { 455 if (sk == NULL) {
434 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 456 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
435 goto discard; 457 goto discard;
436 458
437 if (skb_checksum_complete(skb)) 459 if (udp_lib_checksum_complete(skb))
438 goto discard; 460 goto discard;
439 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS); 461 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS, is_udplite);
440 462
441 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); 463 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
442 464
@@ -451,14 +473,20 @@ static int udpv6_rcv(struct sk_buff **pskb)
451 return(0); 473 return(0);
452 474
453short_packet: 475short_packet:
454 if (net_ratelimit()) 476 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n",
455 printk(KERN_DEBUG "UDP: short packet: %d/%u\n", ulen, skb->len); 477 is_udplite? "-Lite" : "", ulen, skb->len);
456 478
457discard: 479discard:
458 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 480 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
459 kfree_skb(skb); 481 kfree_skb(skb);
460 return(0); 482 return(0);
461} 483}
484
485static __inline__ int udpv6_rcv(struct sk_buff **pskb)
486{
487 return __udp6_lib_rcv(pskb, udp_hash, 0);
488}
489
462/* 490/*
463 * Throw away all pending data and cancel the corking. Socket is locked. 491 * Throw away all pending data and cancel the corking. Socket is locked.
464 */ 492 */
@@ -477,13 +505,15 @@ static void udp_v6_flush_pending_frames(struct sock *sk)
477 * Sending 505 * Sending
478 */ 506 */
479 507
480static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up) 508static int udp_v6_push_pending_frames(struct sock *sk)
481{ 509{
482 struct sk_buff *skb; 510 struct sk_buff *skb;
483 struct udphdr *uh; 511 struct udphdr *uh;
512 struct udp_sock *up = udp_sk(sk);
484 struct inet_sock *inet = inet_sk(sk); 513 struct inet_sock *inet = inet_sk(sk);
485 struct flowi *fl = &inet->cork.fl; 514 struct flowi *fl = &inet->cork.fl;
486 int err = 0; 515 int err = 0;
516 __wsum csum = 0;
487 517
488 /* Grab the skbuff where UDP header space exists. */ 518 /* Grab the skbuff where UDP header space exists. */
489 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) 519 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
@@ -498,35 +528,17 @@ static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up)
498 uh->len = htons(up->len); 528 uh->len = htons(up->len);
499 uh->check = 0; 529 uh->check = 0;
500 530
501 if (sk->sk_no_check == UDP_CSUM_NOXMIT) { 531 if (up->pcflag)
502 skb->ip_summed = CHECKSUM_NONE; 532 csum = udplite_csum_outgoing(sk, skb);
503 goto send; 533 else
504 } 534 csum = udp_csum_outgoing(sk, skb);
505
506 if (skb_queue_len(&sk->sk_write_queue) == 1) {
507 skb->csum = csum_partial((char *)uh,
508 sizeof(struct udphdr), skb->csum);
509 uh->check = csum_ipv6_magic(&fl->fl6_src,
510 &fl->fl6_dst,
511 up->len, fl->proto, skb->csum);
512 } else {
513 u32 tmp_csum = 0;
514
515 skb_queue_walk(&sk->sk_write_queue, skb) {
516 tmp_csum = csum_add(tmp_csum, skb->csum);
517 }
518 tmp_csum = csum_partial((char *)uh,
519 sizeof(struct udphdr), tmp_csum);
520 tmp_csum = csum_ipv6_magic(&fl->fl6_src,
521 &fl->fl6_dst,
522 up->len, fl->proto, tmp_csum);
523 uh->check = tmp_csum;
524 535
525 } 536 /* add protocol-dependent pseudo-header */
537 uh->check = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst,
538 up->len, fl->proto, csum );
526 if (uh->check == 0) 539 if (uh->check == 0)
527 uh->check = -1; 540 uh->check = CSUM_MANGLED_0;
528 541
529send:
530 err = ip6_push_pending_frames(sk); 542 err = ip6_push_pending_frames(sk);
531out: 543out:
532 up->len = 0; 544 up->len = 0;
@@ -534,7 +546,7 @@ out:
534 return err; 546 return err;
535} 547}
536 548
537static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, 549int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
538 struct msghdr *msg, size_t len) 550 struct msghdr *msg, size_t len)
539{ 551{
540 struct ipv6_txoptions opt_space; 552 struct ipv6_txoptions opt_space;
@@ -554,6 +566,8 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
554 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 566 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
555 int err; 567 int err;
556 int connected = 0; 568 int connected = 0;
569 int is_udplite = up->pcflag;
570 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
557 571
558 /* destination address check */ 572 /* destination address check */
559 if (sin6) { 573 if (sin6) {
@@ -694,7 +708,7 @@ do_udp_sendmsg:
694 opt = fl6_merge_options(&opt_space, flowlabel, opt); 708 opt = fl6_merge_options(&opt_space, flowlabel, opt);
695 opt = ipv6_fixup_options(&opt_space, opt); 709 opt = ipv6_fixup_options(&opt_space, opt);
696 710
697 fl.proto = IPPROTO_UDP; 711 fl.proto = sk->sk_protocol;
698 ipv6_addr_copy(&fl.fl6_dst, daddr); 712 ipv6_addr_copy(&fl.fl6_dst, daddr);
699 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 713 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
700 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 714 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
@@ -761,14 +775,15 @@ back_from_confirm:
761 775
762do_append_data: 776do_append_data:
763 up->len += ulen; 777 up->len += ulen;
764 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, 778 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
779 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
765 sizeof(struct udphdr), hlimit, tclass, opt, &fl, 780 sizeof(struct udphdr), hlimit, tclass, opt, &fl,
766 (struct rt6_info*)dst, 781 (struct rt6_info*)dst,
767 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 782 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
768 if (err) 783 if (err)
769 udp_v6_flush_pending_frames(sk); 784 udp_v6_flush_pending_frames(sk);
770 else if (!corkreq) 785 else if (!corkreq)
771 err = udp_v6_push_pending_frames(sk, up); 786 err = udp_v6_push_pending_frames(sk);
772 else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) 787 else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
773 up->pending = 0; 788 up->pending = 0;
774 789
@@ -793,7 +808,7 @@ do_append_data:
793out: 808out:
794 fl6_sock_release(flowlabel); 809 fl6_sock_release(flowlabel);
795 if (!err) { 810 if (!err) {
796 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); 811 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite);
797 return len; 812 return len;
798 } 813 }
799 /* 814 /*
@@ -804,7 +819,7 @@ out:
804 * seems like overkill. 819 * seems like overkill.
805 */ 820 */
806 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { 821 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
807 UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS); 822 UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite);
808 } 823 }
809 return err; 824 return err;
810 825
@@ -816,7 +831,7 @@ do_confirm:
816 goto out; 831 goto out;
817} 832}
818 833
819static int udpv6_destroy_sock(struct sock *sk) 834int udpv6_destroy_sock(struct sock *sk)
820{ 835{
821 lock_sock(sk); 836 lock_sock(sk);
822 udp_v6_flush_pending_frames(sk); 837 udp_v6_flush_pending_frames(sk);
@@ -830,119 +845,41 @@ static int udpv6_destroy_sock(struct sock *sk)
830/* 845/*
831 * Socket option code for UDP 846 * Socket option code for UDP
832 */ 847 */
833static int do_udpv6_setsockopt(struct sock *sk, int level, int optname, 848int udpv6_setsockopt(struct sock *sk, int level, int optname,
834 char __user *optval, int optlen) 849 char __user *optval, int optlen)
835{
836 struct udp_sock *up = udp_sk(sk);
837 int val;
838 int err = 0;
839
840 if(optlen<sizeof(int))
841 return -EINVAL;
842
843 if (get_user(val, (int __user *)optval))
844 return -EFAULT;
845
846 switch(optname) {
847 case UDP_CORK:
848 if (val != 0) {
849 up->corkflag = 1;
850 } else {
851 up->corkflag = 0;
852 lock_sock(sk);
853 udp_v6_push_pending_frames(sk, up);
854 release_sock(sk);
855 }
856 break;
857
858 case UDP_ENCAP:
859 switch (val) {
860 case 0:
861 up->encap_type = val;
862 break;
863 default:
864 err = -ENOPROTOOPT;
865 break;
866 }
867 break;
868
869 default:
870 err = -ENOPROTOOPT;
871 break;
872 };
873
874 return err;
875}
876
877static int udpv6_setsockopt(struct sock *sk, int level, int optname,
878 char __user *optval, int optlen)
879{ 850{
880 if (level != SOL_UDP) 851 if (level == SOL_UDP || level == SOL_UDPLITE)
881 return ipv6_setsockopt(sk, level, optname, optval, optlen); 852 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
882 return do_udpv6_setsockopt(sk, level, optname, optval, optlen); 853 udp_v6_push_pending_frames);
854 return ipv6_setsockopt(sk, level, optname, optval, optlen);
883} 855}
884 856
885#ifdef CONFIG_COMPAT 857#ifdef CONFIG_COMPAT
886static int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, 858int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
887 char __user *optval, int optlen) 859 char __user *optval, int optlen)
888{ 860{
889 if (level != SOL_UDP) 861 if (level == SOL_UDP || level == SOL_UDPLITE)
890 return compat_ipv6_setsockopt(sk, level, optname, 862 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
891 optval, optlen); 863 udp_v6_push_pending_frames);
892 return do_udpv6_setsockopt(sk, level, optname, optval, optlen); 864 return compat_ipv6_setsockopt(sk, level, optname, optval, optlen);
893} 865}
894#endif 866#endif
895 867
896static int do_udpv6_getsockopt(struct sock *sk, int level, int optname, 868int udpv6_getsockopt(struct sock *sk, int level, int optname,
897 char __user *optval, int __user *optlen) 869 char __user *optval, int __user *optlen)
898{
899 struct udp_sock *up = udp_sk(sk);
900 int val, len;
901
902 if(get_user(len,optlen))
903 return -EFAULT;
904
905 len = min_t(unsigned int, len, sizeof(int));
906
907 if(len < 0)
908 return -EINVAL;
909
910 switch(optname) {
911 case UDP_CORK:
912 val = up->corkflag;
913 break;
914
915 case UDP_ENCAP:
916 val = up->encap_type;
917 break;
918
919 default:
920 return -ENOPROTOOPT;
921 };
922
923 if(put_user(len, optlen))
924 return -EFAULT;
925 if(copy_to_user(optval, &val,len))
926 return -EFAULT;
927 return 0;
928}
929
930static int udpv6_getsockopt(struct sock *sk, int level, int optname,
931 char __user *optval, int __user *optlen)
932{ 870{
933 if (level != SOL_UDP) 871 if (level == SOL_UDP || level == SOL_UDPLITE)
934 return ipv6_getsockopt(sk, level, optname, optval, optlen); 872 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
935 return do_udpv6_getsockopt(sk, level, optname, optval, optlen); 873 return ipv6_getsockopt(sk, level, optname, optval, optlen);
936} 874}
937 875
938#ifdef CONFIG_COMPAT 876#ifdef CONFIG_COMPAT
939static int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, 877int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
940 char __user *optval, int __user *optlen) 878 char __user *optval, int __user *optlen)
941{ 879{
942 if (level != SOL_UDP) 880 if (level == SOL_UDP || level == SOL_UDPLITE)
943 return compat_ipv6_getsockopt(sk, level, optname, 881 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
944 optval, optlen); 882 return compat_ipv6_getsockopt(sk, level, optname, optval, optlen);
945 return do_udpv6_getsockopt(sk, level, optname, optval, optlen);
946} 883}
947#endif 884#endif
948 885
@@ -983,7 +920,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
983 atomic_read(&sp->sk_refcnt), sp); 920 atomic_read(&sp->sk_refcnt), sp);
984} 921}
985 922
986static int udp6_seq_show(struct seq_file *seq, void *v) 923int udp6_seq_show(struct seq_file *seq, void *v)
987{ 924{
988 if (v == SEQ_START_TOKEN) 925 if (v == SEQ_START_TOKEN)
989 seq_printf(seq, 926 seq_printf(seq,
@@ -1002,6 +939,7 @@ static struct udp_seq_afinfo udp6_seq_afinfo = {
1002 .owner = THIS_MODULE, 939 .owner = THIS_MODULE,
1003 .name = "udp6", 940 .name = "udp6",
1004 .family = AF_INET6, 941 .family = AF_INET6,
942 .hashtable = udp_hash,
1005 .seq_show = udp6_seq_show, 943 .seq_show = udp6_seq_show,
1006 .seq_fops = &udp6_seq_fops, 944 .seq_fops = &udp6_seq_fops,
1007}; 945};
@@ -1021,7 +959,7 @@ void udp6_proc_exit(void) {
1021struct proto udpv6_prot = { 959struct proto udpv6_prot = {
1022 .name = "UDPv6", 960 .name = "UDPv6",
1023 .owner = THIS_MODULE, 961 .owner = THIS_MODULE,
1024 .close = udpv6_close, 962 .close = udp_lib_close,
1025 .connect = ip6_datagram_connect, 963 .connect = ip6_datagram_connect,
1026 .disconnect = udp_disconnect, 964 .disconnect = udp_disconnect,
1027 .ioctl = udp_ioctl, 965 .ioctl = udp_ioctl,
@@ -1031,8 +969,8 @@ struct proto udpv6_prot = {
1031 .sendmsg = udpv6_sendmsg, 969 .sendmsg = udpv6_sendmsg,
1032 .recvmsg = udpv6_recvmsg, 970 .recvmsg = udpv6_recvmsg,
1033 .backlog_rcv = udpv6_queue_rcv_skb, 971 .backlog_rcv = udpv6_queue_rcv_skb,
1034 .hash = udp_v6_hash, 972 .hash = udp_lib_hash,
1035 .unhash = udp_v6_unhash, 973 .unhash = udp_lib_unhash,
1036 .get_port = udp_v6_get_port, 974 .get_port = udp_v6_get_port,
1037 .obj_size = sizeof(struct udp6_sock), 975 .obj_size = sizeof(struct udp6_sock),
1038#ifdef CONFIG_COMPAT 976#ifdef CONFIG_COMPAT
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
new file mode 100644
index 000000000000..ec9878899128
--- /dev/null
+++ b/net/ipv6/udp_impl.h
@@ -0,0 +1,34 @@
1#ifndef _UDP6_IMPL_H
2#define _UDP6_IMPL_H
3#include <net/udp.h>
4#include <net/udplite.h>
5#include <net/protocol.h>
6#include <net/addrconf.h>
7#include <net/inet_common.h>
8
9extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
10extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
11 int , int , int , __be32 , struct hlist_head []);
12
13extern int udpv6_getsockopt(struct sock *sk, int level, int optname,
14 char __user *optval, int __user *optlen);
15extern int udpv6_setsockopt(struct sock *sk, int level, int optname,
16 char __user *optval, int optlen);
17#ifdef CONFIG_COMPAT
18extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
19 char __user *optval, int optlen);
20extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
21 char __user *optval, int __user *optlen);
22#endif
23extern int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
24 struct msghdr *msg, size_t len);
25extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
26 struct msghdr *msg, size_t len,
27 int noblock, int flags, int *addr_len);
28extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
29extern int udpv6_destroy_sock(struct sock *sk);
30
31#ifdef CONFIG_PROC_FS
32extern int udp6_seq_show(struct seq_file *seq, void *v);
33#endif
34#endif /* _UDP6_IMPL_H */
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
new file mode 100644
index 000000000000..629f97162fbc
--- /dev/null
+++ b/net/ipv6/udplite.c
@@ -0,0 +1,105 @@
1/*
2 * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6.
3 * See also net/ipv4/udplite.c
4 *
5 * Version: $Id: udplite.c,v 1.9 2006/10/19 08:28:10 gerrit Exp $
6 *
7 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk>
8 *
9 * Changes:
10 * Fixes:
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16#include "udp_impl.h"
17
18DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6) __read_mostly;
19
20static int udplitev6_rcv(struct sk_buff **pskb)
21{
22 return __udp6_lib_rcv(pskb, udplite_hash, 1);
23}
24
25static void udplitev6_err(struct sk_buff *skb,
26 struct inet6_skb_parm *opt,
27 int type, int code, int offset, __be32 info)
28{
29 return __udp6_lib_err(skb, opt, type, code, offset, info, udplite_hash);
30}
31
32static struct inet6_protocol udplitev6_protocol = {
33 .handler = udplitev6_rcv,
34 .err_handler = udplitev6_err,
35 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
36};
37
38static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
39{
40 return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
41}
42
43struct proto udplitev6_prot = {
44 .name = "UDPLITEv6",
45 .owner = THIS_MODULE,
46 .close = udp_lib_close,
47 .connect = ip6_datagram_connect,
48 .disconnect = udp_disconnect,
49 .ioctl = udp_ioctl,
50 .init = udplite_sk_init,
51 .destroy = udpv6_destroy_sock,
52 .setsockopt = udpv6_setsockopt,
53 .getsockopt = udpv6_getsockopt,
54 .sendmsg = udpv6_sendmsg,
55 .recvmsg = udpv6_recvmsg,
56 .backlog_rcv = udpv6_queue_rcv_skb,
57 .hash = udp_lib_hash,
58 .unhash = udp_lib_unhash,
59 .get_port = udplite_v6_get_port,
60 .obj_size = sizeof(struct udp6_sock),
61#ifdef CONFIG_COMPAT
62 .compat_setsockopt = compat_udpv6_setsockopt,
63 .compat_getsockopt = compat_udpv6_getsockopt,
64#endif
65};
66
67static struct inet_protosw udplite6_protosw = {
68 .type = SOCK_DGRAM,
69 .protocol = IPPROTO_UDPLITE,
70 .prot = &udplitev6_prot,
71 .ops = &inet6_dgram_ops,
72 .capability = -1,
73 .no_check = 0,
74 .flags = INET_PROTOSW_PERMANENT,
75};
76
77void __init udplitev6_init(void)
78{
79 if (inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE) < 0)
80 printk(KERN_ERR "%s: Could not register.\n", __FUNCTION__);
81
82 inet6_register_protosw(&udplite6_protosw);
83}
84
85#ifdef CONFIG_PROC_FS
86static struct file_operations udplite6_seq_fops;
87static struct udp_seq_afinfo udplite6_seq_afinfo = {
88 .owner = THIS_MODULE,
89 .name = "udplite6",
90 .family = AF_INET6,
91 .hashtable = udplite_hash,
92 .seq_show = udp6_seq_show,
93 .seq_fops = &udplite6_seq_fops,
94};
95
96int __init udplite6_proc_init(void)
97{
98 return udp_proc_register(&udplite6_seq_afinfo);
99}
100
101void udplite6_proc_exit(void)
102{
103 udp_proc_unregister(&udplite6_seq_afinfo);
104}
105#endif
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d400f8fae129..8dffd4daae9c 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -274,11 +274,12 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
274 break; 274 break;
275 275
276 case IPPROTO_UDP: 276 case IPPROTO_UDP:
277 case IPPROTO_UDPLITE:
277 case IPPROTO_TCP: 278 case IPPROTO_TCP:
278 case IPPROTO_SCTP: 279 case IPPROTO_SCTP:
279 case IPPROTO_DCCP: 280 case IPPROTO_DCCP:
280 if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) { 281 if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
281 u16 *ports = (u16 *)exthdr; 282 __be16 *ports = (__be16 *)exthdr;
282 283
283 fl->fl_ip_sport = ports[0]; 284 fl->fl_ip_sport = ports[0];
284 fl->fl_ip_dport = ports[1]; 285 fl->fl_ip_dport = ports[1];
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 7931e4f898d4..01a5c52a2be3 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -62,7 +62,7 @@ static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
62{ 62{
63 unsigned h; 63 unsigned h;
64 64
65 h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]; 65 h = (__force u32)(addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]);
66 h ^= h >> 16; 66 h ^= h >> 16;
67 h ^= h >> 8; 67 h ^= h >> 8;
68 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1; 68 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;
@@ -126,7 +126,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
126 return NULL; 126 return NULL;
127} 127}
128 128
129u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 129__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
130{ 130{
131 struct xfrm6_tunnel_spi *x6spi; 131 struct xfrm6_tunnel_spi *x6spi;
132 u32 spi; 132 u32 spi;
@@ -196,7 +196,7 @@ out:
196 return spi; 196 return spi;
197} 197}
198 198
199u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 199__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
200{ 200{
201 struct xfrm6_tunnel_spi *x6spi; 201 struct xfrm6_tunnel_spi *x6spi;
202 u32 spi; 202 u32 spi;
@@ -265,7 +265,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
265} 265}
266 266
267static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 267static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
268 int type, int code, int offset, __u32 info) 268 int type, int code, int offset, __be32 info)
269{ 269{
270 /* xfrm6_tunnel native err handling */ 270 /* xfrm6_tunnel native err handling */
271 switch (type) { 271 switch (type) {