aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:40:30 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:40:30 -0400
commita57793651ff1a09ef18bade998632435ca2dc13f (patch)
treefffc839d7b001f196421f09f0a06491588835fe1 /net
parent9cf52b2921fbe62566b6b2ee79f71203749c9e5e (diff)
parent52f095ee88d8851866bc7694ab991ca5abf21d5e (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (51 commits) [IPV6]: Fix again the fl6_sock_lookup() fixed locking [NETFILTER]: nf_conntrack_tcp: fix connection reopening fix [IPV6]: Fix race in ipv6_flowlabel_opt() when inserting two labels [IPV6]: Lost locking in fl6_sock_lookup [IPV6]: Lost locking when inserting a flowlabel in ipv6_fl_list [NETFILTER]: xt_sctp: fix mistake to pass a pointer where array is required [NET]: Fix OOPS due to missing check in dev_parse_header(). [TCP]: Remove lost_retrans zero seqno special cases [NET]: fix carrier-on bug? [NET]: Fix uninitialised variable in ip_frag_reasm() [IPSEC]: Rename mode to outer_mode and add inner_mode [IPSEC]: Disallow combinations of RO and AH/ESP/IPCOMP [IPSEC]: Use the top IPv4 route's peer instead of the bottom [IPSEC]: Store afinfo pointer in xfrm_mode [IPSEC]: Add missing BEET checks [IPSEC]: Move type and mode map into xfrm_state.c [IPSEC]: Fix length check in xfrm_parse_spi [IPSEC]: Move ip_summed zapping out of xfrm6_rcv_spi [IPSEC]: Get nexthdr from caller in xfrm6_rcv_spi [IPSEC]: Move tunnel parsing for IPv4 out of xfrm4_input ...
Diffstat (limited to 'net')
-rw-r--r--net/atm/br2684.c121
-rw-r--r--net/core/filter.c58
-rw-r--r--net/core/pktgen.c2
-rw-r--r--net/core/sock.c14
-rw-r--r--net/dccp/input.c3
-rw-r--r--net/dccp/sysctl.c3
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c2
-rw-r--r--net/ipv4/inet_fragment.c89
-rw-r--r--net/ipv4/ip_fragment.c159
-rw-r--r--net/ipv4/tcp_input.c6
-rw-r--r--net/ipv4/xfrm4_input.c40
-rw-r--r--net/ipv4/xfrm4_mode_beet.c1
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c1
-rw-r--r--net/ipv4/xfrm4_output.c2
-rw-r--r--net/ipv4/xfrm4_policy.c27
-rw-r--r--net/ipv4/xfrm4_state.c1
-rw-r--r--net/ipv4/xfrm4_tunnel.c11
-rw-r--r--net/ipv6/addrconf.c10
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/ah6.c11
-rw-r--r--net/ipv6/esp6.c9
-rw-r--r--net/ipv6/ip6_flowlabel.c57
-rw-r--r--net/ipv6/ipcomp6.c9
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c112
-rw-r--r--net/ipv6/reassembly.c131
-rw-r--r--net/ipv6/xfrm6_input.c14
-rw-r--r--net/ipv6/xfrm6_mode_beet.c1
-rw-r--r--net/ipv6/xfrm6_mode_ro.c9
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c1
-rw-r--r--net/ipv6/xfrm6_output.c2
-rw-r--r--net/ipv6/xfrm6_policy.c17
-rw-r--r--net/ipv6/xfrm6_state.c7
-rw-r--r--net/ipv6/xfrm6_tunnel.c4
-rw-r--r--net/irda/ircomm/ircomm_tty_attach.c15
-rw-r--r--net/mac80211/ieee80211_ioctl.c16
-rw-r--r--net/mac80211/ieee80211_sta.c71
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c11
-rw-r--r--net/netfilter/xt_sctp.c18
-rw-r--r--net/sched/sch_generic.c7
-rw-r--r--net/xfrm/xfrm_input.c5
-rw-r--r--net/xfrm/xfrm_output.c4
-rw-r--r--net/xfrm/xfrm_policy.c179
-rw-r--r--net/xfrm/xfrm_state.c206
43 files changed, 661 insertions, 806 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index c742d37bfb97..ba6428f204f9 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -24,16 +24,6 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
24 24
25#include "common.h" 25#include "common.h"
26 26
27/*
28 * Define this to use a version of the code which interacts with the higher
29 * layers in a more intellegent way, by always reserving enough space for
30 * our header at the begining of the packet. However, there may still be
31 * some problems with programs like tcpdump. In 2.5 we'll sort out what
32 * we need to do to get this perfect. For now we just will copy the packet
33 * if we need space for the header
34 */
35/* #define FASTER_VERSION */
36
37#ifdef SKB_DEBUG 27#ifdef SKB_DEBUG
38static void skb_debug(const struct sk_buff *skb) 28static void skb_debug(const struct sk_buff *skb)
39{ 29{
@@ -69,9 +59,7 @@ struct br2684_vcc {
69#ifdef CONFIG_ATM_BR2684_IPFILTER 59#ifdef CONFIG_ATM_BR2684_IPFILTER
70 struct br2684_filter filter; 60 struct br2684_filter filter;
71#endif /* CONFIG_ATM_BR2684_IPFILTER */ 61#endif /* CONFIG_ATM_BR2684_IPFILTER */
72#ifndef FASTER_VERSION
73 unsigned copies_needed, copies_failed; 62 unsigned copies_needed, copies_failed;
74#endif /* FASTER_VERSION */
75}; 63};
76 64
77struct br2684_dev { 65struct br2684_dev {
@@ -147,13 +135,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
147 struct br2684_vcc *brvcc) 135 struct br2684_vcc *brvcc)
148{ 136{
149 struct atm_vcc *atmvcc; 137 struct atm_vcc *atmvcc;
150#ifdef FASTER_VERSION
151 if (brvcc->encaps == e_llc)
152 memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8);
153 /* last 2 bytes of llc_oui_pid_pad are managed by header routines;
154 yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad)
155 */
156#else
157 int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2; 138 int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
158 if (skb_headroom(skb) < minheadroom) { 139 if (skb_headroom(skb) < minheadroom) {
159 struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom); 140 struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
@@ -170,7 +151,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
170 skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10); 151 skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10);
171 else 152 else
172 memset(skb->data, 0, 2); 153 memset(skb->data, 0, 2);
173#endif /* FASTER_VERSION */
174 skb_debug(skb); 154 skb_debug(skb);
175 155
176 ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; 156 ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
@@ -237,87 +217,6 @@ static struct net_device_stats *br2684_get_stats(struct net_device *dev)
237 return &BRPRIV(dev)->stats; 217 return &BRPRIV(dev)->stats;
238} 218}
239 219
240#ifdef FASTER_VERSION
241/*
242 * These mirror eth_header and eth_header_cache. They are not usually
243 * exported for use in modules, so we grab them from net_device
244 * after ether_setup() is done with it. Bit of a hack.
245 */
246static int (*my_eth_header)(struct sk_buff *, struct net_device *,
247 unsigned short, void *, void *, unsigned);
248static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *);
249
250static int
251br2684_header(struct sk_buff *skb, struct net_device *dev,
252 unsigned short type, void *daddr, void *saddr, unsigned len)
253{
254 u16 *pad_before_eth;
255 int t = my_eth_header(skb, dev, type, daddr, saddr, len);
256 if (t > 0) {
257 pad_before_eth = (u16 *) skb_push(skb, 2);
258 *pad_before_eth = 0;
259 return dev->hard_header_len; /* or return 16; ? */
260 } else
261 return t;
262}
263
264static int
265br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh)
266{
267/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so
268xmit will add the additional header part in that case */
269 u16 *pad_before_eth = (u16 *)(hh->hh_data);
270 int t = my_eth_header_cache(neigh, hh);
271 DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh);
272 if (t < 0)
273 return t;
274 else {
275 *pad_before_eth = 0;
276 hh->hh_len = PADLEN + ETH_HLEN;
277 }
278 return 0;
279}
280
281/*
282 * This is similar to eth_type_trans, which cannot be used because of
283 * our dev->hard_header_len
284 */
285static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev)
286{
287 struct ethhdr *eth;
288 unsigned char *rawp;
289 eth = eth_hdr(skb);
290
291 if (is_multicast_ether_addr(eth->h_dest)) {
292 if (!compare_ether_addr(eth->h_dest, dev->broadcast))
293 skb->pkt_type = PACKET_BROADCAST;
294 else
295 skb->pkt_type = PACKET_MULTICAST;
296 }
297
298 else if (compare_ether_addr(eth->h_dest, dev->dev_addr))
299 skb->pkt_type = PACKET_OTHERHOST;
300
301 if (ntohs(eth->h_proto) >= 1536)
302 return eth->h_proto;
303
304 rawp = skb->data;
305
306 /*
307 * This is a magic hack to spot IPX packets. Older Novell breaks
308 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
309 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
310 * won't work for fault tolerant netware but does for the rest.
311 */
312 if (*(unsigned short *) rawp == 0xFFFF)
313 return htons(ETH_P_802_3);
314
315 /*
316 * Real 802.2 LLC
317 */
318 return htons(ETH_P_802_2);
319}
320#endif /* FASTER_VERSION */
321 220
322/* 221/*
323 * We remember when the MAC gets set, so we don't override it later with 222 * We remember when the MAC gets set, so we don't override it later with
@@ -448,17 +347,8 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
448 return; 347 return;
449 } 348 }
450 349
451#ifdef FASTER_VERSION
452 /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier,
453 than should be. What else should I set? */
454 skb_pull(skb, plen);
455 skb_set_mac_header(skb, -ETH_HLEN);
456 skb->pkt_type = PACKET_HOST;
457 skb->protocol = br_type_trans(skb, net_dev);
458#else
459 skb_pull(skb, plen - ETH_HLEN); 350 skb_pull(skb, plen - ETH_HLEN);
460 skb->protocol = eth_type_trans(skb, net_dev); 351 skb->protocol = eth_type_trans(skb, net_dev);
461#endif /* FASTER_VERSION */
462#ifdef CONFIG_ATM_BR2684_IPFILTER 352#ifdef CONFIG_ATM_BR2684_IPFILTER
463 if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) { 353 if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
464 brdev->stats.rx_dropped++; 354 brdev->stats.rx_dropped++;
@@ -584,13 +474,6 @@ static void br2684_setup(struct net_device *netdev)
584 ether_setup(netdev); 474 ether_setup(netdev);
585 brdev->net_dev = netdev; 475 brdev->net_dev = netdev;
586 476
587#ifdef FASTER_VERSION
588 my_eth_header = netdev->hard_header;
589 netdev->hard_header = br2684_header;
590 my_eth_header_cache = netdev->hard_header_cache;
591 netdev->hard_header_cache = br2684_header_cache;
592 netdev->hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN; /* 10 + 14 */
593#endif
594 my_eth_mac_addr = netdev->set_mac_address; 477 my_eth_mac_addr = netdev->set_mac_address;
595 netdev->set_mac_address = br2684_mac_addr; 478 netdev->set_mac_address = br2684_mac_addr;
596 netdev->hard_start_xmit = br2684_start_xmit; 479 netdev->hard_start_xmit = br2684_start_xmit;
@@ -719,16 +602,12 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
719 602
720 list_for_each_entry(brvcc, &brdev->brvccs, brvccs) { 603 list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
721 seq_printf(seq, " vcc %d.%d.%d: encaps=%s" 604 seq_printf(seq, " vcc %d.%d.%d: encaps=%s"
722#ifndef FASTER_VERSION
723 ", failed copies %u/%u" 605 ", failed copies %u/%u"
724#endif /* FASTER_VERSION */
725 "\n", brvcc->atmvcc->dev->number, 606 "\n", brvcc->atmvcc->dev->number,
726 brvcc->atmvcc->vpi, brvcc->atmvcc->vci, 607 brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
727 (brvcc->encaps == e_llc) ? "LLC" : "VC" 608 (brvcc->encaps == e_llc) ? "LLC" : "VC"
728#ifndef FASTER_VERSION
729 , brvcc->copies_failed 609 , brvcc->copies_failed
730 , brvcc->copies_needed 610 , brvcc->copies_needed
731#endif /* FASTER_VERSION */
732 ); 611 );
733#ifdef CONFIG_ATM_BR2684_IPFILTER 612#ifdef CONFIG_ATM_BR2684_IPFILTER
734#define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] 613#define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte]
diff --git a/net/core/filter.c b/net/core/filter.c
index bd903aaf7aa7..1f0068eae501 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -387,6 +387,25 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
387} 387}
388 388
389/** 389/**
390 * sk_filter_rcu_release: Release a socket filter by rcu_head
391 * @rcu: rcu_head that contains the sk_filter to free
392 */
393static void sk_filter_rcu_release(struct rcu_head *rcu)
394{
395 struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
396
397 sk_filter_release(fp);
398}
399
400static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
401{
402 unsigned int size = sk_filter_len(fp);
403
404 atomic_sub(size, &sk->sk_omem_alloc);
405 call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
406}
407
408/**
390 * sk_attach_filter - attach a socket filter 409 * sk_attach_filter - attach a socket filter
391 * @fprog: the filter program 410 * @fprog: the filter program
392 * @sk: the socket to use 411 * @sk: the socket to use
@@ -398,7 +417,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
398 */ 417 */
399int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) 418int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
400{ 419{
401 struct sk_filter *fp; 420 struct sk_filter *fp, *old_fp;
402 unsigned int fsize = sizeof(struct sock_filter) * fprog->len; 421 unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
403 int err; 422 int err;
404 423
@@ -418,19 +437,34 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
418 fp->len = fprog->len; 437 fp->len = fprog->len;
419 438
420 err = sk_chk_filter(fp->insns, fp->len); 439 err = sk_chk_filter(fp->insns, fp->len);
421 if (!err) { 440 if (err) {
422 struct sk_filter *old_fp; 441 sk_filter_uncharge(sk, fp);
423 442 return err;
424 rcu_read_lock_bh();
425 old_fp = rcu_dereference(sk->sk_filter);
426 rcu_assign_pointer(sk->sk_filter, fp);
427 rcu_read_unlock_bh();
428 fp = old_fp;
429 } 443 }
430 444
431 if (fp) 445 rcu_read_lock_bh();
432 sk_filter_release(sk, fp); 446 old_fp = rcu_dereference(sk->sk_filter);
433 return err; 447 rcu_assign_pointer(sk->sk_filter, fp);
448 rcu_read_unlock_bh();
449
450 sk_filter_delayed_uncharge(sk, old_fp);
451 return 0;
452}
453
454int sk_detach_filter(struct sock *sk)
455{
456 int ret = -ENOENT;
457 struct sk_filter *filter;
458
459 rcu_read_lock_bh();
460 filter = rcu_dereference(sk->sk_filter);
461 if (filter) {
462 rcu_assign_pointer(sk->sk_filter, NULL);
463 sk_filter_delayed_uncharge(sk, filter);
464 ret = 0;
465 }
466 rcu_read_unlock_bh();
467 return ret;
434} 468}
435 469
436EXPORT_SYMBOL(sk_chk_filter); 470EXPORT_SYMBOL(sk_chk_filter);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 2100c734b102..8cae60c53383 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2454,7 +2454,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
2454 spin_lock(&x->lock); 2454 spin_lock(&x->lock);
2455 iph = ip_hdr(skb); 2455 iph = ip_hdr(skb);
2456 2456
2457 err = x->mode->output(x, skb); 2457 err = x->outer_mode->output(x, skb);
2458 if (err) 2458 if (err)
2459 goto error; 2459 goto error;
2460 err = x->type->output(x, skb); 2460 err = x->type->output(x, skb);
diff --git a/net/core/sock.c b/net/core/sock.c
index d45ecdccc6a1..d292b4113d6e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -428,7 +428,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
428 char __user *optval, int optlen) 428 char __user *optval, int optlen)
429{ 429{
430 struct sock *sk=sock->sk; 430 struct sock *sk=sock->sk;
431 struct sk_filter *filter;
432 int val; 431 int val;
433 int valbool; 432 int valbool;
434 struct linger ling; 433 struct linger ling;
@@ -652,16 +651,7 @@ set_rcvbuf:
652 break; 651 break;
653 652
654 case SO_DETACH_FILTER: 653 case SO_DETACH_FILTER:
655 rcu_read_lock_bh(); 654 ret = sk_detach_filter(sk);
656 filter = rcu_dereference(sk->sk_filter);
657 if (filter) {
658 rcu_assign_pointer(sk->sk_filter, NULL);
659 sk_filter_release(sk, filter);
660 rcu_read_unlock_bh();
661 break;
662 }
663 rcu_read_unlock_bh();
664 ret = -ENONET;
665 break; 655 break;
666 656
667 case SO_PASSSEC: 657 case SO_PASSSEC:
@@ -925,7 +915,7 @@ void sk_free(struct sock *sk)
925 915
926 filter = rcu_dereference(sk->sk_filter); 916 filter = rcu_dereference(sk->sk_filter);
927 if (filter) { 917 if (filter) {
928 sk_filter_release(sk, filter); 918 sk_filter_uncharge(sk, filter);
929 rcu_assign_pointer(sk->sk_filter, NULL); 919 rcu_assign_pointer(sk->sk_filter, NULL);
930 } 920 }
931 921
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 19d7e1dbd87e..3560a2a875a0 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -19,6 +19,9 @@
19#include "ccid.h" 19#include "ccid.h"
20#include "dccp.h" 20#include "dccp.h"
21 21
22/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
23int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
24
22static void dccp_fin(struct sock *sk, struct sk_buff *skb) 25static void dccp_fin(struct sock *sk, struct sk_buff *skb)
23{ 26{
24 sk->sk_shutdown |= RCV_SHUTDOWN; 27 sk->sk_shutdown |= RCV_SHUTDOWN;
diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c
index 9364b2fb4dbd..c62c05039f69 100644
--- a/net/dccp/sysctl.c
+++ b/net/dccp/sysctl.c
@@ -18,9 +18,6 @@
18#error This file should not be compiled without CONFIG_SYSCTL defined 18#error This file should not be compiled without CONFIG_SYSCTL defined
19#endif 19#endif
20 20
21/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
22int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
23
24static struct ctl_table dccp_default_table[] = { 21static struct ctl_table dccp_default_table[] = {
25 { 22 {
26 .procname = "seq_window", 23 .procname = "seq_window",
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54eeca3ed..72e6ab66834f 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -586,7 +586,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
586 if (stype & IEEE80211_STYPE_QOS_DATA) { 586 if (stype & IEEE80211_STYPE_QOS_DATA) {
587 const struct ieee80211_hdr_3addrqos *qoshdr = 587 const struct ieee80211_hdr_3addrqos *qoshdr =
588 (struct ieee80211_hdr_3addrqos *)skb->data; 588 (struct ieee80211_hdr_3addrqos *)skb->data;
589 hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID); 589 hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
590 } else 590 } else
591 hdr[12] = 0; /* priority */ 591 hdr[12] = 0; /* priority */
592 592
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 484cf512858f..e15e04fc6661 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -136,7 +136,9 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
136 *work -= f->qsize; 136 *work -= f->qsize;
137 atomic_sub(f->qsize, &f->mem); 137 atomic_sub(f->qsize, &f->mem);
138 138
139 f->destructor(q); 139 if (f->destructor)
140 f->destructor(q);
141 kfree(q);
140 142
141} 143}
142EXPORT_SYMBOL(inet_frag_destroy); 144EXPORT_SYMBOL(inet_frag_destroy);
@@ -172,3 +174,88 @@ int inet_frag_evictor(struct inet_frags *f)
172 return evicted; 174 return evicted;
173} 175}
174EXPORT_SYMBOL(inet_frag_evictor); 176EXPORT_SYMBOL(inet_frag_evictor);
177
178static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
179 struct inet_frags *f, unsigned int hash, void *arg)
180{
181 struct inet_frag_queue *qp;
182#ifdef CONFIG_SMP
183 struct hlist_node *n;
184#endif
185
186 write_lock(&f->lock);
187#ifdef CONFIG_SMP
188 /* With SMP race we have to recheck hash table, because
189 * such entry could be created on other cpu, while we
190 * promoted read lock to write lock.
191 */
192 hlist_for_each_entry(qp, n, &f->hash[hash], list) {
193 if (f->match(qp, arg)) {
194 atomic_inc(&qp->refcnt);
195 write_unlock(&f->lock);
196 qp_in->last_in |= COMPLETE;
197 inet_frag_put(qp_in, f);
198 return qp;
199 }
200 }
201#endif
202 qp = qp_in;
203 if (!mod_timer(&qp->timer, jiffies + f->ctl->timeout))
204 atomic_inc(&qp->refcnt);
205
206 atomic_inc(&qp->refcnt);
207 hlist_add_head(&qp->list, &f->hash[hash]);
208 list_add_tail(&qp->lru_list, &f->lru_list);
209 f->nqueues++;
210 write_unlock(&f->lock);
211 return qp;
212}
213
214static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
215{
216 struct inet_frag_queue *q;
217
218 q = kzalloc(f->qsize, GFP_ATOMIC);
219 if (q == NULL)
220 return NULL;
221
222 f->constructor(q, arg);
223 atomic_add(f->qsize, &f->mem);
224 setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
225 spin_lock_init(&q->lock);
226 atomic_set(&q->refcnt, 1);
227
228 return q;
229}
230
231static struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
232 void *arg, unsigned int hash)
233{
234 struct inet_frag_queue *q;
235
236 q = inet_frag_alloc(f, arg);
237 if (q == NULL)
238 return NULL;
239
240 return inet_frag_intern(q, f, hash, arg);
241}
242
243struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
244 unsigned int hash)
245{
246 struct inet_frag_queue *q;
247 struct hlist_node *n;
248
249 read_lock(&f->lock);
250 hlist_for_each_entry(q, n, &f->hash[hash], list) {
251 if (f->match(q, key)) {
252 atomic_inc(&q->refcnt);
253 read_unlock(&f->lock);
254 return q;
255 }
256 }
257 read_unlock(&f->lock);
258
259 return inet_frag_create(f, key, hash);
260}
261EXPORT_SYMBOL(inet_frag_find);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 443b3f89192f..2143bf30597a 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -108,6 +108,11 @@ int ip_frag_mem(void)
108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, 108static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
109 struct net_device *dev); 109 struct net_device *dev);
110 110
111struct ip4_create_arg {
112 struct iphdr *iph;
113 u32 user;
114};
115
111static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) 116static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
112{ 117{
113 return jhash_3words((__force u32)id << 16 | prot, 118 return jhash_3words((__force u32)id << 16 | prot,
@@ -123,6 +128,19 @@ static unsigned int ip4_hashfn(struct inet_frag_queue *q)
123 return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol); 128 return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
124} 129}
125 130
131static int ip4_frag_match(struct inet_frag_queue *q, void *a)
132{
133 struct ipq *qp;
134 struct ip4_create_arg *arg = a;
135
136 qp = container_of(q, struct ipq, q);
137 return (qp->id == arg->iph->id &&
138 qp->saddr == arg->iph->saddr &&
139 qp->daddr == arg->iph->daddr &&
140 qp->protocol == arg->iph->protocol &&
141 qp->user == arg->user);
142}
143
126/* Memory Tracking Functions. */ 144/* Memory Tracking Functions. */
127static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) 145static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
128{ 146{
@@ -132,6 +150,20 @@ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
132 kfree_skb(skb); 150 kfree_skb(skb);
133} 151}
134 152
153static void ip4_frag_init(struct inet_frag_queue *q, void *a)
154{
155 struct ipq *qp = container_of(q, struct ipq, q);
156 struct ip4_create_arg *arg = a;
157
158 qp->protocol = arg->iph->protocol;
159 qp->id = arg->iph->id;
160 qp->saddr = arg->iph->saddr;
161 qp->daddr = arg->iph->daddr;
162 qp->user = arg->user;
163 qp->peer = sysctl_ipfrag_max_dist ?
164 inet_getpeer(arg->iph->saddr, 1) : NULL;
165}
166
135static __inline__ void ip4_frag_free(struct inet_frag_queue *q) 167static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
136{ 168{
137 struct ipq *qp; 169 struct ipq *qp;
@@ -139,17 +171,6 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
139 qp = container_of(q, struct ipq, q); 171 qp = container_of(q, struct ipq, q);
140 if (qp->peer) 172 if (qp->peer)
141 inet_putpeer(qp->peer); 173 inet_putpeer(qp->peer);
142 kfree(qp);
143}
144
145static __inline__ struct ipq *frag_alloc_queue(void)
146{
147 struct ipq *qp = kzalloc(sizeof(struct ipq), GFP_ATOMIC);
148
149 if (!qp)
150 return NULL;
151 atomic_add(sizeof(struct ipq), &ip4_frags.mem);
152 return qp;
153} 174}
154 175
155 176
@@ -185,7 +206,9 @@ static void ip_evictor(void)
185 */ 206 */
186static void ip_expire(unsigned long arg) 207static void ip_expire(unsigned long arg)
187{ 208{
188 struct ipq *qp = (struct ipq *) arg; 209 struct ipq *qp;
210
211 qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
189 212
190 spin_lock(&qp->q.lock); 213 spin_lock(&qp->q.lock);
191 214
@@ -210,112 +233,30 @@ out:
210 ipq_put(qp); 233 ipq_put(qp);
211} 234}
212 235
213/* Creation primitives. */ 236/* Find the correct entry in the "incomplete datagrams" queue for
214 237 * this IP datagram, and create new one, if nothing is found.
215static struct ipq *ip_frag_intern(struct ipq *qp_in) 238 */
239static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
216{ 240{
217 struct ipq *qp; 241 struct inet_frag_queue *q;
218#ifdef CONFIG_SMP 242 struct ip4_create_arg arg;
219 struct hlist_node *n;
220#endif
221 unsigned int hash; 243 unsigned int hash;
222 244
223 write_lock(&ip4_frags.lock); 245 arg.iph = iph;
224 hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr, 246 arg.user = user;
225 qp_in->protocol); 247 hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
226#ifdef CONFIG_SMP
227 /* With SMP race we have to recheck hash table, because
228 * such entry could be created on other cpu, while we
229 * promoted read lock to write lock.
230 */
231 hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
232 if (qp->id == qp_in->id &&
233 qp->saddr == qp_in->saddr &&
234 qp->daddr == qp_in->daddr &&
235 qp->protocol == qp_in->protocol &&
236 qp->user == qp_in->user) {
237 atomic_inc(&qp->q.refcnt);
238 write_unlock(&ip4_frags.lock);
239 qp_in->q.last_in |= COMPLETE;
240 ipq_put(qp_in);
241 return qp;
242 }
243 }
244#endif
245 qp = qp_in;
246
247 if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout))
248 atomic_inc(&qp->q.refcnt);
249 248
250 atomic_inc(&qp->q.refcnt); 249 q = inet_frag_find(&ip4_frags, &arg, hash);
251 hlist_add_head(&qp->q.list, &ip4_frags.hash[hash]); 250 if (q == NULL)
252 INIT_LIST_HEAD(&qp->q.lru_list);
253 list_add_tail(&qp->q.lru_list, &ip4_frags.lru_list);
254 ip4_frags.nqueues++;
255 write_unlock(&ip4_frags.lock);
256 return qp;
257}
258
259/* Add an entry to the 'ipq' queue for a newly received IP datagram. */
260static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
261{
262 struct ipq *qp;
263
264 if ((qp = frag_alloc_queue()) == NULL)
265 goto out_nomem; 251 goto out_nomem;
266 252
267 qp->protocol = iph->protocol; 253 return container_of(q, struct ipq, q);
268 qp->id = iph->id;
269 qp->saddr = iph->saddr;
270 qp->daddr = iph->daddr;
271 qp->user = user;
272 qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
273
274 /* Initialize a timer for this entry. */
275 init_timer(&qp->q.timer);
276 qp->q.timer.data = (unsigned long) qp; /* pointer to queue */
277 qp->q.timer.function = ip_expire; /* expire function */
278 spin_lock_init(&qp->q.lock);
279 atomic_set(&qp->q.refcnt, 1);
280
281 return ip_frag_intern(qp);
282 254
283out_nomem: 255out_nomem:
284 LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); 256 LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
285 return NULL; 257 return NULL;
286} 258}
287 259
288/* Find the correct entry in the "incomplete datagrams" queue for
289 * this IP datagram, and create new one, if nothing is found.
290 */
291static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
292{
293 __be16 id = iph->id;
294 __be32 saddr = iph->saddr;
295 __be32 daddr = iph->daddr;
296 __u8 protocol = iph->protocol;
297 unsigned int hash;
298 struct ipq *qp;
299 struct hlist_node *n;
300
301 read_lock(&ip4_frags.lock);
302 hash = ipqhashfn(id, saddr, daddr, protocol);
303 hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
304 if (qp->id == id &&
305 qp->saddr == saddr &&
306 qp->daddr == daddr &&
307 qp->protocol == protocol &&
308 qp->user == user) {
309 atomic_inc(&qp->q.refcnt);
310 read_unlock(&ip4_frags.lock);
311 return qp;
312 }
313 }
314 read_unlock(&ip4_frags.lock);
315
316 return ip_frag_create(iph, user);
317}
318
319/* Is the fragment too far ahead to be part of ipq? */ 260/* Is the fragment too far ahead to be part of ipq? */
320static inline int ip_frag_too_far(struct ipq *qp) 261static inline int ip_frag_too_far(struct ipq *qp)
321{ 262{
@@ -545,7 +486,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
545 if (prev) { 486 if (prev) {
546 head = prev->next; 487 head = prev->next;
547 fp = skb_clone(head, GFP_ATOMIC); 488 fp = skb_clone(head, GFP_ATOMIC);
548
549 if (!fp) 489 if (!fp)
550 goto out_nomem; 490 goto out_nomem;
551 491
@@ -571,7 +511,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
571 goto out_oversize; 511 goto out_oversize;
572 512
573 /* Head of list must not be cloned. */ 513 /* Head of list must not be cloned. */
574 err = -ENOMEM;
575 if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) 514 if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
576 goto out_nomem; 515 goto out_nomem;
577 516
@@ -627,6 +566,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
627out_nomem: 566out_nomem:
628 LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing " 567 LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
629 "queue %p\n", qp); 568 "queue %p\n", qp);
569 err = -ENOMEM;
630 goto out_fail; 570 goto out_fail;
631out_oversize: 571out_oversize:
632 if (net_ratelimit()) 572 if (net_ratelimit())
@@ -671,9 +611,12 @@ void __init ipfrag_init(void)
671{ 611{
672 ip4_frags.ctl = &ip4_frags_ctl; 612 ip4_frags.ctl = &ip4_frags_ctl;
673 ip4_frags.hashfn = ip4_hashfn; 613 ip4_frags.hashfn = ip4_hashfn;
614 ip4_frags.constructor = ip4_frag_init;
674 ip4_frags.destructor = ip4_frag_free; 615 ip4_frags.destructor = ip4_frag_free;
675 ip4_frags.skb_free = NULL; 616 ip4_frags.skb_free = NULL;
676 ip4_frags.qsize = sizeof(struct ipq); 617 ip4_frags.qsize = sizeof(struct ipq);
618 ip4_frags.match = ip4_frag_match;
619 ip4_frags.frag_expire = ip_expire;
677 inet_frags_init(&ip4_frags); 620 inet_frags_init(&ip4_frags);
678} 621}
679 622
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0f00966b1784..9288220b73a8 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
1121 struct sk_buff *skb; 1121 struct sk_buff *skb;
1122 int flag = 0; 1122 int flag = 0;
1123 int cnt = 0; 1123 int cnt = 0;
1124 u32 new_low_seq = 0; 1124 u32 new_low_seq = tp->snd_nxt;
1125 1125
1126 tcp_for_write_queue(skb, sk) { 1126 tcp_for_write_queue(skb, sk) {
1127 u32 ack_seq = TCP_SKB_CB(skb)->ack_seq; 1127 u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
@@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
1153 NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT); 1153 NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
1154 } 1154 }
1155 } else { 1155 } else {
1156 if (!new_low_seq || before(ack_seq, new_low_seq)) 1156 if (before(ack_seq, new_low_seq))
1157 new_low_seq = ack_seq; 1157 new_low_seq = ack_seq;
1158 cnt += tcp_skb_pcount(skb); 1158 cnt += tcp_skb_pcount(skb);
1159 } 1159 }
@@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1242 int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3; 1242 int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
1243 int reord = tp->packets_out; 1243 int reord = tp->packets_out;
1244 int prior_fackets; 1244 int prior_fackets;
1245 u32 highest_sack_end_seq = 0; 1245 u32 highest_sack_end_seq = tp->lost_retrans_low;
1246 int flag = 0; 1246 int flag = 0;
1247 int found_dup_sack = 0; 1247 int found_dup_sack = 0;
1248 int cached_fack_count; 1248 int cached_fack_count;
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index e9bbfde19ac3..5e95c8a07efb 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,19 +16,6 @@
16#include <net/ip.h> 16#include <net/ip.h>
17#include <net/xfrm.h> 17#include <net/xfrm.h>
18 18
19static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
20{
21 switch (nexthdr) {
22 case IPPROTO_IPIP:
23 case IPPROTO_IPV6:
24 *spi = ip_hdr(skb)->saddr;
25 *seq = 0;
26 return 0;
27 }
28
29 return xfrm_parse_spi(skb, nexthdr, spi, seq);
30}
31
32#ifdef CONFIG_NETFILTER 19#ifdef CONFIG_NETFILTER
33static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) 20static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
34{ 21{
@@ -46,28 +33,29 @@ drop:
46} 33}
47#endif 34#endif
48 35
49static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) 36int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
37 int encap_type)
50{ 38{
51 __be32 spi, seq; 39 int err;
40 __be32 seq;
52 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 41 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
53 struct xfrm_state *x; 42 struct xfrm_state *x;
54 int xfrm_nr = 0; 43 int xfrm_nr = 0;
55 int decaps = 0; 44 int decaps = 0;
56 int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
57 unsigned int nhoff = offsetof(struct iphdr, protocol); 45 unsigned int nhoff = offsetof(struct iphdr, protocol);
58 46
59 if (err != 0) 47 seq = 0;
48 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
60 goto drop; 49 goto drop;
61 50
62 do { 51 do {
63 const struct iphdr *iph = ip_hdr(skb); 52 const struct iphdr *iph = ip_hdr(skb);
64 int nexthdr;
65 53
66 if (xfrm_nr == XFRM_MAX_DEPTH) 54 if (xfrm_nr == XFRM_MAX_DEPTH)
67 goto drop; 55 goto drop;
68 56
69 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, 57 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
70 iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET); 58 nexthdr, AF_INET);
71 if (x == NULL) 59 if (x == NULL)
72 goto drop; 60 goto drop;
73 61
@@ -103,15 +91,15 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
103 91
104 xfrm_vec[xfrm_nr++] = x; 92 xfrm_vec[xfrm_nr++] = x;
105 93
106 if (x->mode->input(x, skb)) 94 if (x->outer_mode->input(x, skb))
107 goto drop; 95 goto drop;
108 96
109 if (x->props.mode == XFRM_MODE_TUNNEL) { 97 if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
110 decaps = 1; 98 decaps = 1;
111 break; 99 break;
112 } 100 }
113 101
114 err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq); 102 err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
115 if (err < 0) 103 if (err < 0)
116 goto drop; 104 goto drop;
117 } while (!err); 105 } while (!err);
@@ -165,6 +153,7 @@ drop:
165 kfree_skb(skb); 153 kfree_skb(skb);
166 return 0; 154 return 0;
167} 155}
156EXPORT_SYMBOL(xfrm4_rcv_encap);
168 157
169/* If it's a keepalive packet, then just eat it. 158/* If it's a keepalive packet, then just eat it.
170 * If it's an encapsulated packet, then pass it to the 159 * If it's an encapsulated packet, then pass it to the
@@ -252,11 +241,8 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
252 __skb_pull(skb, len); 241 __skb_pull(skb, len);
253 skb_reset_transport_header(skb); 242 skb_reset_transport_header(skb);
254 243
255 /* modify the protocol (it's ESP!) */
256 iph->protocol = IPPROTO_ESP;
257
258 /* process ESP */ 244 /* process ESP */
259 ret = xfrm4_rcv_encap(skb, encap_type); 245 ret = xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
260 return ret; 246 return ret;
261 247
262drop: 248drop:
@@ -266,7 +252,7 @@ drop:
266 252
267int xfrm4_rcv(struct sk_buff *skb) 253int xfrm4_rcv(struct sk_buff *skb)
268{ 254{
269 return xfrm4_rcv_encap(skb, 0); 255 return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
270} 256}
271 257
272EXPORT_SYMBOL(xfrm4_rcv); 258EXPORT_SYMBOL(xfrm4_rcv);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 73d2338bec55..e42e122414be 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -114,6 +114,7 @@ static struct xfrm_mode xfrm4_beet_mode = {
114 .output = xfrm4_beet_output, 114 .output = xfrm4_beet_output,
115 .owner = THIS_MODULE, 115 .owner = THIS_MODULE,
116 .encap = XFRM_MODE_BEET, 116 .encap = XFRM_MODE_BEET,
117 .flags = XFRM_MODE_FLAG_TUNNEL,
117}; 118};
118 119
119static int __init xfrm4_beet_init(void) 120static int __init xfrm4_beet_init(void)
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 1ae9d32276f0..e4deecba6dd2 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -139,6 +139,7 @@ static struct xfrm_mode xfrm4_tunnel_mode = {
139 .output = xfrm4_tunnel_output, 139 .output = xfrm4_tunnel_output,
140 .owner = THIS_MODULE, 140 .owner = THIS_MODULE,
141 .encap = XFRM_MODE_TUNNEL, 141 .encap = XFRM_MODE_TUNNEL,
142 .flags = XFRM_MODE_FLAG_TUNNEL,
142}; 143};
143 144
144static int __init xfrm4_tunnel_init(void) 145static int __init xfrm4_tunnel_init(void)
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index a4edd666318b..c4a7156962bd 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -47,7 +47,7 @@ static inline int xfrm4_output_one(struct sk_buff *skb)
47 struct iphdr *iph; 47 struct iphdr *iph;
48 int err; 48 int err;
49 49
50 if (x->props.mode == XFRM_MODE_TUNNEL) { 50 if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
51 err = xfrm4_tunnel_check_size(skb); 51 err = xfrm4_tunnel_check_size(skb);
52 if (err) 52 if (err)
53 goto error_nolock; 53 goto error_nolock;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 329825ca68fe..cc86fb110dd8 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -117,7 +117,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
117 header_len += xfrm[i]->props.header_len; 117 header_len += xfrm[i]->props.header_len;
118 trailer_len += xfrm[i]->props.trailer_len; 118 trailer_len += xfrm[i]->props.trailer_len;
119 119
120 if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) { 120 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
121 unsigned short encap_family = xfrm[i]->props.family; 121 unsigned short encap_family = xfrm[i]->props.family;
122 switch (encap_family) { 122 switch (encap_family) {
123 case AF_INET: 123 case AF_INET:
@@ -151,7 +151,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
151 i = 0; 151 i = 0;
152 for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { 152 for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
153 struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; 153 struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
154 struct xfrm_state_afinfo *afinfo;
155 x->u.rt.fl = *fl; 154 x->u.rt.fl = *fl;
156 155
157 dst_prev->xfrm = xfrm[i++]; 156 dst_prev->xfrm = xfrm[i++];
@@ -169,27 +168,17 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
169 /* Copy neighbout for reachability confirmation */ 168 /* Copy neighbout for reachability confirmation */
170 dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); 169 dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
171 dst_prev->input = rt->u.dst.input; 170 dst_prev->input = rt->u.dst.input;
172 /* XXX: When IPv6 module can be unloaded, we should manage reference 171 dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
173 * to xfrm6_output in afinfo->output. Miyazawa 172 if (rt0->peer)
174 * */ 173 atomic_inc(&rt0->peer->refcnt);
175 afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family); 174 x->u.rt.peer = rt0->peer;
176 if (!afinfo) {
177 dst = *dst_p;
178 err = -EAFNOSUPPORT;
179 goto error;
180 }
181 dst_prev->output = afinfo->output;
182 xfrm_state_put_afinfo(afinfo);
183 if (dst_prev->xfrm->props.family == AF_INET && rt->peer)
184 atomic_inc(&rt->peer->refcnt);
185 x->u.rt.peer = rt->peer;
186 /* Sheit... I remember I did this right. Apparently, 175 /* Sheit... I remember I did this right. Apparently,
187 * it was magically lost, so this code needs audit */ 176 * it was magically lost, so this code needs audit */
188 x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); 177 x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
189 x->u.rt.rt_type = rt->rt_type; 178 x->u.rt.rt_type = rt0->rt_type;
190 x->u.rt.rt_src = rt0->rt_src; 179 x->u.rt.rt_src = rt0->rt_src;
191 x->u.rt.rt_dst = rt0->rt_dst; 180 x->u.rt.rt_dst = rt0->rt_dst;
192 x->u.rt.rt_gateway = rt->rt_gateway; 181 x->u.rt.rt_gateway = rt0->rt_gateway;
193 x->u.rt.rt_spec_dst = rt0->rt_spec_dst; 182 x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
194 x->u.rt.idev = rt0->idev; 183 x->u.rt.idev = rt0->idev;
195 in_dev_hold(rt0->idev); 184 in_dev_hold(rt0->idev);
@@ -291,7 +280,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
291 280
292 if (likely(xdst->u.rt.idev)) 281 if (likely(xdst->u.rt.idev))
293 in_dev_put(xdst->u.rt.idev); 282 in_dev_put(xdst->u.rt.idev);
294 if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer)) 283 if (likely(xdst->u.rt.peer))
295 inet_putpeer(xdst->u.rt.peer); 284 inet_putpeer(xdst->u.rt.peer);
296 xfrm_dst_destroy(xdst); 285 xfrm_dst_destroy(xdst);
297} 286}
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 93e2c061cdda..13d54a1c3337 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -49,6 +49,7 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
49 49
50static struct xfrm_state_afinfo xfrm4_state_afinfo = { 50static struct xfrm_state_afinfo xfrm4_state_afinfo = {
51 .family = AF_INET, 51 .family = AF_INET,
52 .owner = THIS_MODULE,
52 .init_flags = xfrm4_init_flags, 53 .init_flags = xfrm4_init_flags,
53 .init_tempsel = __xfrm4_init_tempsel, 54 .init_tempsel = __xfrm4_init_tempsel,
54 .output = xfrm4_output, 55 .output = xfrm4_output,
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 1312417608e2..326845195620 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
18 18
19static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) 19static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
20{ 20{
21 return IPPROTO_IP; 21 return ip_hdr(skb)->protocol;
22} 22}
23 23
24static int ipip_init_state(struct xfrm_state *x) 24static int ipip_init_state(struct xfrm_state *x)
@@ -48,20 +48,25 @@ static struct xfrm_type ipip_type = {
48 .output = ipip_output 48 .output = ipip_output
49}; 49};
50 50
51static int xfrm_tunnel_rcv(struct sk_buff *skb)
52{
53 return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
54}
55
51static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) 56static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
52{ 57{
53 return -ENOENT; 58 return -ENOENT;
54} 59}
55 60
56static struct xfrm_tunnel xfrm_tunnel_handler = { 61static struct xfrm_tunnel xfrm_tunnel_handler = {
57 .handler = xfrm4_rcv, 62 .handler = xfrm_tunnel_rcv,
58 .err_handler = xfrm_tunnel_err, 63 .err_handler = xfrm_tunnel_err,
59 .priority = 2, 64 .priority = 2,
60}; 65};
61 66
62#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 67#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
63static struct xfrm_tunnel xfrm64_tunnel_handler = { 68static struct xfrm_tunnel xfrm64_tunnel_handler = {
64 .handler = xfrm4_rcv, 69 .handler = xfrm_tunnel_rcv,
65 .err_handler = xfrm_tunnel_err, 70 .err_handler = xfrm_tunnel_err,
66 .priority = 2, 71 .priority = 2,
67}; 72};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 52d10d213217..348bd8d06112 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -255,11 +255,6 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
255 255
256static int snmp6_alloc_dev(struct inet6_dev *idev) 256static int snmp6_alloc_dev(struct inet6_dev *idev)
257{ 257{
258 int err = -ENOMEM;
259
260 if (!idev || !idev->dev)
261 return -EINVAL;
262
263 if (snmp_mib_init((void **)idev->stats.ipv6, 258 if (snmp_mib_init((void **)idev->stats.ipv6,
264 sizeof(struct ipstats_mib), 259 sizeof(struct ipstats_mib),
265 __alignof__(struct ipstats_mib)) < 0) 260 __alignof__(struct ipstats_mib)) < 0)
@@ -280,15 +275,14 @@ err_icmpmsg:
280err_icmp: 275err_icmp:
281 snmp_mib_free((void **)idev->stats.ipv6); 276 snmp_mib_free((void **)idev->stats.ipv6);
282err_ip: 277err_ip:
283 return err; 278 return -ENOMEM;
284} 279}
285 280
286static int snmp6_free_dev(struct inet6_dev *idev) 281static void snmp6_free_dev(struct inet6_dev *idev)
287{ 282{
288 snmp_mib_free((void **)idev->stats.icmpv6msg); 283 snmp_mib_free((void **)idev->stats.icmpv6msg);
289 snmp_mib_free((void **)idev->stats.icmpv6); 284 snmp_mib_free((void **)idev->stats.icmpv6);
290 snmp_mib_free((void **)idev->stats.ipv6); 285 snmp_mib_free((void **)idev->stats.ipv6);
291 return 0;
292} 286}
293 287
294/* Nobody refers to this device, we may destroy it. */ 288/* Nobody refers to this device, we may destroy it. */
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index bc929381fa46..1b1caf3aa1c1 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -747,6 +747,7 @@ static void cleanup_ipv6_mibs(void)
747{ 747{
748 snmp_mib_free((void **)ipv6_statistics); 748 snmp_mib_free((void **)ipv6_statistics);
749 snmp_mib_free((void **)icmpv6_statistics); 749 snmp_mib_free((void **)icmpv6_statistics);
750 snmp_mib_free((void **)icmpv6msg_statistics);
750 snmp_mib_free((void **)udp_stats_in6); 751 snmp_mib_free((void **)udp_stats_in6);
751 snmp_mib_free((void **)udplite_stats_in6); 752 snmp_mib_free((void **)udplite_stats_in6);
752} 753}
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index f9f689162692..67cd06613a25 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -344,6 +344,8 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
344 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 344 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
345 goto out; 345 goto out;
346 346
347 skb->ip_summed = CHECKSUM_NONE;
348
347 hdr_len = skb->data - skb_network_header(skb); 349 hdr_len = skb->data - skb_network_header(skb);
348 ah = (struct ip_auth_hdr *)skb->data; 350 ah = (struct ip_auth_hdr *)skb->data;
349 ahp = x->data; 351 ahp = x->data;
@@ -475,8 +477,15 @@ static int ah6_init_state(struct xfrm_state *x)
475 477
476 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 478 x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
477 ahp->icv_trunc_len); 479 ahp->icv_trunc_len);
478 if (x->props.mode == XFRM_MODE_TUNNEL) 480 switch (x->props.mode) {
481 case XFRM_MODE_BEET:
482 case XFRM_MODE_TRANSPORT:
483 break;
484 case XFRM_MODE_TUNNEL:
479 x->props.header_len += sizeof(struct ipv6hdr); 485 x->props.header_len += sizeof(struct ipv6hdr);
486 default:
487 goto error;
488 }
480 x->data = ahp; 489 x->data = ahp;
481 490
482 return 0; 491 return 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 9eb928598351..b0715432e454 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -354,8 +354,15 @@ static int esp6_init_state(struct xfrm_state *x)
354 (x->ealg->alg_key_len + 7) / 8)) 354 (x->ealg->alg_key_len + 7) / 8))
355 goto error; 355 goto error;
356 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; 356 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
357 if (x->props.mode == XFRM_MODE_TUNNEL) 357 switch (x->props.mode) {
358 case XFRM_MODE_BEET:
359 case XFRM_MODE_TRANSPORT:
360 break;
361 case XFRM_MODE_TUNNEL:
358 x->props.header_len += sizeof(struct ipv6hdr); 362 x->props.header_len += sizeof(struct ipv6hdr);
363 default:
364 goto error;
365 }
359 x->data = esp; 366 x->data = esp;
360 return 0; 367 return 0;
361 368
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 217d60f9fc80..b12cc22e7745 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -154,8 +154,10 @@ static void ip6_fl_gc(unsigned long dummy)
154 write_unlock(&ip6_fl_lock); 154 write_unlock(&ip6_fl_lock);
155} 155}
156 156
157static int fl_intern(struct ip6_flowlabel *fl, __be32 label) 157static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label)
158{ 158{
159 struct ip6_flowlabel *lfl;
160
159 fl->label = label & IPV6_FLOWLABEL_MASK; 161 fl->label = label & IPV6_FLOWLABEL_MASK;
160 162
161 write_lock_bh(&ip6_fl_lock); 163 write_lock_bh(&ip6_fl_lock);
@@ -163,12 +165,26 @@ static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
163 for (;;) { 165 for (;;) {
164 fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK; 166 fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK;
165 if (fl->label) { 167 if (fl->label) {
166 struct ip6_flowlabel *lfl;
167 lfl = __fl_lookup(fl->label); 168 lfl = __fl_lookup(fl->label);
168 if (lfl == NULL) 169 if (lfl == NULL)
169 break; 170 break;
170 } 171 }
171 } 172 }
173 } else {
174 /*
175 * we dropper the ip6_fl_lock, so this entry could reappear
176 * and we need to recheck with it.
177 *
178 * OTOH no need to search the active socket first, like it is
179 * done in ipv6_flowlabel_opt - sock is locked, so new entry
180 * with the same label can only appear on another sock
181 */
182 lfl = __fl_lookup(fl->label);
183 if (lfl != NULL) {
184 atomic_inc(&lfl->users);
185 write_unlock_bh(&ip6_fl_lock);
186 return lfl;
187 }
172 } 188 }
173 189
174 fl->lastuse = jiffies; 190 fl->lastuse = jiffies;
@@ -176,7 +192,7 @@ static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
176 fl_ht[FL_HASH(fl->label)] = fl; 192 fl_ht[FL_HASH(fl->label)] = fl;
177 atomic_inc(&fl_size); 193 atomic_inc(&fl_size);
178 write_unlock_bh(&ip6_fl_lock); 194 write_unlock_bh(&ip6_fl_lock);
179 return 0; 195 return NULL;
180} 196}
181 197
182 198
@@ -190,14 +206,17 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label)
190 206
191 label &= IPV6_FLOWLABEL_MASK; 207 label &= IPV6_FLOWLABEL_MASK;
192 208
209 read_lock_bh(&ip6_sk_fl_lock);
193 for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) { 210 for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) {
194 struct ip6_flowlabel *fl = sfl->fl; 211 struct ip6_flowlabel *fl = sfl->fl;
195 if (fl->label == label) { 212 if (fl->label == label) {
196 fl->lastuse = jiffies; 213 fl->lastuse = jiffies;
197 atomic_inc(&fl->users); 214 atomic_inc(&fl->users);
215 read_unlock_bh(&ip6_sk_fl_lock);
198 return fl; 216 return fl;
199 } 217 }
200 } 218 }
219 read_unlock_bh(&ip6_sk_fl_lock);
201 return NULL; 220 return NULL;
202} 221}
203 222
@@ -409,6 +428,16 @@ static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2)
409 return 0; 428 return 0;
410} 429}
411 430
431static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
432 struct ip6_flowlabel *fl)
433{
434 write_lock_bh(&ip6_sk_fl_lock);
435 sfl->fl = fl;
436 sfl->next = np->ipv6_fl_list;
437 np->ipv6_fl_list = sfl;
438 write_unlock_bh(&ip6_sk_fl_lock);
439}
440
412int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) 441int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
413{ 442{
414 int err; 443 int err;
@@ -416,7 +445,8 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
416 struct in6_flowlabel_req freq; 445 struct in6_flowlabel_req freq;
417 struct ipv6_fl_socklist *sfl1=NULL; 446 struct ipv6_fl_socklist *sfl1=NULL;
418 struct ipv6_fl_socklist *sfl, **sflp; 447 struct ipv6_fl_socklist *sfl, **sflp;
419 struct ip6_flowlabel *fl; 448 struct ip6_flowlabel *fl, *fl1 = NULL;
449
420 450
421 if (optlen < sizeof(freq)) 451 if (optlen < sizeof(freq))
422 return -EINVAL; 452 return -EINVAL;
@@ -472,8 +502,6 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
472 sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL); 502 sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
473 503
474 if (freq.flr_label) { 504 if (freq.flr_label) {
475 struct ip6_flowlabel *fl1 = NULL;
476
477 err = -EEXIST; 505 err = -EEXIST;
478 read_lock_bh(&ip6_sk_fl_lock); 506 read_lock_bh(&ip6_sk_fl_lock);
479 for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) { 507 for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) {
@@ -492,6 +520,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
492 if (fl1 == NULL) 520 if (fl1 == NULL)
493 fl1 = fl_lookup(freq.flr_label); 521 fl1 = fl_lookup(freq.flr_label);
494 if (fl1) { 522 if (fl1) {
523recheck:
495 err = -EEXIST; 524 err = -EEXIST;
496 if (freq.flr_flags&IPV6_FL_F_EXCL) 525 if (freq.flr_flags&IPV6_FL_F_EXCL)
497 goto release; 526 goto release;
@@ -513,11 +542,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
513 fl1->linger = fl->linger; 542 fl1->linger = fl->linger;
514 if ((long)(fl->expires - fl1->expires) > 0) 543 if ((long)(fl->expires - fl1->expires) > 0)
515 fl1->expires = fl->expires; 544 fl1->expires = fl->expires;
516 write_lock_bh(&ip6_sk_fl_lock); 545 fl_link(np, sfl1, fl1);
517 sfl1->fl = fl1;
518 sfl1->next = np->ipv6_fl_list;
519 np->ipv6_fl_list = sfl1;
520 write_unlock_bh(&ip6_sk_fl_lock);
521 fl_free(fl); 546 fl_free(fl);
522 return 0; 547 return 0;
523 548
@@ -534,9 +559,9 @@ release:
534 if (sfl1 == NULL || (err = mem_check(sk)) != 0) 559 if (sfl1 == NULL || (err = mem_check(sk)) != 0)
535 goto done; 560 goto done;
536 561
537 err = fl_intern(fl, freq.flr_label); 562 fl1 = fl_intern(fl, freq.flr_label);
538 if (err) 563 if (fl1 != NULL)
539 goto done; 564 goto recheck;
540 565
541 if (!freq.flr_label) { 566 if (!freq.flr_label) {
542 if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, 567 if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
@@ -545,9 +570,7 @@ release:
545 } 570 }
546 } 571 }
547 572
548 sfl1->fl = fl; 573 fl_link(np, sfl1, fl);
549 sfl1->next = np->ipv6_fl_list;
550 np->ipv6_fl_list = sfl1;
551 return 0; 574 return 0;
552 575
553 default: 576 default:
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 28fc8edfdc3a..80ef2a1d39fd 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -411,8 +411,15 @@ static int ipcomp6_init_state(struct xfrm_state *x)
411 goto out; 411 goto out;
412 412
413 x->props.header_len = 0; 413 x->props.header_len = 0;
414 if (x->props.mode == XFRM_MODE_TUNNEL) 414 switch (x->props.mode) {
415 case XFRM_MODE_BEET:
416 case XFRM_MODE_TRANSPORT:
417 break;
418 case XFRM_MODE_TUNNEL:
415 x->props.header_len += sizeof(struct ipv6hdr); 419 x->props.header_len += sizeof(struct ipv6hdr);
420 default:
421 goto error;
422 }
416 423
417 mutex_lock(&ipcomp6_resource_mutex); 424 mutex_lock(&ipcomp6_resource_mutex);
418 if (!ipcomp6_alloc_scratches()) 425 if (!ipcomp6_alloc_scratches())
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 726fafd41961..e170c67c47a5 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -130,22 +130,6 @@ static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
130 kfree_skb(skb); 130 kfree_skb(skb);
131} 131}
132 132
133static void nf_frag_free(struct inet_frag_queue *q)
134{
135 kfree(container_of(q, struct nf_ct_frag6_queue, q));
136}
137
138static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
139{
140 struct nf_ct_frag6_queue *fq;
141
142 fq = kzalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
143 if (fq == NULL)
144 return NULL;
145 atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_frags.mem);
146 return fq;
147}
148
149/* Destruction primitives. */ 133/* Destruction primitives. */
150 134
151static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) 135static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
@@ -168,7 +152,10 @@ static void nf_ct_frag6_evictor(void)
168 152
169static void nf_ct_frag6_expire(unsigned long data) 153static void nf_ct_frag6_expire(unsigned long data)
170{ 154{
171 struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data; 155 struct nf_ct_frag6_queue *fq;
156
157 fq = container_of((struct inet_frag_queue *)data,
158 struct nf_ct_frag6_queue, q);
172 159
173 spin_lock(&fq->q.lock); 160 spin_lock(&fq->q.lock);
174 161
@@ -184,89 +171,29 @@ out:
184 171
185/* Creation primitives. */ 172/* Creation primitives. */
186 173
187static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, 174static __inline__ struct nf_ct_frag6_queue *
188 struct nf_ct_frag6_queue *fq_in) 175fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
189{ 176{
190 struct nf_ct_frag6_queue *fq; 177 struct inet_frag_queue *q;
191#ifdef CONFIG_SMP 178 struct ip6_create_arg arg;
192 struct hlist_node *n; 179 unsigned int hash;
193#endif
194
195 write_lock(&nf_frags.lock);
196#ifdef CONFIG_SMP
197 hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) {
198 if (fq->id == fq_in->id &&
199 ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
200 ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
201 atomic_inc(&fq->q.refcnt);
202 write_unlock(&nf_frags.lock);
203 fq_in->q.last_in |= COMPLETE;
204 fq_put(fq_in);
205 return fq;
206 }
207 }
208#endif
209 fq = fq_in;
210
211 if (!mod_timer(&fq->q.timer, jiffies + nf_frags_ctl.timeout))
212 atomic_inc(&fq->q.refcnt);
213
214 atomic_inc(&fq->q.refcnt);
215 hlist_add_head(&fq->q.list, &nf_frags.hash[hash]);
216 INIT_LIST_HEAD(&fq->q.lru_list);
217 list_add_tail(&fq->q.lru_list, &nf_frags.lru_list);
218 nf_frags.nqueues++;
219 write_unlock(&nf_frags.lock);
220 return fq;
221}
222 180
181 arg.id = id;
182 arg.src = src;
183 arg.dst = dst;
184 hash = ip6qhashfn(id, src, dst);
223 185
224static struct nf_ct_frag6_queue * 186 q = inet_frag_find(&nf_frags, &arg, hash);
225nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, struct in6_addr *dst) 187 if (q == NULL)
226{
227 struct nf_ct_frag6_queue *fq;
228
229 if ((fq = frag_alloc_queue()) == NULL) {
230 pr_debug("Can't alloc new queue\n");
231 goto oom; 188 goto oom;
232 }
233
234 fq->id = id;
235 ipv6_addr_copy(&fq->saddr, src);
236 ipv6_addr_copy(&fq->daddr, dst);
237
238 setup_timer(&fq->q.timer, nf_ct_frag6_expire, (unsigned long)fq);
239 spin_lock_init(&fq->q.lock);
240 atomic_set(&fq->q.refcnt, 1);
241 189
242 return nf_ct_frag6_intern(hash, fq); 190 return container_of(q, struct nf_ct_frag6_queue, q);
243 191
244oom: 192oom:
193 pr_debug("Can't alloc new queue\n");
245 return NULL; 194 return NULL;
246} 195}
247 196
248static __inline__ struct nf_ct_frag6_queue *
249fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
250{
251 struct nf_ct_frag6_queue *fq;
252 struct hlist_node *n;
253 unsigned int hash = ip6qhashfn(id, src, dst);
254
255 read_lock(&nf_frags.lock);
256 hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) {
257 if (fq->id == id &&
258 ipv6_addr_equal(src, &fq->saddr) &&
259 ipv6_addr_equal(dst, &fq->daddr)) {
260 atomic_inc(&fq->q.refcnt);
261 read_unlock(&nf_frags.lock);
262 return fq;
263 }
264 }
265 read_unlock(&nf_frags.lock);
266
267 return nf_ct_frag6_create(hash, id, src, dst);
268}
269
270 197
271static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, 198static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
272 struct frag_hdr *fhdr, int nhoff) 199 struct frag_hdr *fhdr, int nhoff)
@@ -749,9 +676,12 @@ int nf_ct_frag6_init(void)
749{ 676{
750 nf_frags.ctl = &nf_frags_ctl; 677 nf_frags.ctl = &nf_frags_ctl;
751 nf_frags.hashfn = nf_hashfn; 678 nf_frags.hashfn = nf_hashfn;
752 nf_frags.destructor = nf_frag_free; 679 nf_frags.constructor = ip6_frag_init;
680 nf_frags.destructor = NULL;
753 nf_frags.skb_free = nf_skb_free; 681 nf_frags.skb_free = nf_skb_free;
754 nf_frags.qsize = sizeof(struct nf_ct_frag6_queue); 682 nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
683 nf_frags.match = ip6_frag_match;
684 nf_frags.frag_expire = nf_ct_frag6_expire;
755 inet_frags_init(&nf_frags); 685 inet_frags_init(&nf_frags);
756 686
757 return 0; 687 return 0;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 6ad19cfc2025..76c88a93b9b5 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -143,6 +143,18 @@ static unsigned int ip6_hashfn(struct inet_frag_queue *q)
143 return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr); 143 return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
144} 144}
145 145
146int ip6_frag_match(struct inet_frag_queue *q, void *a)
147{
148 struct frag_queue *fq;
149 struct ip6_create_arg *arg = a;
150
151 fq = container_of(q, struct frag_queue, q);
152 return (fq->id == arg->id &&
153 ipv6_addr_equal(&fq->saddr, arg->src) &&
154 ipv6_addr_equal(&fq->daddr, arg->dst));
155}
156EXPORT_SYMBOL(ip6_frag_match);
157
146/* Memory Tracking Functions. */ 158/* Memory Tracking Functions. */
147static inline void frag_kfree_skb(struct sk_buff *skb, int *work) 159static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
148{ 160{
@@ -152,20 +164,16 @@ static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
152 kfree_skb(skb); 164 kfree_skb(skb);
153} 165}
154 166
155static void ip6_frag_free(struct inet_frag_queue *fq) 167void ip6_frag_init(struct inet_frag_queue *q, void *a)
156{ 168{
157 kfree(container_of(fq, struct frag_queue, q)); 169 struct frag_queue *fq = container_of(q, struct frag_queue, q);
158} 170 struct ip6_create_arg *arg = a;
159
160static inline struct frag_queue *frag_alloc_queue(void)
161{
162 struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC);
163 171
164 if(!fq) 172 fq->id = arg->id;
165 return NULL; 173 ipv6_addr_copy(&fq->saddr, arg->src);
166 atomic_add(sizeof(struct frag_queue), &ip6_frags.mem); 174 ipv6_addr_copy(&fq->daddr, arg->dst);
167 return fq;
168} 175}
176EXPORT_SYMBOL(ip6_frag_init);
169 177
170/* Destruction primitives. */ 178/* Destruction primitives. */
171 179
@@ -193,9 +201,11 @@ static void ip6_evictor(struct inet6_dev *idev)
193 201
194static void ip6_frag_expire(unsigned long data) 202static void ip6_frag_expire(unsigned long data)
195{ 203{
196 struct frag_queue *fq = (struct frag_queue *) data; 204 struct frag_queue *fq;
197 struct net_device *dev = NULL; 205 struct net_device *dev = NULL;
198 206
207 fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
208
199 spin_lock(&fq->q.lock); 209 spin_lock(&fq->q.lock);
200 210
201 if (fq->q.last_in & COMPLETE) 211 if (fq->q.last_in & COMPLETE)
@@ -230,98 +240,30 @@ out:
230 fq_put(fq); 240 fq_put(fq);
231} 241}
232 242
233/* Creation primitives. */ 243static __inline__ struct frag_queue *
234 244fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
235 245 struct inet6_dev *idev)
236static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
237{ 246{
238 struct frag_queue *fq; 247 struct inet_frag_queue *q;
248 struct ip6_create_arg arg;
239 unsigned int hash; 249 unsigned int hash;
240#ifdef CONFIG_SMP
241 struct hlist_node *n;
242#endif
243 250
244 write_lock(&ip6_frags.lock); 251 arg.id = id;
245 hash = ip6qhashfn(fq_in->id, &fq_in->saddr, &fq_in->daddr); 252 arg.src = src;
246#ifdef CONFIG_SMP 253 arg.dst = dst;
247 hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) { 254 hash = ip6qhashfn(id, src, dst);
248 if (fq->id == fq_in->id &&
249 ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
250 ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
251 atomic_inc(&fq->q.refcnt);
252 write_unlock(&ip6_frags.lock);
253 fq_in->q.last_in |= COMPLETE;
254 fq_put(fq_in);
255 return fq;
256 }
257 }
258#endif
259 fq = fq_in;
260
261 if (!mod_timer(&fq->q.timer, jiffies + ip6_frags_ctl.timeout))
262 atomic_inc(&fq->q.refcnt);
263
264 atomic_inc(&fq->q.refcnt);
265 hlist_add_head(&fq->q.list, &ip6_frags.hash[hash]);
266 INIT_LIST_HEAD(&fq->q.lru_list);
267 list_add_tail(&fq->q.lru_list, &ip6_frags.lru_list);
268 ip6_frags.nqueues++;
269 write_unlock(&ip6_frags.lock);
270 return fq;
271}
272
273
274static struct frag_queue *
275ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
276 struct inet6_dev *idev)
277{
278 struct frag_queue *fq;
279 255
280 if ((fq = frag_alloc_queue()) == NULL) 256 q = inet_frag_find(&ip6_frags, &arg, hash);
257 if (q == NULL)
281 goto oom; 258 goto oom;
282 259
283 fq->id = id; 260 return container_of(q, struct frag_queue, q);
284 ipv6_addr_copy(&fq->saddr, src);
285 ipv6_addr_copy(&fq->daddr, dst);
286
287 init_timer(&fq->q.timer);
288 fq->q.timer.function = ip6_frag_expire;
289 fq->q.timer.data = (long) fq;
290 spin_lock_init(&fq->q.lock);
291 atomic_set(&fq->q.refcnt, 1);
292
293 return ip6_frag_intern(fq);
294 261
295oom: 262oom:
296 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS); 263 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
297 return NULL; 264 return NULL;
298} 265}
299 266
300static __inline__ struct frag_queue *
301fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
302 struct inet6_dev *idev)
303{
304 struct frag_queue *fq;
305 struct hlist_node *n;
306 unsigned int hash;
307
308 read_lock(&ip6_frags.lock);
309 hash = ip6qhashfn(id, src, dst);
310 hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
311 if (fq->id == id &&
312 ipv6_addr_equal(src, &fq->saddr) &&
313 ipv6_addr_equal(dst, &fq->daddr)) {
314 atomic_inc(&fq->q.refcnt);
315 read_unlock(&ip6_frags.lock);
316 return fq;
317 }
318 }
319 read_unlock(&ip6_frags.lock);
320
321 return ip6_frag_create(id, src, dst, idev);
322}
323
324
325static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, 267static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
326 struct frag_hdr *fhdr, int nhoff) 268 struct frag_hdr *fhdr, int nhoff)
327{ 269{
@@ -697,8 +639,11 @@ void __init ipv6_frag_init(void)
697 639
698 ip6_frags.ctl = &ip6_frags_ctl; 640 ip6_frags.ctl = &ip6_frags_ctl;
699 ip6_frags.hashfn = ip6_hashfn; 641 ip6_frags.hashfn = ip6_hashfn;
700 ip6_frags.destructor = ip6_frag_free; 642 ip6_frags.constructor = ip6_frag_init;
643 ip6_frags.destructor = NULL;
701 ip6_frags.skb_free = NULL; 644 ip6_frags.skb_free = NULL;
702 ip6_frags.qsize = sizeof(struct frag_queue); 645 ip6_frags.qsize = sizeof(struct frag_queue);
646 ip6_frags.match = ip6_frag_match;
647 ip6_frags.frag_expire = ip6_frag_expire;
703 inet_frags_init(&ip6_frags); 648 inet_frags_init(&ip6_frags);
704} 649}
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 02f69e544f6f..515783707e86 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,7 +16,7 @@
16#include <net/ipv6.h> 16#include <net/ipv6.h>
17#include <net/xfrm.h> 17#include <net/xfrm.h>
18 18
19int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) 19int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
20{ 20{
21 int err; 21 int err;
22 __be32 seq; 22 __be32 seq;
@@ -24,11 +24,9 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
24 struct xfrm_state *x; 24 struct xfrm_state *x;
25 int xfrm_nr = 0; 25 int xfrm_nr = 0;
26 int decaps = 0; 26 int decaps = 0;
27 int nexthdr;
28 unsigned int nhoff; 27 unsigned int nhoff;
29 28
30 nhoff = IP6CB(skb)->nhoff; 29 nhoff = IP6CB(skb)->nhoff;
31 nexthdr = skb_network_header(skb)[nhoff];
32 30
33 seq = 0; 31 seq = 0;
34 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) 32 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
@@ -41,7 +39,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
41 goto drop; 39 goto drop;
42 40
43 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, 41 x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
44 nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6); 42 nexthdr, AF_INET6);
45 if (x == NULL) 43 if (x == NULL)
46 goto drop; 44 goto drop;
47 spin_lock(&x->lock); 45 spin_lock(&x->lock);
@@ -70,10 +68,10 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
70 68
71 xfrm_vec[xfrm_nr++] = x; 69 xfrm_vec[xfrm_nr++] = x;
72 70
73 if (x->mode->input(x, skb)) 71 if (x->outer_mode->input(x, skb))
74 goto drop; 72 goto drop;
75 73
76 if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */ 74 if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
77 decaps = 1; 75 decaps = 1;
78 break; 76 break;
79 } 77 }
@@ -99,7 +97,6 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
99 memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, 97 memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
100 xfrm_nr * sizeof(xfrm_vec[0])); 98 xfrm_nr * sizeof(xfrm_vec[0]));
101 skb->sp->len += xfrm_nr; 99 skb->sp->len += xfrm_nr;
102 skb->ip_summed = CHECKSUM_NONE;
103 100
104 nf_reset(skb); 101 nf_reset(skb);
105 102
@@ -135,7 +132,8 @@ EXPORT_SYMBOL(xfrm6_rcv_spi);
135 132
136int xfrm6_rcv(struct sk_buff *skb) 133int xfrm6_rcv(struct sk_buff *skb)
137{ 134{
138 return xfrm6_rcv_spi(skb, 0); 135 return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
136 0);
139} 137}
140 138
141EXPORT_SYMBOL(xfrm6_rcv); 139EXPORT_SYMBOL(xfrm6_rcv);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 13bb1e856764..2bfb4f05c14c 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -79,6 +79,7 @@ static struct xfrm_mode xfrm6_beet_mode = {
79 .output = xfrm6_beet_output, 79 .output = xfrm6_beet_output,
80 .owner = THIS_MODULE, 80 .owner = THIS_MODULE,
81 .encap = XFRM_MODE_BEET, 81 .encap = XFRM_MODE_BEET,
82 .flags = XFRM_MODE_FLAG_TUNNEL,
82}; 83};
83 84
84static int __init xfrm6_beet_init(void) 85static int __init xfrm6_beet_init(void)
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index 957ae36b6695..a7bc8c62317a 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -58,16 +58,7 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
58 return 0; 58 return 0;
59} 59}
60 60
61/*
62 * Do nothing about routing optimization header unlike IPsec.
63 */
64static int xfrm6_ro_input(struct xfrm_state *x, struct sk_buff *skb)
65{
66 return 0;
67}
68
69static struct xfrm_mode xfrm6_ro_mode = { 61static struct xfrm_mode xfrm6_ro_mode = {
70 .input = xfrm6_ro_input,
71 .output = xfrm6_ro_output, 62 .output = xfrm6_ro_output,
72 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
73 .encap = XFRM_MODE_ROUTEOPTIMIZATION, 64 .encap = XFRM_MODE_ROUTEOPTIMIZATION,
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index ea2283879112..fd84e2217274 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -118,6 +118,7 @@ static struct xfrm_mode xfrm6_tunnel_mode = {
118 .output = xfrm6_tunnel_output, 118 .output = xfrm6_tunnel_output,
119 .owner = THIS_MODULE, 119 .owner = THIS_MODULE,
120 .encap = XFRM_MODE_TUNNEL, 120 .encap = XFRM_MODE_TUNNEL,
121 .flags = XFRM_MODE_FLAG_TUNNEL,
121}; 122};
122 123
123static int __init xfrm6_tunnel_init(void) 124static int __init xfrm6_tunnel_init(void)
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index a5a32c17249d..656976760ad4 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -50,7 +50,7 @@ static inline int xfrm6_output_one(struct sk_buff *skb)
50 struct ipv6hdr *iph; 50 struct ipv6hdr *iph;
51 int err; 51 int err;
52 52
53 if (x->props.mode == XFRM_MODE_TUNNEL) { 53 if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
54 err = xfrm6_tunnel_check_size(skb); 54 err = xfrm6_tunnel_check_size(skb);
55 if (err) 55 if (err)
56 goto error_nolock; 56 goto error_nolock;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 15aa4c58c315..82e27b80d07d 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -178,8 +178,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
178 __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]); 178 __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
179 trailer_len += xfrm[i]->props.trailer_len; 179 trailer_len += xfrm[i]->props.trailer_len;
180 180
181 if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL || 181 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
182 xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {
183 unsigned short encap_family = xfrm[i]->props.family; 182 unsigned short encap_family = xfrm[i]->props.family;
184 switch(encap_family) { 183 switch(encap_family) {
185 case AF_INET: 184 case AF_INET:
@@ -215,7 +214,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
215 i = 0; 214 i = 0;
216 for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { 215 for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
217 struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; 216 struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
218 struct xfrm_state_afinfo *afinfo;
219 217
220 dst_prev->xfrm = xfrm[i++]; 218 dst_prev->xfrm = xfrm[i++];
221 dst_prev->dev = rt->u.dst.dev; 219 dst_prev->dev = rt->u.dst.dev;
@@ -232,18 +230,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
232 /* Copy neighbour for reachability confirmation */ 230 /* Copy neighbour for reachability confirmation */
233 dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); 231 dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
234 dst_prev->input = rt->u.dst.input; 232 dst_prev->input = rt->u.dst.input;
235 /* XXX: When IPv4 is implemented as module and can be unloaded, 233 dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
236 * we should manage reference to xfrm4_output in afinfo->output.
237 * Miyazawa
238 */
239 afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
240 if (!afinfo) {
241 dst = *dst_p;
242 goto error;
243 }
244
245 dst_prev->output = afinfo->output;
246 xfrm_state_put_afinfo(afinfo);
247 /* Sheit... I remember I did this right. Apparently, 234 /* Sheit... I remember I did this right. Apparently,
248 * it was magically lost, so this code needs audit */ 235 * it was magically lost, so this code needs audit */
249 x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); 236 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 cdadb4847469..b392bee396f1 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -93,7 +93,8 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
93 /* Rule 4: select IPsec tunnel */ 93 /* Rule 4: select IPsec tunnel */
94 for (i = 0; i < n; i++) { 94 for (i = 0; i < n; i++) {
95 if (src[i] && 95 if (src[i] &&
96 src[i]->props.mode == XFRM_MODE_TUNNEL) { 96 (src[i]->props.mode == XFRM_MODE_TUNNEL ||
97 src[i]->props.mode == XFRM_MODE_BEET)) {
97 dst[j++] = src[i]; 98 dst[j++] = src[i];
98 src[i] = NULL; 99 src[i] = NULL;
99 } 100 }
@@ -146,7 +147,8 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
146 /* Rule 3: select IPsec tunnel */ 147 /* Rule 3: select IPsec tunnel */
147 for (i = 0; i < n; i++) { 148 for (i = 0; i < n; i++) {
148 if (src[i] && 149 if (src[i] &&
149 src[i]->mode == XFRM_MODE_TUNNEL) { 150 (src[i]->mode == XFRM_MODE_TUNNEL ||
151 src[i]->mode == XFRM_MODE_BEET)) {
150 dst[j++] = src[i]; 152 dst[j++] = src[i];
151 src[i] = NULL; 153 src[i] = NULL;
152 } 154 }
@@ -168,6 +170,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
168 170
169static struct xfrm_state_afinfo xfrm6_state_afinfo = { 171static struct xfrm_state_afinfo xfrm6_state_afinfo = {
170 .family = AF_INET6, 172 .family = AF_INET6,
173 .owner = THIS_MODULE,
171 .init_tempsel = __xfrm6_init_tempsel, 174 .init_tempsel = __xfrm6_init_tempsel,
172 .tmpl_sort = __xfrm6_tmpl_sort, 175 .tmpl_sort = __xfrm6_tmpl_sort,
173 .state_sort = __xfrm6_state_sort, 176 .state_sort = __xfrm6_state_sort,
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 3f8a3abde67e..fae90ff31087 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -248,7 +248,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
248 248
249static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) 249static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
250{ 250{
251 return 0; 251 return skb_network_header(skb)[IP6CB(skb)->nhoff];
252} 252}
253 253
254static int xfrm6_tunnel_rcv(struct sk_buff *skb) 254static int xfrm6_tunnel_rcv(struct sk_buff *skb)
@@ -257,7 +257,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
257 __be32 spi; 257 __be32 spi;
258 258
259 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 259 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
260 return xfrm6_rcv_spi(skb, spi) > 0 ? : 0; 260 return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
261} 261}
262 262
263static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 263static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index 824309dabfe9..b5a13882c927 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -381,18 +381,9 @@ static void ircomm_tty_discovery_indication(discinfo_t *discovery,
381 info.daddr = discovery->daddr; 381 info.daddr = discovery->daddr;
382 info.saddr = discovery->saddr; 382 info.saddr = discovery->saddr;
383 383
384 /* FIXME. We have a locking problem on the hashbin here. 384 self = (struct ircomm_tty_cb *) priv;
385 * We probably need to use hashbin_find_next(), but we first 385 ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
386 * need to ensure that "line" is unique. - Jean II */ 386 NULL, &info);
387 self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
388 while (self != NULL) {
389 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
390
391 ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
392 NULL, &info);
393
394 self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
395 }
396} 387}
397 388
398/* 389/*
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index f0224c2311d2..6caa3ec2cff7 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -306,9 +306,12 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
306 ((chan->chan == channel) || (chan->freq == freq))) { 306 ((chan->chan == channel) || (chan->freq == freq))) {
307 local->oper_channel = chan; 307 local->oper_channel = chan;
308 local->oper_hw_mode = mode; 308 local->oper_hw_mode = mode;
309 set++; 309 set = 1;
310 break;
310 } 311 }
311 } 312 }
313 if (set)
314 break;
312 } 315 }
313 316
314 if (set) { 317 if (set) {
@@ -508,10 +511,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
508 511
509static int ieee80211_ioctl_siwscan(struct net_device *dev, 512static int ieee80211_ioctl_siwscan(struct net_device *dev,
510 struct iw_request_info *info, 513 struct iw_request_info *info,
511 struct iw_point *data, char *extra) 514 union iwreq_data *wrqu, char *extra)
512{ 515{
513 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 516 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
514 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 517 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
518 struct iw_scan_req *req = NULL;
515 u8 *ssid = NULL; 519 u8 *ssid = NULL;
516 size_t ssid_len = 0; 520 size_t ssid_len = 0;
517 521
@@ -536,6 +540,14 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
536 return -EOPNOTSUPP; 540 return -EOPNOTSUPP;
537 } 541 }
538 542
543 /* if SSID was specified explicitly then use that */
544 if (wrqu->data.length == sizeof(struct iw_scan_req) &&
545 wrqu->data.flags & IW_SCAN_THIS_ESSID) {
546 req = (struct iw_scan_req *)extra;
547 ssid = req->essid;
548 ssid_len = req->essid_len;
549 }
550
539 return ieee80211_sta_req_scan(dev, ssid, ssid_len); 551 return ieee80211_sta_req_scan(dev, ssid, ssid_len);
540} 552}
541 553
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 1641e8fe44b7..db81aef6177a 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14/* TODO: 14/* TODO:
15 * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
16 * order BSS list by RSSI(?) ("quality of AP") 15 * order BSS list by RSSI(?) ("quality of AP")
17 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, 16 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
18 * SSID) 17 * SSID)
@@ -61,7 +60,8 @@
61static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, 60static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
62 u8 *ssid, size_t ssid_len); 61 u8 *ssid, size_t ssid_len);
63static struct ieee80211_sta_bss * 62static struct ieee80211_sta_bss *
64ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); 63ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
64 u8 *ssid, u8 ssid_len);
65static void ieee80211_rx_bss_put(struct net_device *dev, 65static void ieee80211_rx_bss_put(struct net_device *dev,
66 struct ieee80211_sta_bss *bss); 66 struct ieee80211_sta_bss *bss);
67static int ieee80211_sta_find_ibss(struct net_device *dev, 67static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -427,7 +427,9 @@ static void ieee80211_set_associated(struct net_device *dev,
427 if (sdata->type != IEEE80211_IF_TYPE_STA) 427 if (sdata->type != IEEE80211_IF_TYPE_STA)
428 return; 428 return;
429 429
430 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 430 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
431 local->hw.conf.channel,
432 ifsta->ssid, ifsta->ssid_len);
431 if (bss) { 433 if (bss) {
432 if (bss->has_erp_value) 434 if (bss->has_erp_value)
433 ieee80211_handle_erp_ie(dev, bss->erp_value); 435 ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -574,7 +576,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
574 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | 576 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
575 WLAN_CAPABILITY_SHORT_PREAMBLE; 577 WLAN_CAPABILITY_SHORT_PREAMBLE;
576 } 578 }
577 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 579 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
580 ifsta->ssid, ifsta->ssid_len);
578 if (bss) { 581 if (bss) {
579 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 582 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
580 capab |= WLAN_CAPABILITY_PRIVACY; 583 capab |= WLAN_CAPABILITY_PRIVACY;
@@ -722,6 +725,7 @@ static void ieee80211_send_disassoc(struct net_device *dev,
722static int ieee80211_privacy_mismatch(struct net_device *dev, 725static int ieee80211_privacy_mismatch(struct net_device *dev,
723 struct ieee80211_if_sta *ifsta) 726 struct ieee80211_if_sta *ifsta)
724{ 727{
728 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
725 struct ieee80211_sta_bss *bss; 729 struct ieee80211_sta_bss *bss;
726 int res = 0; 730 int res = 0;
727 731
@@ -729,7 +733,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
729 ifsta->key_management_enabled) 733 ifsta->key_management_enabled)
730 return 0; 734 return 0;
731 735
732 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 736 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
737 ifsta->ssid, ifsta->ssid_len);
733 if (!bss) 738 if (!bss)
734 return 0; 739 return 0;
735 740
@@ -1203,15 +1208,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1203 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); 1208 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1204 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 1209 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
1205 aid = le16_to_cpu(mgmt->u.assoc_resp.aid); 1210 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
1206 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1207 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1208 "set\n", dev->name, aid);
1209 aid &= ~(BIT(15) | BIT(14));
1210 1211
1211 printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " 1212 printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
1212 "status=%d aid=%d)\n", 1213 "status=%d aid=%d)\n",
1213 dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), 1214 dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
1214 capab_info, status_code, aid); 1215 capab_info, status_code, aid & ~(BIT(15) | BIT(14)));
1215 1216
1216 if (status_code != WLAN_STATUS_SUCCESS) { 1217 if (status_code != WLAN_STATUS_SUCCESS) {
1217 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", 1218 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -1223,6 +1224,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1223 return; 1224 return;
1224 } 1225 }
1225 1226
1227 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1228 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1229 "set\n", dev->name, aid);
1230 aid &= ~(BIT(15) | BIT(14));
1231
1226 pos = mgmt->u.assoc_resp.variable; 1232 pos = mgmt->u.assoc_resp.variable;
1227 if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) 1233 if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
1228 == ParseFailed) { 1234 == ParseFailed) {
@@ -1241,7 +1247,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1241 * update our stored copy */ 1247 * update our stored copy */
1242 if (elems.erp_info && elems.erp_info_len >= 1) { 1248 if (elems.erp_info && elems.erp_info_len >= 1) {
1243 struct ieee80211_sta_bss *bss 1249 struct ieee80211_sta_bss *bss
1244 = ieee80211_rx_bss_get(dev, ifsta->bssid); 1250 = ieee80211_rx_bss_get(dev, ifsta->bssid,
1251 local->hw.conf.channel,
1252 ifsta->ssid, ifsta->ssid_len);
1245 if (bss) { 1253 if (bss) {
1246 bss->erp_value = elems.erp_info[0]; 1254 bss->erp_value = elems.erp_info[0];
1247 bss->has_erp_value = 1; 1255 bss->has_erp_value = 1;
@@ -1271,7 +1279,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
1271 " AP\n", dev->name); 1279 " AP\n", dev->name);
1272 return; 1280 return;
1273 } 1281 }
1274 bss = ieee80211_rx_bss_get(dev, ifsta->bssid); 1282 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
1283 local->hw.conf.channel,
1284 ifsta->ssid, ifsta->ssid_len);
1275 if (bss) { 1285 if (bss) {
1276 sta->last_rssi = bss->rssi; 1286 sta->last_rssi = bss->rssi;
1277 sta->last_signal = bss->signal; 1287 sta->last_signal = bss->signal;
@@ -1347,7 +1357,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
1347 1357
1348 1358
1349static struct ieee80211_sta_bss * 1359static struct ieee80211_sta_bss *
1350ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) 1360ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
1361 u8 *ssid, u8 ssid_len)
1351{ 1362{
1352 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1363 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1353 struct ieee80211_sta_bss *bss; 1364 struct ieee80211_sta_bss *bss;
@@ -1358,6 +1369,11 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
1358 atomic_inc(&bss->users); 1369 atomic_inc(&bss->users);
1359 atomic_inc(&bss->users); 1370 atomic_inc(&bss->users);
1360 memcpy(bss->bssid, bssid, ETH_ALEN); 1371 memcpy(bss->bssid, bssid, ETH_ALEN);
1372 bss->channel = channel;
1373 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
1374 memcpy(bss->ssid, ssid, ssid_len);
1375 bss->ssid_len = ssid_len;
1376 }
1361 1377
1362 spin_lock_bh(&local->sta_bss_lock); 1378 spin_lock_bh(&local->sta_bss_lock);
1363 /* TODO: order by RSSI? */ 1379 /* TODO: order by RSSI? */
@@ -1369,7 +1385,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
1369 1385
1370 1386
1371static struct ieee80211_sta_bss * 1387static struct ieee80211_sta_bss *
1372ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) 1388ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
1389 u8 *ssid, u8 ssid_len)
1373{ 1390{
1374 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1391 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1375 struct ieee80211_sta_bss *bss; 1392 struct ieee80211_sta_bss *bss;
@@ -1377,7 +1394,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
1377 spin_lock_bh(&local->sta_bss_lock); 1394 spin_lock_bh(&local->sta_bss_lock);
1378 bss = local->sta_bss_hash[STA_HASH(bssid)]; 1395 bss = local->sta_bss_hash[STA_HASH(bssid)];
1379 while (bss) { 1396 while (bss) {
1380 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { 1397 if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
1398 bss->channel == channel &&
1399 bss->ssid_len == ssid_len &&
1400 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
1381 atomic_inc(&bss->users); 1401 atomic_inc(&bss->users);
1382 break; 1402 break;
1383 } 1403 }
@@ -1545,9 +1565,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1545 else 1565 else
1546 channel = rx_status->channel; 1566 channel = rx_status->channel;
1547 1567
1548 bss = ieee80211_rx_bss_get(dev, mgmt->bssid); 1568 bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
1569 elems.ssid, elems.ssid_len);
1549 if (!bss) { 1570 if (!bss) {
1550 bss = ieee80211_rx_bss_add(dev, mgmt->bssid); 1571 bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
1572 elems.ssid, elems.ssid_len);
1551 if (!bss) 1573 if (!bss)
1552 return; 1574 return;
1553 } else { 1575 } else {
@@ -1573,10 +1595,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1573 1595
1574 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 1596 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
1575 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 1597 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
1576 if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
1577 memcpy(bss->ssid, elems.ssid, elems.ssid_len);
1578 bss->ssid_len = elems.ssid_len;
1579 }
1580 1598
1581 bss->supp_rates_len = 0; 1599 bss->supp_rates_len = 0;
1582 if (elems.supp_rates) { 1600 if (elems.supp_rates) {
@@ -1647,7 +1665,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
1647 1665
1648 1666
1649 bss->hw_mode = rx_status->phymode; 1667 bss->hw_mode = rx_status->phymode;
1650 bss->channel = channel;
1651 bss->freq = rx_status->freq; 1668 bss->freq = rx_status->freq;
1652 if (channel != rx_status->channel && 1669 if (channel != rx_status->channel &&
1653 (bss->hw_mode == MODE_IEEE80211G || 1670 (bss->hw_mode == MODE_IEEE80211G ||
@@ -2375,7 +2392,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
2375{ 2392{
2376 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2393 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2377 struct ieee80211_sta_bss *bss; 2394 struct ieee80211_sta_bss *bss;
2378 struct ieee80211_sub_if_data *sdata; 2395 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2379 struct ieee80211_hw_mode *mode; 2396 struct ieee80211_hw_mode *mode;
2380 u8 bssid[ETH_ALEN], *pos; 2397 u8 bssid[ETH_ALEN], *pos;
2381 int i; 2398 int i;
@@ -2398,18 +2415,17 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
2398 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", 2415 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
2399 dev->name, print_mac(mac, bssid)); 2416 dev->name, print_mac(mac, bssid));
2400 2417
2401 bss = ieee80211_rx_bss_add(dev, bssid); 2418 bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
2419 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
2402 if (!bss) 2420 if (!bss)
2403 return -ENOMEM; 2421 return -ENOMEM;
2404 2422
2405 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2406 mode = local->oper_hw_mode; 2423 mode = local->oper_hw_mode;
2407 2424
2408 if (local->hw.conf.beacon_int == 0) 2425 if (local->hw.conf.beacon_int == 0)
2409 local->hw.conf.beacon_int = 100; 2426 local->hw.conf.beacon_int = 100;
2410 bss->beacon_int = local->hw.conf.beacon_int; 2427 bss->beacon_int = local->hw.conf.beacon_int;
2411 bss->hw_mode = local->hw.conf.phymode; 2428 bss->hw_mode = local->hw.conf.phymode;
2412 bss->channel = local->hw.conf.channel;
2413 bss->freq = local->hw.conf.freq; 2429 bss->freq = local->hw.conf.freq;
2414 bss->last_update = jiffies; 2430 bss->last_update = jiffies;
2415 bss->capability = WLAN_CAPABILITY_IBSS; 2431 bss->capability = WLAN_CAPABILITY_IBSS;
@@ -2469,7 +2485,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
2469 "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); 2485 "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
2470#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2486#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2471 if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && 2487 if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
2472 (bss = ieee80211_rx_bss_get(dev, bssid))) { 2488 (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
2489 ifsta->ssid, ifsta->ssid_len))) {
2473 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" 2490 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
2474 " based on configured SSID\n", 2491 " based on configured SSID\n",
2475 dev->name, print_mac(mac, bssid)); 2492 dev->name, print_mac(mac, bssid));
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index a127ab32881e..7a3f64c1aca6 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -834,10 +834,12 @@ static int tcp_packet(struct nf_conn *conntrack,
834 case TCP_CONNTRACK_SYN_SENT: 834 case TCP_CONNTRACK_SYN_SENT:
835 if (old_state < TCP_CONNTRACK_TIME_WAIT) 835 if (old_state < TCP_CONNTRACK_TIME_WAIT)
836 break; 836 break;
837 if (conntrack->proto.tcp.seen[!dir].flags & 837 if ((conntrack->proto.tcp.seen[!dir].flags &
838 IP_CT_TCP_FLAG_CLOSE_INIT) { 838 IP_CT_TCP_FLAG_CLOSE_INIT)
839 /* Attempt to reopen a closed connection. 839 || (conntrack->proto.tcp.last_dir == dir
840 * Delete this connection and look up again. */ 840 && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
841 /* Attempt to reopen a closed/aborted connection.
842 * Delete this connection and look up again. */
841 write_unlock_bh(&tcp_lock); 843 write_unlock_bh(&tcp_lock);
842 if (del_timer(&conntrack->timeout)) 844 if (del_timer(&conntrack->timeout))
843 conntrack->timeout.function((unsigned long) 845 conntrack->timeout.function((unsigned long)
@@ -925,6 +927,7 @@ static int tcp_packet(struct nf_conn *conntrack,
925 in_window: 927 in_window:
926 /* From now on we have got in-window packets */ 928 /* From now on we have got in-window packets */
927 conntrack->proto.tcp.last_index = index; 929 conntrack->proto.tcp.last_index = index;
930 conntrack->proto.tcp.last_dir = dir;
928 931
929 pr_debug("tcp_conntracks: "); 932 pr_debug("tcp_conntracks: ");
930 NF_CT_DUMP_TUPLE(tuple); 933 NF_CT_DUMP_TUPLE(tuple);
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index f907770fd4e9..3358273a47b7 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -42,21 +42,21 @@ match_flags(const struct xt_sctp_flag_info *flag_info,
42static inline bool 42static inline bool
43match_packet(const struct sk_buff *skb, 43match_packet(const struct sk_buff *skb,
44 unsigned int offset, 44 unsigned int offset,
45 const u_int32_t *chunkmap, 45 const struct xt_sctp_info *info,
46 int chunk_match_type,
47 const struct xt_sctp_flag_info *flag_info,
48 const int flag_count,
49 bool *hotdrop) 46 bool *hotdrop)
50{ 47{
51 u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 48 u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
52 sctp_chunkhdr_t _sch, *sch; 49 sctp_chunkhdr_t _sch, *sch;
50 int chunk_match_type = info->chunk_match_type;
51 const struct xt_sctp_flag_info *flag_info = info->flag_info;
52 int flag_count = info->flag_count;
53 53
54#ifdef DEBUG_SCTP 54#ifdef DEBUG_SCTP
55 int i = 0; 55 int i = 0;
56#endif 56#endif
57 57
58 if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) 58 if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
59 SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); 59 SCTP_CHUNKMAP_COPY(chunkmapcopy, info->chunkmap);
60 60
61 do { 61 do {
62 sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); 62 sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
@@ -73,7 +73,7 @@ match_packet(const struct sk_buff *skb,
73 73
74 duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); 74 duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
75 75
76 if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { 76 if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) {
77 switch (chunk_match_type) { 77 switch (chunk_match_type) {
78 case SCTP_CHUNK_MATCH_ANY: 78 case SCTP_CHUNK_MATCH_ANY:
79 if (match_flags(flag_info, flag_count, 79 if (match_flags(flag_info, flag_count,
@@ -104,7 +104,7 @@ match_packet(const struct sk_buff *skb,
104 104
105 switch (chunk_match_type) { 105 switch (chunk_match_type) {
106 case SCTP_CHUNK_MATCH_ALL: 106 case SCTP_CHUNK_MATCH_ALL:
107 return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); 107 return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap);
108 case SCTP_CHUNK_MATCH_ANY: 108 case SCTP_CHUNK_MATCH_ANY:
109 return false; 109 return false;
110 case SCTP_CHUNK_MATCH_ONLY: 110 case SCTP_CHUNK_MATCH_ONLY:
@@ -148,9 +148,7 @@ match(const struct sk_buff *skb,
148 && ntohs(sh->dest) <= info->dpts[1], 148 && ntohs(sh->dest) <= info->dpts[1],
149 XT_SCTP_DEST_PORTS, info->flags, info->invflags) 149 XT_SCTP_DEST_PORTS, info->flags, info->invflags)
150 && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t), 150 && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
151 info->chunkmap, info->chunk_match_type, 151 info, hotdrop),
152 info->flag_info, info->flag_count,
153 hotdrop),
154 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 152 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
155} 153}
156 154
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 95ae11956f35..e01d57692c9a 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -249,10 +249,11 @@ static void dev_watchdog_down(struct net_device *dev)
249 */ 249 */
250void netif_carrier_on(struct net_device *dev) 250void netif_carrier_on(struct net_device *dev)
251{ 251{
252 if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) 252 if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
253 linkwatch_fire_event(dev); 253 linkwatch_fire_event(dev);
254 if (netif_running(dev)) 254 if (netif_running(dev))
255 __netdev_watchdog_up(dev); 255 __netdev_watchdog_up(dev);
256 }
256} 257}
257 258
258/** 259/**
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 113f44429982..cb97fda1b6df 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -49,13 +49,16 @@ EXPORT_SYMBOL(secpath_dup);
49int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) 49int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
50{ 50{
51 int offset, offset_seq; 51 int offset, offset_seq;
52 int hlen;
52 53
53 switch (nexthdr) { 54 switch (nexthdr) {
54 case IPPROTO_AH: 55 case IPPROTO_AH:
56 hlen = sizeof(struct ip_auth_hdr);
55 offset = offsetof(struct ip_auth_hdr, spi); 57 offset = offsetof(struct ip_auth_hdr, spi);
56 offset_seq = offsetof(struct ip_auth_hdr, seq_no); 58 offset_seq = offsetof(struct ip_auth_hdr, seq_no);
57 break; 59 break;
58 case IPPROTO_ESP: 60 case IPPROTO_ESP:
61 hlen = sizeof(struct ip_esp_hdr);
59 offset = offsetof(struct ip_esp_hdr, spi); 62 offset = offsetof(struct ip_esp_hdr, spi);
60 offset_seq = offsetof(struct ip_esp_hdr, seq_no); 63 offset_seq = offsetof(struct ip_esp_hdr, seq_no);
61 break; 64 break;
@@ -69,7 +72,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
69 return 1; 72 return 1;
70 } 73 }
71 74
72 if (!pskb_may_pull(skb, 16)) 75 if (!pskb_may_pull(skb, hlen))
73 return -EINVAL; 76 return -EINVAL;
74 77
75 *spi = *(__be32*)(skb_transport_header(skb) + offset); 78 *spi = *(__be32*)(skb_transport_header(skb) + offset);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 0eb3377602e9..f4bfd6c45651 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -63,7 +63,7 @@ int xfrm_output(struct sk_buff *skb)
63 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); 63 xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
64 } 64 }
65 65
66 err = x->mode->output(x, skb); 66 err = x->outer_mode->output(x, skb);
67 if (err) 67 if (err)
68 goto error; 68 goto error;
69 69
@@ -82,7 +82,7 @@ int xfrm_output(struct sk_buff *skb)
82 } 82 }
83 dst = skb->dst; 83 dst = skb->dst;
84 x = dst->xfrm; 84 x = dst->xfrm;
85 } while (x && (x->props.mode != XFRM_MODE_TUNNEL)); 85 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
86 86
87 err = 0; 87 err = 0;
88 88
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index af27c193697c..b702bd8a3893 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -49,8 +49,6 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
49 49
50static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); 50static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
51static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); 51static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
52static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family);
53static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo);
54 52
55static inline int 53static inline int
56__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) 54__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -86,72 +84,6 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
86 return 0; 84 return 0;
87} 85}
88 86
89int xfrm_register_type(struct xfrm_type *type, unsigned short family)
90{
91 struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
92 struct xfrm_type **typemap;
93 int err = 0;
94
95 if (unlikely(afinfo == NULL))
96 return -EAFNOSUPPORT;
97 typemap = afinfo->type_map;
98
99 if (likely(typemap[type->proto] == NULL))
100 typemap[type->proto] = type;
101 else
102 err = -EEXIST;
103 xfrm_policy_unlock_afinfo(afinfo);
104 return err;
105}
106EXPORT_SYMBOL(xfrm_register_type);
107
108int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
109{
110 struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
111 struct xfrm_type **typemap;
112 int err = 0;
113
114 if (unlikely(afinfo == NULL))
115 return -EAFNOSUPPORT;
116 typemap = afinfo->type_map;
117
118 if (unlikely(typemap[type->proto] != type))
119 err = -ENOENT;
120 else
121 typemap[type->proto] = NULL;
122 xfrm_policy_unlock_afinfo(afinfo);
123 return err;
124}
125EXPORT_SYMBOL(xfrm_unregister_type);
126
127struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
128{
129 struct xfrm_policy_afinfo *afinfo;
130 struct xfrm_type **typemap;
131 struct xfrm_type *type;
132 int modload_attempted = 0;
133
134retry:
135 afinfo = xfrm_policy_get_afinfo(family);
136 if (unlikely(afinfo == NULL))
137 return NULL;
138 typemap = afinfo->type_map;
139
140 type = typemap[proto];
141 if (unlikely(type && !try_module_get(type->owner)))
142 type = NULL;
143 if (!type && !modload_attempted) {
144 xfrm_policy_put_afinfo(afinfo);
145 request_module("xfrm-type-%d-%d",
146 (int) family, (int) proto);
147 modload_attempted = 1;
148 goto retry;
149 }
150
151 xfrm_policy_put_afinfo(afinfo);
152 return type;
153}
154
155int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, 87int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
156 unsigned short family) 88 unsigned short family)
157{ 89{
@@ -170,94 +102,6 @@ int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
170} 102}
171EXPORT_SYMBOL(xfrm_dst_lookup); 103EXPORT_SYMBOL(xfrm_dst_lookup);
172 104
173void xfrm_put_type(struct xfrm_type *type)
174{
175 module_put(type->owner);
176}
177
178int xfrm_register_mode(struct xfrm_mode *mode, int family)
179{
180 struct xfrm_policy_afinfo *afinfo;
181 struct xfrm_mode **modemap;
182 int err;
183
184 if (unlikely(mode->encap >= XFRM_MODE_MAX))
185 return -EINVAL;
186
187 afinfo = xfrm_policy_lock_afinfo(family);
188 if (unlikely(afinfo == NULL))
189 return -EAFNOSUPPORT;
190
191 err = -EEXIST;
192 modemap = afinfo->mode_map;
193 if (likely(modemap[mode->encap] == NULL)) {
194 modemap[mode->encap] = mode;
195 err = 0;
196 }
197
198 xfrm_policy_unlock_afinfo(afinfo);
199 return err;
200}
201EXPORT_SYMBOL(xfrm_register_mode);
202
203int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
204{
205 struct xfrm_policy_afinfo *afinfo;
206 struct xfrm_mode **modemap;
207 int err;
208
209 if (unlikely(mode->encap >= XFRM_MODE_MAX))
210 return -EINVAL;
211
212 afinfo = xfrm_policy_lock_afinfo(family);
213 if (unlikely(afinfo == NULL))
214 return -EAFNOSUPPORT;
215
216 err = -ENOENT;
217 modemap = afinfo->mode_map;
218 if (likely(modemap[mode->encap] == mode)) {
219 modemap[mode->encap] = NULL;
220 err = 0;
221 }
222
223 xfrm_policy_unlock_afinfo(afinfo);
224 return err;
225}
226EXPORT_SYMBOL(xfrm_unregister_mode);
227
228struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
229{
230 struct xfrm_policy_afinfo *afinfo;
231 struct xfrm_mode *mode;
232 int modload_attempted = 0;
233
234 if (unlikely(encap >= XFRM_MODE_MAX))
235 return NULL;
236
237retry:
238 afinfo = xfrm_policy_get_afinfo(family);
239 if (unlikely(afinfo == NULL))
240 return NULL;
241
242 mode = afinfo->mode_map[encap];
243 if (unlikely(mode && !try_module_get(mode->owner)))
244 mode = NULL;
245 if (!mode && !modload_attempted) {
246 xfrm_policy_put_afinfo(afinfo);
247 request_module("xfrm-mode-%d-%d", family, encap);
248 modload_attempted = 1;
249 goto retry;
250 }
251
252 xfrm_policy_put_afinfo(afinfo);
253 return mode;
254}
255
256void xfrm_put_mode(struct xfrm_mode *mode)
257{
258 module_put(mode->owner);
259}
260
261static inline unsigned long make_jiffies(long secs) 105static inline unsigned long make_jiffies(long secs)
262{ 106{
263 if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ) 107 if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
@@ -2096,7 +1940,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
2096 if (xdst->genid != dst->xfrm->genid) 1940 if (xdst->genid != dst->xfrm->genid)
2097 return 0; 1941 return 0;
2098 1942
2099 if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL && 1943 if (strict && fl &&
1944 !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
2100 !xfrm_state_addr_flow_check(dst->xfrm, fl, family)) 1945 !xfrm_state_addr_flow_check(dst->xfrm, fl, family))
2101 return 0; 1946 return 0;
2102 1947
@@ -2213,23 +2058,6 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
2213 read_unlock(&xfrm_policy_afinfo_lock); 2058 read_unlock(&xfrm_policy_afinfo_lock);
2214} 2059}
2215 2060
2216static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family)
2217{
2218 struct xfrm_policy_afinfo *afinfo;
2219 if (unlikely(family >= NPROTO))
2220 return NULL;
2221 write_lock_bh(&xfrm_policy_afinfo_lock);
2222 afinfo = xfrm_policy_afinfo[family];
2223 if (unlikely(!afinfo))
2224 write_unlock_bh(&xfrm_policy_afinfo_lock);
2225 return afinfo;
2226}
2227
2228static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo)
2229{
2230 write_unlock_bh(&xfrm_policy_afinfo_lock);
2231}
2232
2233static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) 2061static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
2234{ 2062{
2235 struct net_device *dev = ptr; 2063 struct net_device *dev = ptr;
@@ -2464,7 +2292,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
2464 if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i])) 2292 if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i]))
2465 continue; 2293 continue;
2466 n++; 2294 n++;
2467 if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL) 2295 if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
2296 pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
2468 continue; 2297 continue;
2469 /* update endpoints */ 2298 /* update endpoints */
2470 memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr, 2299 memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 344f0a6abec5..224b44e31a07 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -57,6 +57,9 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
57static unsigned int xfrm_state_num; 57static unsigned int xfrm_state_num;
58static unsigned int xfrm_state_genid; 58static unsigned int xfrm_state_genid;
59 59
60static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
61static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
62
60static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr, 63static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
61 xfrm_address_t *saddr, 64 xfrm_address_t *saddr,
62 u32 reqid, 65 u32 reqid,
@@ -187,6 +190,184 @@ int __xfrm_state_delete(struct xfrm_state *x);
187int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); 190int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
188void km_state_expired(struct xfrm_state *x, int hard, u32 pid); 191void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
189 192
193static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
194{
195 struct xfrm_state_afinfo *afinfo;
196 if (unlikely(family >= NPROTO))
197 return NULL;
198 write_lock_bh(&xfrm_state_afinfo_lock);
199 afinfo = xfrm_state_afinfo[family];
200 if (unlikely(!afinfo))
201 write_unlock_bh(&xfrm_state_afinfo_lock);
202 return afinfo;
203}
204
205static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
206{
207 write_unlock_bh(&xfrm_state_afinfo_lock);
208}
209
210int xfrm_register_type(struct xfrm_type *type, unsigned short family)
211{
212 struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
213 struct xfrm_type **typemap;
214 int err = 0;
215
216 if (unlikely(afinfo == NULL))
217 return -EAFNOSUPPORT;
218 typemap = afinfo->type_map;
219
220 if (likely(typemap[type->proto] == NULL))
221 typemap[type->proto] = type;
222 else
223 err = -EEXIST;
224 xfrm_state_unlock_afinfo(afinfo);
225 return err;
226}
227EXPORT_SYMBOL(xfrm_register_type);
228
229int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
230{
231 struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
232 struct xfrm_type **typemap;
233 int err = 0;
234
235 if (unlikely(afinfo == NULL))
236 return -EAFNOSUPPORT;
237 typemap = afinfo->type_map;
238
239 if (unlikely(typemap[type->proto] != type))
240 err = -ENOENT;
241 else
242 typemap[type->proto] = NULL;
243 xfrm_state_unlock_afinfo(afinfo);
244 return err;
245}
246EXPORT_SYMBOL(xfrm_unregister_type);
247
248static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
249{
250 struct xfrm_state_afinfo *afinfo;
251 struct xfrm_type **typemap;
252 struct xfrm_type *type;
253 int modload_attempted = 0;
254
255retry:
256 afinfo = xfrm_state_get_afinfo(family);
257 if (unlikely(afinfo == NULL))
258 return NULL;
259 typemap = afinfo->type_map;
260
261 type = typemap[proto];
262 if (unlikely(type && !try_module_get(type->owner)))
263 type = NULL;
264 if (!type && !modload_attempted) {
265 xfrm_state_put_afinfo(afinfo);
266 request_module("xfrm-type-%d-%d", family, proto);
267 modload_attempted = 1;
268 goto retry;
269 }
270
271 xfrm_state_put_afinfo(afinfo);
272 return type;
273}
274
275static void xfrm_put_type(struct xfrm_type *type)
276{
277 module_put(type->owner);
278}
279
280int xfrm_register_mode(struct xfrm_mode *mode, int family)
281{
282 struct xfrm_state_afinfo *afinfo;
283 struct xfrm_mode **modemap;
284 int err;
285
286 if (unlikely(mode->encap >= XFRM_MODE_MAX))
287 return -EINVAL;
288
289 afinfo = xfrm_state_lock_afinfo(family);
290 if (unlikely(afinfo == NULL))
291 return -EAFNOSUPPORT;
292
293 err = -EEXIST;
294 modemap = afinfo->mode_map;
295 if (modemap[mode->encap])
296 goto out;
297
298 err = -ENOENT;
299 if (!try_module_get(afinfo->owner))
300 goto out;
301
302 mode->afinfo = afinfo;
303 modemap[mode->encap] = mode;
304 err = 0;
305
306out:
307 xfrm_state_unlock_afinfo(afinfo);
308 return err;
309}
310EXPORT_SYMBOL(xfrm_register_mode);
311
312int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
313{
314 struct xfrm_state_afinfo *afinfo;
315 struct xfrm_mode **modemap;
316 int err;
317
318 if (unlikely(mode->encap >= XFRM_MODE_MAX))
319 return -EINVAL;
320
321 afinfo = xfrm_state_lock_afinfo(family);
322 if (unlikely(afinfo == NULL))
323 return -EAFNOSUPPORT;
324
325 err = -ENOENT;
326 modemap = afinfo->mode_map;
327 if (likely(modemap[mode->encap] == mode)) {
328 modemap[mode->encap] = NULL;
329 module_put(mode->afinfo->owner);
330 err = 0;
331 }
332
333 xfrm_state_unlock_afinfo(afinfo);
334 return err;
335}
336EXPORT_SYMBOL(xfrm_unregister_mode);
337
338static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
339{
340 struct xfrm_state_afinfo *afinfo;
341 struct xfrm_mode *mode;
342 int modload_attempted = 0;
343
344 if (unlikely(encap >= XFRM_MODE_MAX))
345 return NULL;
346
347retry:
348 afinfo = xfrm_state_get_afinfo(family);
349 if (unlikely(afinfo == NULL))
350 return NULL;
351
352 mode = afinfo->mode_map[encap];
353 if (unlikely(mode && !try_module_get(mode->owner)))
354 mode = NULL;
355 if (!mode && !modload_attempted) {
356 xfrm_state_put_afinfo(afinfo);
357 request_module("xfrm-mode-%d-%d", family, encap);
358 modload_attempted = 1;
359 goto retry;
360 }
361
362 xfrm_state_put_afinfo(afinfo);
363 return mode;
364}
365
366static void xfrm_put_mode(struct xfrm_mode *mode)
367{
368 module_put(mode->owner);
369}
370
190static void xfrm_state_gc_destroy(struct xfrm_state *x) 371static void xfrm_state_gc_destroy(struct xfrm_state *x)
191{ 372{
192 del_timer_sync(&x->timer); 373 del_timer_sync(&x->timer);
@@ -196,8 +377,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
196 kfree(x->calg); 377 kfree(x->calg);
197 kfree(x->encap); 378 kfree(x->encap);
198 kfree(x->coaddr); 379 kfree(x->coaddr);
199 if (x->mode) 380 if (x->inner_mode)
200 xfrm_put_mode(x->mode); 381 xfrm_put_mode(x->inner_mode);
382 if (x->outer_mode)
383 xfrm_put_mode(x->outer_mode);
201 if (x->type) { 384 if (x->type) {
202 x->type->destructor(x); 385 x->type->destructor(x);
203 xfrm_put_type(x->type); 386 xfrm_put_type(x->type);
@@ -1699,7 +1882,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
1699} 1882}
1700EXPORT_SYMBOL(xfrm_state_unregister_afinfo); 1883EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
1701 1884
1702struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) 1885static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
1703{ 1886{
1704 struct xfrm_state_afinfo *afinfo; 1887 struct xfrm_state_afinfo *afinfo;
1705 if (unlikely(family >= NPROTO)) 1888 if (unlikely(family >= NPROTO))
@@ -1711,14 +1894,11 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
1711 return afinfo; 1894 return afinfo;
1712} 1895}
1713 1896
1714void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) 1897static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
1715{ 1898{
1716 read_unlock(&xfrm_state_afinfo_lock); 1899 read_unlock(&xfrm_state_afinfo_lock);
1717} 1900}
1718 1901
1719EXPORT_SYMBOL(xfrm_state_get_afinfo);
1720EXPORT_SYMBOL(xfrm_state_put_afinfo);
1721
1722/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ 1902/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
1723void xfrm_state_delete_tunnel(struct xfrm_state *x) 1903void xfrm_state_delete_tunnel(struct xfrm_state *x)
1724{ 1904{
@@ -1769,6 +1949,14 @@ int xfrm_init_state(struct xfrm_state *x)
1769 goto error; 1949 goto error;
1770 1950
1771 err = -EPROTONOSUPPORT; 1951 err = -EPROTONOSUPPORT;
1952 x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
1953 if (x->inner_mode == NULL)
1954 goto error;
1955
1956 if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
1957 family != x->sel.family)
1958 goto error;
1959
1772 x->type = xfrm_get_type(x->id.proto, family); 1960 x->type = xfrm_get_type(x->id.proto, family);
1773 if (x->type == NULL) 1961 if (x->type == NULL)
1774 goto error; 1962 goto error;
@@ -1777,8 +1965,8 @@ int xfrm_init_state(struct xfrm_state *x)
1777 if (err) 1965 if (err)
1778 goto error; 1966 goto error;
1779 1967
1780 x->mode = xfrm_get_mode(x->props.mode, family); 1968 x->outer_mode = xfrm_get_mode(x->props.mode, family);
1781 if (x->mode == NULL) 1969 if (x->outer_mode == NULL)
1782 goto error; 1970 goto error;
1783 1971
1784 x->km.state = XFRM_STATE_VALID; 1972 x->km.state = XFRM_STATE_VALID;