aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 11:01:37 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 11:01:37 -0500
commitf049274b012fd3b50113f194bfbbcbc3143d0da3 (patch)
tree15ef947c1959da3196d8dbc524b435972f6d37f7 /net/ipv6
parentb37df85960a34dd96d0a4695c650f7972ef56c30 (diff)
parent1539b98b561754252dd520b98fa03a688a4f81b5 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (79 commits) [IPX]: Fix NULL pointer dereference on ipx unload [ATM]: atmarp.h needs to always include linux/types.h [NET]: Fix net/socket.c warnings. [NET]: cleanup sock_from_file() [NET]: change layout of ehash table [S390]: Add AF_IUCV socket support [S390]: Adapt special message interface to new IUCV API [S390]: Adapt netiucv driver to new IUCV API [S390]: Adapt vmlogrdr driver to new IUCV API [S390]: Adapt monreader driver to new IUCV API [S390]: Rewrite of the IUCV base code, part 2 [S390]: Rewrite of the IUCV base code, part 1 [X.25]: Adds /proc/net/x25/forward to view active forwarded calls. [X.25]: Adds /proc/sys/net/x25/x25_forward to control forwarding. [X.25]: Add call forwarding [XFRM]: xfrm_migrate() needs exporting to modules. [PFKEYV2]: CONFIG_NET_KEY_MIGRATE option [PFKEYV2]: Extension for dynamic update of endpoint address(es) [XFRM]: CONFIG_XFRM_MIGRATE option [XFRM]: User interface for handling XFRM_MSG_MIGRATE ...
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c70
-rw-r--r--net/ipv6/datagram.c2
-rw-r--r--net/ipv6/inet6_hashtables.c4
-rw-r--r--net/ipv6/ip6_tunnel.c3
-rw-r--r--net/ipv6/mcast.c2
-rw-r--r--net/ipv6/mip6.c26
-rw-r--r--net/ipv6/netfilter/Kconfig8
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6_tables.c12
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c17
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c15
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c10
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c8
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c8
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c8
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c1
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c11
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c8
-rw-r--r--net/ipv6/netfilter/ip6t_mh.c108
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c8
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c8
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c21
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c21
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c19
-rw-r--r--net/ipv6/raw.c15
-rw-r--r--net/ipv6/route.c33
-rw-r--r--net/ipv6/sit.c3
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/ipv6/udp.c2
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c42
-rw-r--r--net/ipv6/xfrm6_policy.c46
-rw-r--r--net/ipv6/xfrm6_state.c1
32 files changed, 342 insertions, 201 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e3854696988d..fe5e1d833871 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3117,7 +3117,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3117 3117
3118 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3118 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3119 if (nlh == NULL) 3119 if (nlh == NULL)
3120 return -ENOBUFS; 3120 return -EMSGSIZE;
3121 3121
3122 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), 3122 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
3123 ifa->idev->dev->ifindex); 3123 ifa->idev->dev->ifindex);
@@ -3137,8 +3137,10 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3137 } 3137 }
3138 3138
3139 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 || 3139 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 ||
3140 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) 3140 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) {
3141 return nlmsg_cancel(skb, nlh); 3141 nlmsg_cancel(skb, nlh);
3142 return -EMSGSIZE;
3143 }
3142 3144
3143 return nlmsg_end(skb, nlh); 3145 return nlmsg_end(skb, nlh);
3144} 3146}
@@ -3155,13 +3157,15 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3155 3157
3156 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3158 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3157 if (nlh == NULL) 3159 if (nlh == NULL)
3158 return -ENOBUFS; 3160 return -EMSGSIZE;
3159 3161
3160 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); 3162 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3161 if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 || 3163 if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 ||
3162 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp, 3164 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
3163 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) 3165 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3164 return nlmsg_cancel(skb, nlh); 3166 nlmsg_cancel(skb, nlh);
3167 return -EMSGSIZE;
3168 }
3165 3169
3166 return nlmsg_end(skb, nlh); 3170 return nlmsg_end(skb, nlh);
3167} 3171}
@@ -3178,13 +3182,15 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3178 3182
3179 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3183 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags);
3180 if (nlh == NULL) 3184 if (nlh == NULL)
3181 return -ENOBUFS; 3185 return -EMSGSIZE;
3182 3186
3183 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); 3187 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
3184 if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 || 3188 if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 ||
3185 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp, 3189 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
3186 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) 3190 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3187 return nlmsg_cancel(skb, nlh); 3191 nlmsg_cancel(skb, nlh);
3192 return -EMSGSIZE;
3193 }
3188 3194
3189 return nlmsg_end(skb, nlh); 3195 return nlmsg_end(skb, nlh);
3190} 3196}
@@ -3334,9 +3340,12 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3334 3340
3335 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3341 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3336 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3342 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3337 /* failure implies BUG in inet6_ifaddr_msgsize() */ 3343 if (err < 0) {
3338 BUG_ON(err < 0); 3344 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
3339 3345 WARN_ON(err == -EMSGSIZE);
3346 kfree_skb(skb);
3347 goto errout_ifa;
3348 }
3340 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); 3349 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
3341errout_ifa: 3350errout_ifa:
3342 in6_ifa_put(ifa); 3351 in6_ifa_put(ifa);
@@ -3354,9 +3363,12 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3354 goto errout; 3363 goto errout;
3355 3364
3356 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); 3365 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3357 /* failure implies BUG in inet6_ifaddr_msgsize() */ 3366 if (err < 0) {
3358 BUG_ON(err < 0); 3367 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
3359 3368 WARN_ON(err == -EMSGSIZE);
3369 kfree_skb(skb);
3370 goto errout;
3371 }
3360 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3372 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3361errout: 3373errout:
3362 if (err < 0) 3374 if (err < 0)
@@ -3426,7 +3438,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3426 3438
3427 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 3439 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
3428 if (nlh == NULL) 3440 if (nlh == NULL)
3429 return -ENOBUFS; 3441 return -EMSGSIZE;
3430 3442
3431 hdr = nlmsg_data(nlh); 3443 hdr = nlmsg_data(nlh);
3432 hdr->ifi_family = AF_INET6; 3444 hdr->ifi_family = AF_INET6;
@@ -3469,7 +3481,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3469 return nlmsg_end(skb, nlh); 3481 return nlmsg_end(skb, nlh);
3470 3482
3471nla_put_failure: 3483nla_put_failure:
3472 return nlmsg_cancel(skb, nlh); 3484 nlmsg_cancel(skb, nlh);
3485 return -EMSGSIZE;
3473} 3486}
3474 3487
3475static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3488static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
@@ -3507,9 +3520,12 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3507 goto errout; 3520 goto errout;
3508 3521
3509 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); 3522 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3510 /* failure implies BUG in inet6_if_nlmsg_size() */ 3523 if (err < 0) {
3511 BUG_ON(err < 0); 3524 /* -EMSGSIZE implies BUG in inet6_if_nlmsg_size() */
3512 3525 WARN_ON(err == -EMSGSIZE);
3526 kfree_skb(skb);
3527 goto errout;
3528 }
3513 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3529 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3514errout: 3530errout:
3515 if (err < 0) 3531 if (err < 0)
@@ -3533,7 +3549,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3533 3549
3534 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags); 3550 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
3535 if (nlh == NULL) 3551 if (nlh == NULL)
3536 return -ENOBUFS; 3552 return -EMSGSIZE;
3537 3553
3538 pmsg = nlmsg_data(nlh); 3554 pmsg = nlmsg_data(nlh);
3539 pmsg->prefix_family = AF_INET6; 3555 pmsg->prefix_family = AF_INET6;
@@ -3558,7 +3574,8 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3558 return nlmsg_end(skb, nlh); 3574 return nlmsg_end(skb, nlh);
3559 3575
3560nla_put_failure: 3576nla_put_failure:
3561 return nlmsg_cancel(skb, nlh); 3577 nlmsg_cancel(skb, nlh);
3578 return -EMSGSIZE;
3562} 3579}
3563 3580
3564static void inet6_prefix_notify(int event, struct inet6_dev *idev, 3581static void inet6_prefix_notify(int event, struct inet6_dev *idev,
@@ -3572,9 +3589,12 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3572 goto errout; 3589 goto errout;
3573 3590
3574 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); 3591 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3575 /* failure implies BUG in inet6_prefix_nlmsg_size() */ 3592 if (err < 0) {
3576 BUG_ON(err < 0); 3593 /* -EMSGSIZE implies BUG in inet6_prefix_nlmsg_size() */
3577 3594 WARN_ON(err == -EMSGSIZE);
3595 kfree_skb(skb);
3596 goto errout;
3597 }
3578 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); 3598 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3579errout: 3599errout:
3580 if (err < 0) 3600 if (err < 0)
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 5c94fea90e97..ecde30140f4a 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -178,7 +178,7 @@ ipv4_connected:
178 if (final_p) 178 if (final_p)
179 ipv6_addr_copy(&fl.fl6_dst, final_p); 179 ipv6_addr_copy(&fl.fl6_dst, final_p);
180 180
181 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 181 if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
182 goto out; 182 goto out;
183 183
184 /* source address lookup done in ip6_dst_lookup */ 184 /* source address lookup done in ip6_dst_lookup */
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index b7e5bae0e347..e61116949bee 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -79,7 +79,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
79 goto hit; /* You sunk my battleship! */ 79 goto hit; /* You sunk my battleship! */
80 } 80 }
81 /* Must check for a TIME_WAIT'er before going to listener hash. */ 81 /* Must check for a TIME_WAIT'er before going to listener hash. */
82 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { 82 sk_for_each(sk, node, &head->twchain) {
83 const struct inet_timewait_sock *tw = inet_twsk(sk); 83 const struct inet_timewait_sock *tw = inet_twsk(sk);
84 84
85 if(*((__portpair *)&(tw->tw_dport)) == ports && 85 if(*((__portpair *)&(tw->tw_dport)) == ports &&
@@ -183,7 +183,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
183 write_lock(&head->lock); 183 write_lock(&head->lock);
184 184
185 /* Check TIME-WAIT sockets first. */ 185 /* Check TIME-WAIT sockets first. */
186 sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { 186 sk_for_each(sk2, node, &head->twchain) {
187 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2); 187 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
188 188
189 tw = inet_twsk(sk2); 189 tw = inet_twsk(sk2);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 8d918348f5bb..2b9e3bb7da65 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -999,7 +999,8 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
999 break; 999 break;
1000 dev = t->dev; 1000 dev = t->dev;
1001 } 1001 }
1002 err = unregister_netdevice(dev); 1002 err = 0;
1003 unregister_netdevice(dev);
1003 break; 1004 break;
1004 default: 1005 default:
1005 err = -EINVAL; 1006 err = -EINVAL;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 882cde4b4047..e3ec21695832 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1582,6 +1582,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
1582 skb = add_grhead(skb, pmc, type, &pgr); 1582 skb = add_grhead(skb, pmc, type, &pgr);
1583 first = 0; 1583 first = 0;
1584 } 1584 }
1585 if (!skb)
1586 return NULL;
1585 psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc)); 1587 psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc));
1586 *psrc = psf->sf_addr; 1588 *psrc = psf->sf_addr;
1587 scount++; stotal++; 1589 scount++; stotal++;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index be7dd7db65d7..681bb077eacc 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -89,7 +89,6 @@ static int mip6_mh_len(int type)
89int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) 89int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
90{ 90{
91 struct ip6_mh *mh; 91 struct ip6_mh *mh;
92 int mhlen;
93 92
94 if (!pskb_may_pull(skb, (skb->h.raw - skb->data) + 8) || 93 if (!pskb_may_pull(skb, (skb->h.raw - skb->data) + 8) ||
95 !pskb_may_pull(skb, (skb->h.raw - skb->data) + ((skb->h.raw[1] + 1) << 3))) 94 !pskb_may_pull(skb, (skb->h.raw - skb->data) + ((skb->h.raw[1] + 1) << 3)))
@@ -103,31 +102,6 @@ int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
103 mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw); 102 mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw);
104 return -1; 103 return -1;
105 } 104 }
106 mhlen = (mh->ip6mh_hdrlen + 1) << 3;
107
108 if (skb->ip_summed == CHECKSUM_COMPLETE) {
109 skb->ip_summed = CHECKSUM_UNNECESSARY;
110 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
111 &skb->nh.ipv6h->daddr,
112 mhlen, IPPROTO_MH,
113 skb->csum)) {
114 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH hw checksum failed\n");
115 skb->ip_summed = CHECKSUM_NONE;
116 }
117 }
118 if (skb->ip_summed == CHECKSUM_NONE) {
119 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
120 &skb->nh.ipv6h->daddr,
121 mhlen, IPPROTO_MH,
122 skb_checksum(skb, 0, mhlen, 0))) {
123 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH checksum failed "
124 "[" NIP6_FMT " > " NIP6_FMT "]\n",
125 NIP6(skb->nh.ipv6h->saddr),
126 NIP6(skb->nh.ipv6h->daddr));
127 return -1;
128 }
129 skb->ip_summed = CHECKSUM_UNNECESSARY;
130 }
131 105
132 if (mh->ip6mh_proto != IPPROTO_NONE) { 106 if (mh->ip6mh_proto != IPPROTO_NONE) {
133 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n", 107 LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index adcd6131df2a..cd549aea84f0 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -114,6 +114,14 @@ config IP6_NF_MATCH_AH
114 114
115 To compile it as a module, choose M here. If unsure, say N. 115 To compile it as a module, choose M here. If unsure, say N.
116 116
117config IP6_NF_MATCH_MH
118 tristate "MH match support"
119 depends on IP6_NF_IPTABLES
120 help
121 This module allows one to match MH packets.
122
123 To compile it as a module, choose M here. If unsure, say N.
124
117config IP6_NF_MATCH_EUI64 125config IP6_NF_MATCH_EUI64
118 tristate "EUI64 address check" 126 tristate "EUI64 address check"
119 depends on IP6_NF_IPTABLES 127 depends on IP6_NF_IPTABLES
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index ac1dfebde175..4513eab77397 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
19obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o 19obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
20obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o 20obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
21obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o 21obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
22obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
22 23
23# objects for l3 independent conntrack 24# objects for l3 independent conntrack
24nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o 25nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 99502c5da4c4..7083e1cfb2f5 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -530,7 +530,7 @@ check_match(struct ip6t_entry_match *m,
530 unsigned int hookmask, 530 unsigned int hookmask,
531 unsigned int *i) 531 unsigned int *i)
532{ 532{
533 struct ip6t_match *match; 533 struct xt_match *match;
534 int ret; 534 int ret;
535 535
536 match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, 536 match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
@@ -564,14 +564,14 @@ err:
564 return ret; 564 return ret;
565} 565}
566 566
567static struct ip6t_target ip6t_standard_target; 567static struct xt_target ip6t_standard_target;
568 568
569static inline int 569static inline int
570check_entry(struct ip6t_entry *e, const char *name, unsigned int size, 570check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
571 unsigned int *i) 571 unsigned int *i)
572{ 572{
573 struct ip6t_entry_target *t; 573 struct ip6t_entry_target *t;
574 struct ip6t_target *target; 574 struct xt_target *target;
575 int ret; 575 int ret;
576 unsigned int j; 576 unsigned int j;
577 577
@@ -1348,13 +1348,13 @@ icmp6_checkentry(const char *tablename,
1348} 1348}
1349 1349
1350/* The built-in targets: standard (NULL) and error. */ 1350/* The built-in targets: standard (NULL) and error. */
1351static struct ip6t_target ip6t_standard_target = { 1351static struct xt_target ip6t_standard_target = {
1352 .name = IP6T_STANDARD_TARGET, 1352 .name = IP6T_STANDARD_TARGET,
1353 .targetsize = sizeof(int), 1353 .targetsize = sizeof(int),
1354 .family = AF_INET6, 1354 .family = AF_INET6,
1355}; 1355};
1356 1356
1357static struct ip6t_target ip6t_error_target = { 1357static struct xt_target ip6t_error_target = {
1358 .name = IP6T_ERROR_TARGET, 1358 .name = IP6T_ERROR_TARGET,
1359 .target = ip6t_error, 1359 .target = ip6t_error,
1360 .targetsize = IP6T_FUNCTION_MAXNAMELEN, 1360 .targetsize = IP6T_FUNCTION_MAXNAMELEN,
@@ -1371,7 +1371,7 @@ static struct nf_sockopt_ops ip6t_sockopts = {
1371 .get = do_ip6t_get_ctl, 1371 .get = do_ip6t_get_ctl,
1372}; 1372};
1373 1373
1374static struct ip6t_match icmp6_matchstruct = { 1374static struct xt_match icmp6_matchstruct = {
1375 .name = "icmp6", 1375 .name = "icmp6",
1376 .match = &icmp6_match, 1376 .match = &icmp6_match,
1377 .matchsize = sizeof(struct ip6t_icmp), 1377 .matchsize = sizeof(struct ip6t_icmp),
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index 435750f664dd..04e500172fb4 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -9,12 +9,13 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/ip.h> 11#include <linux/ip.h>
12#include <linux/ipv6.h>
12 13
13#include <linux/netfilter_ipv6/ip6_tables.h> 14#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter_ipv6/ip6t_HL.h> 15#include <linux/netfilter_ipv6/ip6t_HL.h>
15 16
16MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>"); 17MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
17MODULE_DESCRIPTION("IP tables Hop Limit modification module"); 18MODULE_DESCRIPTION("IP6 tables Hop Limit modification module");
18MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
19 20
20static unsigned int ip6t_hl_target(struct sk_buff **pskb, 21static unsigned int ip6t_hl_target(struct sk_buff **pskb,
@@ -52,10 +53,9 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
52 break; 53 break;
53 } 54 }
54 55
55 if (new_hl != ip6h->hop_limit) 56 ip6h->hop_limit = new_hl;
56 ip6h->hop_limit = new_hl;
57 57
58 return IP6T_CONTINUE; 58 return XT_CONTINUE;
59} 59}
60 60
61static int ip6t_hl_checkentry(const char *tablename, 61static int ip6t_hl_checkentry(const char *tablename,
@@ -79,8 +79,9 @@ static int ip6t_hl_checkentry(const char *tablename,
79 return 1; 79 return 1;
80} 80}
81 81
82static struct ip6t_target ip6t_HL = { 82static struct xt_target ip6t_HL = {
83 .name = "HL", 83 .name = "HL",
84 .family = AF_INET6,
84 .target = ip6t_hl_target, 85 .target = ip6t_hl_target,
85 .targetsize = sizeof(struct ip6t_HL_info), 86 .targetsize = sizeof(struct ip6t_HL_info),
86 .table = "mangle", 87 .table = "mangle",
@@ -90,12 +91,12 @@ static struct ip6t_target ip6t_HL = {
90 91
91static int __init ip6t_hl_init(void) 92static int __init ip6t_hl_init(void)
92{ 93{
93 return ip6t_register_target(&ip6t_HL); 94 return xt_register_target(&ip6t_HL);
94} 95}
95 96
96static void __exit ip6t_hl_fini(void) 97static void __exit ip6t_hl_fini(void)
97{ 98{
98 ip6t_unregister_target(&ip6t_HL); 99 xt_unregister_target(&ip6t_HL);
99} 100}
100 101
101module_init(ip6t_hl_init); 102module_init(ip6t_hl_init);
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 33b1faa90d74..5587a77b884c 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -21,6 +21,7 @@
21#include <net/tcp.h> 21#include <net/tcp.h>
22#include <net/ipv6.h> 22#include <net/ipv6.h>
23#include <linux/netfilter.h> 23#include <linux/netfilter.h>
24#include <linux/netfilter/x_tables.h>
24#include <linux/netfilter_ipv6/ip6_tables.h> 25#include <linux/netfilter_ipv6/ip6_tables.h>
25 26
26MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>"); 27MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
@@ -442,7 +443,7 @@ ip6t_log_target(struct sk_buff **pskb,
442 443
443 ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, 444 ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
444 loginfo->prefix); 445 loginfo->prefix);
445 return IP6T_CONTINUE; 446 return XT_CONTINUE;
446} 447}
447 448
448 449
@@ -466,8 +467,9 @@ static int ip6t_log_checkentry(const char *tablename,
466 return 1; 467 return 1;
467} 468}
468 469
469static struct ip6t_target ip6t_log_reg = { 470static struct xt_target ip6t_log_reg = {
470 .name = "LOG", 471 .name = "LOG",
472 .family = AF_INET6,
471 .target = ip6t_log_target, 473 .target = ip6t_log_target,
472 .targetsize = sizeof(struct ip6t_log_info), 474 .targetsize = sizeof(struct ip6t_log_info),
473 .checkentry = ip6t_log_checkentry, 475 .checkentry = ip6t_log_checkentry,
@@ -482,8 +484,11 @@ static struct nf_logger ip6t_logger = {
482 484
483static int __init ip6t_log_init(void) 485static int __init ip6t_log_init(void)
484{ 486{
485 if (ip6t_register_target(&ip6t_log_reg)) 487 int ret;
486 return -EINVAL; 488
489 ret = xt_register_target(&ip6t_log_reg);
490 if (ret < 0)
491 return ret;
487 if (nf_log_register(PF_INET6, &ip6t_logger) < 0) { 492 if (nf_log_register(PF_INET6, &ip6t_logger) < 0) {
488 printk(KERN_WARNING "ip6t_LOG: not logging via system console " 493 printk(KERN_WARNING "ip6t_LOG: not logging via system console "
489 "since somebody else already registered for PF_INET6\n"); 494 "since somebody else already registered for PF_INET6\n");
@@ -497,7 +502,7 @@ static int __init ip6t_log_init(void)
497static void __exit ip6t_log_fini(void) 502static void __exit ip6t_log_fini(void)
498{ 503{
499 nf_log_unregister_logger(&ip6t_logger); 504 nf_log_unregister_logger(&ip6t_logger);
500 ip6t_unregister_target(&ip6t_log_reg); 505 xt_unregister_target(&ip6t_log_reg);
501} 506}
502 507
503module_init(ip6t_log_init); 508module_init(ip6t_log_init);
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 311eae82feb3..278349c18793 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -26,6 +26,7 @@
26#include <net/ip6_fib.h> 26#include <net/ip6_fib.h>
27#include <net/ip6_route.h> 27#include <net/ip6_route.h>
28#include <net/flow.h> 28#include <net/flow.h>
29#include <linux/netfilter/x_tables.h>
29#include <linux/netfilter_ipv6/ip6_tables.h> 30#include <linux/netfilter_ipv6/ip6_tables.h>
30#include <linux/netfilter_ipv6/ip6t_REJECT.h> 31#include <linux/netfilter_ipv6/ip6t_REJECT.h>
31 32
@@ -234,7 +235,7 @@ static int check(const char *tablename,
234 } else if (rejinfo->with == IP6T_TCP_RESET) { 235 } else if (rejinfo->with == IP6T_TCP_RESET) {
235 /* Must specify that it's a TCP packet */ 236 /* Must specify that it's a TCP packet */
236 if (e->ipv6.proto != IPPROTO_TCP 237 if (e->ipv6.proto != IPPROTO_TCP
237 || (e->ipv6.invflags & IP6T_INV_PROTO)) { 238 || (e->ipv6.invflags & XT_INV_PROTO)) {
238 DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); 239 DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
239 return 0; 240 return 0;
240 } 241 }
@@ -242,8 +243,9 @@ static int check(const char *tablename,
242 return 1; 243 return 1;
243} 244}
244 245
245static struct ip6t_target ip6t_reject_reg = { 246static struct xt_target ip6t_reject_reg = {
246 .name = "REJECT", 247 .name = "REJECT",
248 .family = AF_INET6,
247 .target = reject6_target, 249 .target = reject6_target,
248 .targetsize = sizeof(struct ip6t_reject_info), 250 .targetsize = sizeof(struct ip6t_reject_info),
249 .table = "filter", 251 .table = "filter",
@@ -255,12 +257,12 @@ static struct ip6t_target ip6t_reject_reg = {
255 257
256static int __init ip6t_reject_init(void) 258static int __init ip6t_reject_init(void)
257{ 259{
258 return ip6t_register_target(&ip6t_reject_reg); 260 return xt_register_target(&ip6t_reject_reg);
259} 261}
260 262
261static void __exit ip6t_reject_fini(void) 263static void __exit ip6t_reject_fini(void)
262{ 264{
263 ip6t_unregister_target(&ip6t_reject_reg); 265 xt_unregister_target(&ip6t_reject_reg);
264} 266}
265 267
266module_init(ip6t_reject_init); 268module_init(ip6t_reject_init);
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 46486645eb75..456c76adcbf6 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -15,6 +15,7 @@
15#include <net/checksum.h> 15#include <net/checksum.h>
16#include <net/ipv6.h> 16#include <net/ipv6.h>
17 17
18#include <linux/netfilter/x_tables.h>
18#include <linux/netfilter_ipv6/ip6_tables.h> 19#include <linux/netfilter_ipv6/ip6_tables.h>
19#include <linux/netfilter_ipv6/ip6t_ah.h> 20#include <linux/netfilter_ipv6/ip6t_ah.h>
20 21
@@ -118,8 +119,9 @@ checkentry(const char *tablename,
118 return 1; 119 return 1;
119} 120}
120 121
121static struct ip6t_match ah_match = { 122static struct xt_match ah_match = {
122 .name = "ah", 123 .name = "ah",
124 .family = AF_INET6,
123 .match = match, 125 .match = match,
124 .matchsize = sizeof(struct ip6t_ah), 126 .matchsize = sizeof(struct ip6t_ah),
125 .checkentry = checkentry, 127 .checkentry = checkentry,
@@ -128,12 +130,12 @@ static struct ip6t_match ah_match = {
128 130
129static int __init ip6t_ah_init(void) 131static int __init ip6t_ah_init(void)
130{ 132{
131 return ip6t_register_match(&ah_match); 133 return xt_register_match(&ah_match);
132} 134}
133 135
134static void __exit ip6t_ah_fini(void) 136static void __exit ip6t_ah_fini(void)
135{ 137{
136 ip6t_unregister_match(&ah_match); 138 xt_unregister_match(&ah_match);
137} 139}
138 140
139module_init(ip6t_ah_init); 141module_init(ip6t_ah_init);
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 4f6b84c8f4ab..967bed71d4a8 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -12,6 +12,7 @@
12#include <linux/ipv6.h> 12#include <linux/ipv6.h>
13#include <linux/if_ether.h> 13#include <linux/if_ether.h>
14 14
15#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_ipv6/ip6_tables.h> 16#include <linux/netfilter_ipv6/ip6_tables.h>
16 17
17MODULE_DESCRIPTION("IPv6 EUI64 address checking match"); 18MODULE_DESCRIPTION("IPv6 EUI64 address checking match");
@@ -61,8 +62,9 @@ match(const struct sk_buff *skb,
61 return 0; 62 return 0;
62} 63}
63 64
64static struct ip6t_match eui64_match = { 65static struct xt_match eui64_match = {
65 .name = "eui64", 66 .name = "eui64",
67 .family = AF_INET6,
66 .match = match, 68 .match = match,
67 .matchsize = sizeof(int), 69 .matchsize = sizeof(int),
68 .hooks = (1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) | 70 .hooks = (1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
@@ -72,12 +74,12 @@ static struct ip6t_match eui64_match = {
72 74
73static int __init ip6t_eui64_init(void) 75static int __init ip6t_eui64_init(void)
74{ 76{
75 return ip6t_register_match(&eui64_match); 77 return xt_register_match(&eui64_match);
76} 78}
77 79
78static void __exit ip6t_eui64_fini(void) 80static void __exit ip6t_eui64_fini(void)
79{ 81{
80 ip6t_unregister_match(&eui64_match); 82 xt_unregister_match(&eui64_match);
81} 83}
82 84
83module_init(ip6t_eui64_init); 85module_init(ip6t_eui64_init);
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index cd22eaaccdca..5a5da71321b6 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -14,6 +14,7 @@
14#include <net/checksum.h> 14#include <net/checksum.h>
15#include <net/ipv6.h> 15#include <net/ipv6.h>
16 16
17#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter_ipv6/ip6_tables.h> 18#include <linux/netfilter_ipv6/ip6_tables.h>
18#include <linux/netfilter_ipv6/ip6t_frag.h> 19#include <linux/netfilter_ipv6/ip6t_frag.h>
19 20
@@ -135,8 +136,9 @@ checkentry(const char *tablename,
135 return 1; 136 return 1;
136} 137}
137 138
138static struct ip6t_match frag_match = { 139static struct xt_match frag_match = {
139 .name = "frag", 140 .name = "frag",
141 .family = AF_INET6,
140 .match = match, 142 .match = match,
141 .matchsize = sizeof(struct ip6t_frag), 143 .matchsize = sizeof(struct ip6t_frag),
142 .checkentry = checkentry, 144 .checkentry = checkentry,
@@ -145,12 +147,12 @@ static struct ip6t_match frag_match = {
145 147
146static int __init ip6t_frag_init(void) 148static int __init ip6t_frag_init(void)
147{ 149{
148 return ip6t_register_match(&frag_match); 150 return xt_register_match(&frag_match);
149} 151}
150 152
151static void __exit ip6t_frag_fini(void) 153static void __exit ip6t_frag_fini(void)
152{ 154{
153 ip6t_unregister_match(&frag_match); 155 xt_unregister_match(&frag_match);
154} 156}
155 157
156module_init(ip6t_frag_init); 158module_init(ip6t_frag_init);
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 3f25babe0440..d2373c7cd354 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -16,6 +16,7 @@
16 16
17#include <asm/byteorder.h> 17#include <asm/byteorder.h>
18 18
19#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter_ipv6/ip6_tables.h> 20#include <linux/netfilter_ipv6/ip6_tables.h>
20#include <linux/netfilter_ipv6/ip6t_opts.h> 21#include <linux/netfilter_ipv6/ip6t_opts.h>
21 22
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index 44a729e17c48..601cc1211c62 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -8,11 +8,12 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/ipv6.h>
11#include <linux/module.h> 12#include <linux/module.h>
12#include <linux/skbuff.h> 13#include <linux/skbuff.h>
13 14
14#include <linux/netfilter_ipv6/ip6t_hl.h> 15#include <linux/netfilter_ipv6/ip6t_hl.h>
15#include <linux/netfilter_ipv6/ip6_tables.h> 16#include <linux/netfilter/x_tables.h>
16 17
17MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>"); 18MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
18MODULE_DESCRIPTION("IP tables Hop Limit matching module"); 19MODULE_DESCRIPTION("IP tables Hop Limit matching module");
@@ -48,8 +49,9 @@ static int match(const struct sk_buff *skb,
48 return 0; 49 return 0;
49} 50}
50 51
51static struct ip6t_match hl_match = { 52static struct xt_match hl_match = {
52 .name = "hl", 53 .name = "hl",
54 .family = AF_INET6,
53 .match = match, 55 .match = match,
54 .matchsize = sizeof(struct ip6t_hl_info), 56 .matchsize = sizeof(struct ip6t_hl_info),
55 .me = THIS_MODULE, 57 .me = THIS_MODULE,
@@ -57,13 +59,12 @@ static struct ip6t_match hl_match = {
57 59
58static int __init ip6t_hl_init(void) 60static int __init ip6t_hl_init(void)
59{ 61{
60 return ip6t_register_match(&hl_match); 62 return xt_register_match(&hl_match);
61} 63}
62 64
63static void __exit ip6t_hl_fini(void) 65static void __exit ip6t_hl_fini(void)
64{ 66{
65 ip6t_unregister_match(&hl_match); 67 xt_unregister_match(&hl_match);
66
67} 68}
68 69
69module_init(ip6t_hl_init); 70module_init(ip6t_hl_init);
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 3093c398002f..26ac084adefc 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -18,6 +18,7 @@
18#include <net/checksum.h> 18#include <net/checksum.h>
19#include <net/ipv6.h> 19#include <net/ipv6.h>
20 20
21#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_ipv6/ip6_tables.h> 22#include <linux/netfilter_ipv6/ip6_tables.h>
22#include <linux/netfilter_ipv6/ip6t_ipv6header.h> 23#include <linux/netfilter_ipv6/ip6t_ipv6header.h>
23 24
@@ -140,8 +141,9 @@ ipv6header_checkentry(const char *tablename,
140 return 1; 141 return 1;
141} 142}
142 143
143static struct ip6t_match ip6t_ipv6header_match = { 144static struct xt_match ip6t_ipv6header_match = {
144 .name = "ipv6header", 145 .name = "ipv6header",
146 .family = AF_INET6,
145 .match = &ipv6header_match, 147 .match = &ipv6header_match,
146 .matchsize = sizeof(struct ip6t_ipv6header_info), 148 .matchsize = sizeof(struct ip6t_ipv6header_info),
147 .checkentry = &ipv6header_checkentry, 149 .checkentry = &ipv6header_checkentry,
@@ -151,12 +153,12 @@ static struct ip6t_match ip6t_ipv6header_match = {
151 153
152static int __init ipv6header_init(void) 154static int __init ipv6header_init(void)
153{ 155{
154 return ip6t_register_match(&ip6t_ipv6header_match); 156 return xt_register_match(&ip6t_ipv6header_match);
155} 157}
156 158
157static void __exit ipv6header_exit(void) 159static void __exit ipv6header_exit(void)
158{ 160{
159 ip6t_unregister_match(&ip6t_ipv6header_match); 161 xt_unregister_match(&ip6t_ipv6header_match);
160} 162}
161 163
162module_init(ipv6header_init); 164module_init(ipv6header_init);
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c
new file mode 100644
index 000000000000..2c7efc6a506d
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_mh.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C)2006 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Author:
9 * Masahide NAKAMURA @USAGI <masahide.nakamura.cz@hitachi.com>
10 *
11 * Based on net/netfilter/xt_tcpudp.c
12 *
13 */
14#include <linux/types.h>
15#include <linux/module.h>
16#include <net/ip.h>
17#include <linux/ipv6.h>
18#include <net/ipv6.h>
19#include <net/mip6.h>
20
21#include <linux/netfilter/x_tables.h>
22#include <linux/netfilter_ipv6/ip6t_mh.h>
23
24MODULE_DESCRIPTION("ip6t_tables match for MH");
25MODULE_LICENSE("GPL");
26
27#ifdef DEBUG_IP_FIREWALL_USER
28#define duprintf(format, args...) printk(format , ## args)
29#else
30#define duprintf(format, args...)
31#endif
32
33/* Returns 1 if the type is matched by the range, 0 otherwise */
34static inline int
35type_match(u_int8_t min, u_int8_t max, u_int8_t type, int invert)
36{
37 int ret;
38
39 ret = (type >= min && type <= max) ^ invert;
40 return ret;
41}
42
43static int
44match(const struct sk_buff *skb,
45 const struct net_device *in,
46 const struct net_device *out,
47 const struct xt_match *match,
48 const void *matchinfo,
49 int offset,
50 unsigned int protoff,
51 int *hotdrop)
52{
53 struct ip6_mh _mh, *mh;
54 const struct ip6t_mh *mhinfo = matchinfo;
55
56 /* Must not be a fragment. */
57 if (offset)
58 return 0;
59
60 mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh);
61 if (mh == NULL) {
62 /* We've been asked to examine this packet, and we
63 can't. Hence, no choice but to drop. */
64 duprintf("Dropping evil MH tinygram.\n");
65 *hotdrop = 1;
66 return 0;
67 }
68
69 return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type,
70 !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
71}
72
73/* Called when user tries to insert an entry of this type. */
74static int
75mh_checkentry(const char *tablename,
76 const void *entry,
77 const struct xt_match *match,
78 void *matchinfo,
79 unsigned int hook_mask)
80{
81 const struct ip6t_mh *mhinfo = matchinfo;
82
83 /* Must specify no unknown invflags */
84 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
85}
86
87static struct xt_match mh_match = {
88 .name = "mh",
89 .family = AF_INET6,
90 .checkentry = mh_checkentry,
91 .match = match,
92 .matchsize = sizeof(struct ip6t_mh),
93 .proto = IPPROTO_MH,
94 .me = THIS_MODULE,
95};
96
97static int __init ip6t_mh_init(void)
98{
99 return xt_register_match(&mh_match);
100}
101
102static void __exit ip6t_mh_fini(void)
103{
104 xt_unregister_match(&mh_match);
105}
106
107module_init(ip6t_mh_init);
108module_exit(ip6t_mh_fini);
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 4eb9bbc4ebc3..43738bba00b5 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/netfilter_ipv6/ip6t_owner.h> 17#include <linux/netfilter_ipv6/ip6t_owner.h>
18#include <linux/netfilter_ipv6/ip6_tables.h> 18#include <linux/netfilter_ipv6/ip6_tables.h>
19#include <linux/netfilter/x_tables.h>
19 20
20MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 21MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
21MODULE_DESCRIPTION("IP6 tables owner matching module"); 22MODULE_DESCRIPTION("IP6 tables owner matching module");
@@ -69,8 +70,9 @@ checkentry(const char *tablename,
69 return 1; 70 return 1;
70} 71}
71 72
72static struct ip6t_match owner_match = { 73static struct xt_match owner_match = {
73 .name = "owner", 74 .name = "owner",
75 .family = AF_INET6,
74 .match = match, 76 .match = match,
75 .matchsize = sizeof(struct ip6t_owner_info), 77 .matchsize = sizeof(struct ip6t_owner_info),
76 .hooks = (1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING), 78 .hooks = (1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING),
@@ -80,12 +82,12 @@ static struct ip6t_match owner_match = {
80 82
81static int __init ip6t_owner_init(void) 83static int __init ip6t_owner_init(void)
82{ 84{
83 return ip6t_register_match(&owner_match); 85 return xt_register_match(&owner_match);
84} 86}
85 87
86static void __exit ip6t_owner_fini(void) 88static void __exit ip6t_owner_fini(void)
87{ 89{
88 ip6t_unregister_match(&owner_match); 90 xt_unregister_match(&owner_match);
89} 91}
90 92
91module_init(ip6t_owner_init); 93module_init(ip6t_owner_init);
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 54d7d14134fd..81ab00d8c182 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -16,6 +16,7 @@
16 16
17#include <asm/byteorder.h> 17#include <asm/byteorder.h>
18 18
19#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter_ipv6/ip6_tables.h> 20#include <linux/netfilter_ipv6/ip6_tables.h>
20#include <linux/netfilter_ipv6/ip6t_rt.h> 21#include <linux/netfilter_ipv6/ip6t_rt.h>
21 22
@@ -221,8 +222,9 @@ checkentry(const char *tablename,
221 return 1; 222 return 1;
222} 223}
223 224
224static struct ip6t_match rt_match = { 225static struct xt_match rt_match = {
225 .name = "rt", 226 .name = "rt",
227 .family = AF_INET6,
226 .match = match, 228 .match = match,
227 .matchsize = sizeof(struct ip6t_rt), 229 .matchsize = sizeof(struct ip6t_rt),
228 .checkentry = checkentry, 230 .checkentry = checkentry,
@@ -231,12 +233,12 @@ static struct ip6t_match rt_match = {
231 233
232static int __init ip6t_rt_init(void) 234static int __init ip6t_rt_init(void)
233{ 235{
234 return ip6t_register_match(&rt_match); 236 return xt_register_match(&rt_match);
235} 237}
236 238
237static void __exit ip6t_rt_fini(void) 239static void __exit ip6t_rt_fini(void)
238{ 240{
239 ip6t_unregister_match(&rt_match); 241 xt_unregister_match(&rt_match);
240} 242}
241 243
242module_init(ip6t_rt_init); 244module_init(ip6t_rt_init);
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 2fc07c74decf..112a21d0c6da 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -19,25 +19,6 @@ MODULE_DESCRIPTION("ip6tables filter table");
19 19
20#define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT)) 20#define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT))
21 21
22/* Standard entry. */
23struct ip6t_standard
24{
25 struct ip6t_entry entry;
26 struct ip6t_standard_target target;
27};
28
29struct ip6t_error_target
30{
31 struct ip6t_entry_target target;
32 char errorname[IP6T_FUNCTION_MAXNAMELEN];
33};
34
35struct ip6t_error
36{
37 struct ip6t_entry entry;
38 struct ip6t_error_target target;
39};
40
41static struct 22static struct
42{ 23{
43 struct ip6t_replace repl; 24 struct ip6t_replace repl;
@@ -92,7 +73,7 @@ static struct
92 } 73 }
93}; 74};
94 75
95static struct ip6t_table packet_filter = { 76static struct xt_table packet_filter = {
96 .name = "filter", 77 .name = "filter",
97 .valid_hooks = FILTER_VALID_HOOKS, 78 .valid_hooks = FILTER_VALID_HOOKS,
98 .lock = RW_LOCK_UNLOCKED, 79 .lock = RW_LOCK_UNLOCKED,
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 6250e86a6ddc..5f5aa0e51478 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -29,25 +29,6 @@ MODULE_DESCRIPTION("ip6tables mangle table");
29#define DEBUGP(x, args...) 29#define DEBUGP(x, args...)
30#endif 30#endif
31 31
32/* Standard entry. */
33struct ip6t_standard
34{
35 struct ip6t_entry entry;
36 struct ip6t_standard_target target;
37};
38
39struct ip6t_error_target
40{
41 struct ip6t_entry_target target;
42 char errorname[IP6T_FUNCTION_MAXNAMELEN];
43};
44
45struct ip6t_error
46{
47 struct ip6t_entry entry;
48 struct ip6t_error_target target;
49};
50
51static struct 32static struct
52{ 33{
53 struct ip6t_replace repl; 34 struct ip6t_replace repl;
@@ -122,7 +103,7 @@ static struct
122 } 103 }
123}; 104};
124 105
125static struct ip6t_table packet_mangler = { 106static struct xt_table packet_mangler = {
126 .name = "mangle", 107 .name = "mangle",
127 .valid_hooks = MANGLE_VALID_HOOKS, 108 .valid_hooks = MANGLE_VALID_HOOKS,
128 .lock = RW_LOCK_UNLOCKED, 109 .lock = RW_LOCK_UNLOCKED,
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index b4154da575c0..277bf34638b4 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -14,25 +14,6 @@
14#define DEBUGP(x, args...) 14#define DEBUGP(x, args...)
15#endif 15#endif
16 16
17/* Standard entry. */
18struct ip6t_standard
19{
20 struct ip6t_entry entry;
21 struct ip6t_standard_target target;
22};
23
24struct ip6t_error_target
25{
26 struct ip6t_entry_target target;
27 char errorname[IP6T_FUNCTION_MAXNAMELEN];
28};
29
30struct ip6t_error
31{
32 struct ip6t_entry entry;
33 struct ip6t_error_target target;
34};
35
36static struct 17static struct
37{ 18{
38 struct ip6t_replace repl; 19 struct ip6t_replace repl;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 4ae1b19ada5d..c2d8059e754e 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -815,7 +815,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
815 if (final_p) 815 if (final_p)
816 ipv6_addr_copy(&fl.fl6_dst, final_p); 816 ipv6_addr_copy(&fl.fl6_dst, final_p);
817 817
818 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 818 if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
819 goto out; 819 goto out;
820 820
821 if (hlimit < 0) { 821 if (hlimit < 0) {
@@ -1094,10 +1094,19 @@ static void rawv6_close(struct sock *sk, long timeout)
1094 1094
1095static int rawv6_init_sk(struct sock *sk) 1095static int rawv6_init_sk(struct sock *sk)
1096{ 1096{
1097 if (inet_sk(sk)->num == IPPROTO_ICMPV6) { 1097 struct raw6_sock *rp = raw6_sk(sk);
1098 struct raw6_sock *rp = raw6_sk(sk); 1098
1099 switch (inet_sk(sk)->num) {
1100 case IPPROTO_ICMPV6:
1099 rp->checksum = 1; 1101 rp->checksum = 1;
1100 rp->offset = 2; 1102 rp->offset = 2;
1103 break;
1104 case IPPROTO_MH:
1105 rp->checksum = 1;
1106 rp->offset = 4;
1107 break;
1108 default:
1109 break;
1101 } 1110 }
1102 return(0); 1111 return(0);
1103} 1112}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 5f0043c30b70..19c906f6efa1 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -311,12 +311,21 @@ static inline void rt6_probe(struct rt6_info *rt)
311static int inline rt6_check_dev(struct rt6_info *rt, int oif) 311static int inline rt6_check_dev(struct rt6_info *rt, int oif)
312{ 312{
313 struct net_device *dev = rt->rt6i_dev; 313 struct net_device *dev = rt->rt6i_dev;
314 if (!oif || dev->ifindex == oif) 314 int ret = 0;
315
316 if (!oif)
315 return 2; 317 return 2;
316 if ((dev->flags & IFF_LOOPBACK) && 318 if (dev->flags & IFF_LOOPBACK) {
317 rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif) 319 if (!WARN_ON(rt->rt6i_idev == NULL) &&
318 return 1; 320 rt->rt6i_idev->dev->ifindex == oif)
319 return 0; 321 ret = 1;
322 else
323 return 0;
324 }
325 if (dev->ifindex == oif)
326 return 2;
327
328 return ret;
320} 329}
321 330
322static int inline rt6_check_neigh(struct rt6_info *rt) 331static int inline rt6_check_neigh(struct rt6_info *rt)
@@ -2040,7 +2049,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2040 2049
2041 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags); 2050 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
2042 if (nlh == NULL) 2051 if (nlh == NULL)
2043 return -ENOBUFS; 2052 return -EMSGSIZE;
2044 2053
2045 rtm = nlmsg_data(nlh); 2054 rtm = nlmsg_data(nlh);
2046 rtm->rtm_family = AF_INET6; 2055 rtm->rtm_family = AF_INET6;
@@ -2111,7 +2120,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2111 return nlmsg_end(skb, nlh); 2120 return nlmsg_end(skb, nlh);
2112 2121
2113nla_put_failure: 2122nla_put_failure:
2114 return nlmsg_cancel(skb, nlh); 2123 nlmsg_cancel(skb, nlh);
2124 return -EMSGSIZE;
2115} 2125}
2116 2126
2117int rt6_dump_route(struct rt6_info *rt, void *p_arg) 2127int rt6_dump_route(struct rt6_info *rt, void *p_arg)
@@ -2222,9 +2232,12 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2222 goto errout; 2232 goto errout;
2223 2233
2224 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); 2234 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2225 /* failure implies BUG in rt6_nlmsg_size() */ 2235 if (err < 0) {
2226 BUG_ON(err < 0); 2236 /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
2227 2237 WARN_ON(err == -EMSGSIZE);
2238 kfree_skb(skb);
2239 goto errout;
2240 }
2228 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); 2241 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
2229errout: 2242errout:
2230 if (err < 0) 2243 if (err < 0)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 77b7b0911438..47cfeadac6dd 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -686,7 +686,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
686 goto done; 686 goto done;
687 dev = t->dev; 687 dev = t->dev;
688 } 688 }
689 err = unregister_netdevice(dev); 689 unregister_netdevice(dev);
690 err = 0;
690 break; 691 break;
691 692
692 default: 693 default:
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index c25e930c2c69..dcb7b00a737d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -265,7 +265,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
265 if (final_p) 265 if (final_p)
266 ipv6_addr_copy(&fl.fl6_dst, final_p); 266 ipv6_addr_copy(&fl.fl6_dst, final_p);
267 267
268 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 268 if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
269 goto failure; 269 goto failure;
270 270
271 if (saddr == NULL) { 271 if (saddr == NULL) {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index f52a5c3cc0a3..15e5195549cb 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -736,7 +736,7 @@ do_udp_sendmsg:
736 if (final_p) 736 if (final_p)
737 ipv6_addr_copy(&fl.fl6_dst, final_p); 737 ipv6_addr_copy(&fl.fl6_dst, final_p);
738 738
739 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 739 if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
740 goto out; 740 goto out;
741 741
742 if (hlimit < 0) { 742 if (hlimit < 0) {
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 5e7d8a7d6414..0bc866c0d83c 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -25,6 +25,12 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
25 IP6_ECN_set_ce(inner_iph); 25 IP6_ECN_set_ce(inner_iph);
26} 26}
27 27
28static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
29{
30 if (INET_ECN_is_ce(ipv6_get_dsfield(skb->nh.ipv6h)))
31 IP_ECN_set_ce(skb->h.ipiph);
32}
33
28/* Add encapsulation header. 34/* Add encapsulation header.
29 * 35 *
30 * The top IP header will be constructed per RFC 2401. The following fields 36 * The top IP header will be constructed per RFC 2401. The following fields
@@ -40,6 +46,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
40static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) 46static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
41{ 47{
42 struct dst_entry *dst = skb->dst; 48 struct dst_entry *dst = skb->dst;
49 struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
43 struct ipv6hdr *iph, *top_iph; 50 struct ipv6hdr *iph, *top_iph;
44 int dsfield; 51 int dsfield;
45 52
@@ -52,16 +59,24 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
52 skb->h.ipv6h = top_iph + 1; 59 skb->h.ipv6h = top_iph + 1;
53 60
54 top_iph->version = 6; 61 top_iph->version = 6;
55 top_iph->priority = iph->priority; 62 if (xdst->route->ops->family == AF_INET6) {
56 top_iph->flow_lbl[0] = iph->flow_lbl[0]; 63 top_iph->priority = iph->priority;
57 top_iph->flow_lbl[1] = iph->flow_lbl[1]; 64 top_iph->flow_lbl[0] = iph->flow_lbl[0];
58 top_iph->flow_lbl[2] = iph->flow_lbl[2]; 65 top_iph->flow_lbl[1] = iph->flow_lbl[1];
66 top_iph->flow_lbl[2] = iph->flow_lbl[2];
67 top_iph->nexthdr = IPPROTO_IPV6;
68 } else {
69 top_iph->priority = 0;
70 top_iph->flow_lbl[0] = 0;
71 top_iph->flow_lbl[1] = 0;
72 top_iph->flow_lbl[2] = 0;
73 top_iph->nexthdr = IPPROTO_IPIP;
74 }
59 dsfield = ipv6_get_dsfield(top_iph); 75 dsfield = ipv6_get_dsfield(top_iph);
60 dsfield = INET_ECN_encapsulate(dsfield, dsfield); 76 dsfield = INET_ECN_encapsulate(dsfield, dsfield);
61 if (x->props.flags & XFRM_STATE_NOECN) 77 if (x->props.flags & XFRM_STATE_NOECN)
62 dsfield &= ~INET_ECN_MASK; 78 dsfield &= ~INET_ECN_MASK;
63 ipv6_change_dsfield(top_iph, 0, dsfield); 79 ipv6_change_dsfield(top_iph, 0, dsfield);
64 top_iph->nexthdr = IPPROTO_IPV6;
65 top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); 80 top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
66 ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); 81 ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
67 ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); 82 ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
@@ -72,7 +87,8 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
72{ 87{
73 int err = -EINVAL; 88 int err = -EINVAL;
74 89
75 if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6) 90 if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6
91 && skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
76 goto out; 92 goto out;
77 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 93 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
78 goto out; 94 goto out;
@@ -81,10 +97,16 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
81 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 97 (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
82 goto out; 98 goto out;
83 99
84 if (x->props.flags & XFRM_STATE_DECAP_DSCP) 100 if (skb->nh.raw[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
85 ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h); 101 if (x->props.flags & XFRM_STATE_DECAP_DSCP)
86 if (!(x->props.flags & XFRM_STATE_NOECN)) 102 ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
87 ipip6_ecn_decapsulate(skb); 103 if (!(x->props.flags & XFRM_STATE_NOECN))
104 ipip6_ecn_decapsulate(skb);
105 } else {
106 if (!(x->props.flags & XFRM_STATE_NOECN))
107 ip6ip_ecn_decapsulate(skb);
108 skb->protocol = htons(ETH_P_IP);
109 }
88 skb->mac.raw = memmove(skb->data - skb->mac_len, 110 skb->mac.raw = memmove(skb->data - skb->mac_len,
89 skb->mac.raw, skb->mac_len); 111 skb->mac.raw, skb->mac_len);
90 skb->nh.raw = skb->data; 112 skb->nh.raw = skb->data;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8dffd4daae9c..59480e92177d 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -131,13 +131,11 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
131 struct dst_entry *dst, *dst_prev; 131 struct dst_entry *dst, *dst_prev;
132 struct rt6_info *rt0 = (struct rt6_info*)(*dst_p); 132 struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
133 struct rt6_info *rt = rt0; 133 struct rt6_info *rt = rt0;
134 struct in6_addr *remote = &fl->fl6_dst;
135 struct in6_addr *local = &fl->fl6_src;
136 struct flowi fl_tunnel = { 134 struct flowi fl_tunnel = {
137 .nl_u = { 135 .nl_u = {
138 .ip6_u = { 136 .ip6_u = {
139 .saddr = *local, 137 .saddr = fl->fl6_src,
140 .daddr = *remote 138 .daddr = fl->fl6_dst,
141 } 139 }
142 } 140 }
143 }; 141 };
@@ -153,7 +151,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
153 for (i = 0; i < nx; i++) { 151 for (i = 0; i < nx; i++) {
154 struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops); 152 struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops);
155 struct xfrm_dst *xdst; 153 struct xfrm_dst *xdst;
156 int tunnel = 0;
157 154
158 if (unlikely(dst1 == NULL)) { 155 if (unlikely(dst1 == NULL)) {
159 err = -ENOBUFS; 156 err = -ENOBUFS;
@@ -177,19 +174,27 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
177 174
178 dst1->next = dst_prev; 175 dst1->next = dst_prev;
179 dst_prev = dst1; 176 dst_prev = dst1;
180 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { 177
181 remote = __xfrm6_bundle_addr_remote(xfrm[i], remote);
182 local = __xfrm6_bundle_addr_local(xfrm[i], local);
183 tunnel = 1;
184 }
185 __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]); 178 __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
186 trailer_len += xfrm[i]->props.trailer_len; 179 trailer_len += xfrm[i]->props.trailer_len;
187 180
188 if (tunnel) { 181 if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {
189 ipv6_addr_copy(&fl_tunnel.fl6_dst, remote); 182 unsigned short encap_family = xfrm[i]->props.family;
190 ipv6_addr_copy(&fl_tunnel.fl6_src, local); 183 switch(encap_family) {
184 case AF_INET:
185 fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;
186 fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
187 break;
188 case AF_INET6:
189 ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr*)&xfrm[i]->id.daddr.a6);
190 ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr*)&xfrm[i]->props.saddr.a6);
191 break;
192 default:
193 BUG_ON(1);
194 }
195
191 err = xfrm_dst_lookup((struct xfrm_dst **) &rt, 196 err = xfrm_dst_lookup((struct xfrm_dst **) &rt,
192 &fl_tunnel, AF_INET6); 197 &fl_tunnel, encap_family);
193 if (err) 198 if (err)
194 goto error; 199 goto error;
195 } else 200 } else
@@ -208,6 +213,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
208 i = 0; 213 i = 0;
209 for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { 214 for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
210 struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; 215 struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
216 struct xfrm_state_afinfo *afinfo;
211 217
212 dst_prev->xfrm = xfrm[i++]; 218 dst_prev->xfrm = xfrm[i++];
213 dst_prev->dev = rt->u.dst.dev; 219 dst_prev->dev = rt->u.dst.dev;
@@ -224,7 +230,17 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
224 /* Copy neighbour for reachability confirmation */ 230 /* Copy neighbour for reachability confirmation */
225 dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); 231 dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
226 dst_prev->input = rt->u.dst.input; 232 dst_prev->input = rt->u.dst.input;
227 dst_prev->output = xfrm6_output; 233 /* XXX: When IPv4 is implemented as module and can be unloaded,
234 * we should manage reference to xfrm4_output in afinfo->output.
235 * Miyazawa
236 */
237 afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
238 if (!afinfo) {
239 dst = *dst_p;
240 goto error;
241 };
242 dst_prev->output = afinfo->output;
243 xfrm_state_put_afinfo(afinfo);
228 /* Sheit... I remember I did this right. Apparently, 244 /* Sheit... I remember I did this right. Apparently,
229 * it was magically lost, so this code needs audit */ 245 * it was magically lost, so this code needs audit */
230 x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); 246 x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 9ddaa9d41539..60ad5f074e0a 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -171,6 +171,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
171 .init_tempsel = __xfrm6_init_tempsel, 171 .init_tempsel = __xfrm6_init_tempsel,
172 .tmpl_sort = __xfrm6_tmpl_sort, 172 .tmpl_sort = __xfrm6_tmpl_sort,
173 .state_sort = __xfrm6_state_sort, 173 .state_sort = __xfrm6_state_sort,
174 .output = xfrm6_output,
174}; 175};
175 176
176void __init xfrm6_state_init(void) 177void __init xfrm6_state_init(void)