diff options
Diffstat (limited to 'net')
47 files changed, 496 insertions, 309 deletions
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index c32d27af0a3f..7b214cffc956 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/errno.h> /* return codes */ | 23 | #include <linux/errno.h> /* return codes */ |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/slab.h> /* kmalloc(), kfree() */ | 25 | #include <linux/slab.h> /* kmalloc(), kfree() */ |
26 | #include <linux/mm.h> /* verify_area(), etc. */ | 26 | #include <linux/mm.h> |
27 | #include <linux/string.h> /* inline mem*, str* functions */ | 27 | #include <linux/string.h> /* inline mem*, str* functions */ |
28 | #include <linux/init.h> /* __initfunc et al. */ | 28 | #include <linux/init.h> /* __initfunc et al. */ |
29 | #include <asm/byteorder.h> /* htons(), etc. */ | 29 | #include <asm/byteorder.h> /* htons(), etc. */ |
diff --git a/net/atm/common.c b/net/atm/common.c index 6d16be334ea0..e93e838069e8 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/socket.h> /* SOL_SOCKET */ | 12 | #include <linux/socket.h> /* SOL_SOCKET */ |
13 | #include <linux/errno.h> /* error codes */ | 13 | #include <linux/errno.h> /* error codes */ |
14 | #include <linux/capability.h> | 14 | #include <linux/capability.h> |
15 | #include <linux/mm.h> /* verify_area */ | 15 | #include <linux/mm.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/time.h> /* struct timeval */ | 17 | #include <linux/time.h> /* struct timeval */ |
18 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
@@ -540,7 +540,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, | |||
540 | error = -EMSGSIZE; | 540 | error = -EMSGSIZE; |
541 | goto out; | 541 | goto out; |
542 | } | 542 | } |
543 | /* verify_area is done by net/socket.c */ | 543 | |
544 | eff = (size+3) & ~3; /* align to word boundary */ | 544 | eff = (size+3) & ~3; /* align to word boundary */ |
545 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 545 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
546 | error = 0; | 546 | error = 0; |
diff --git a/net/core/datagram.c b/net/core/datagram.c index d1bfd279cc1a..fcee054b6f75 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -115,10 +115,10 @@ out_noerr: | |||
115 | 115 | ||
116 | /** | 116 | /** |
117 | * skb_recv_datagram - Receive a datagram skbuff | 117 | * skb_recv_datagram - Receive a datagram skbuff |
118 | * @sk - socket | 118 | * @sk: socket |
119 | * @flags - MSG_ flags | 119 | * @flags: MSG_ flags |
120 | * @noblock - blocking operation? | 120 | * @noblock: blocking operation? |
121 | * @err - error code returned | 121 | * @err: error code returned |
122 | * | 122 | * |
123 | * Get a datagram skbuff, understands the peeking, nonblocking wakeups | 123 | * Get a datagram skbuff, understands the peeking, nonblocking wakeups |
124 | * and possible races. This replaces identical code in packet, raw and | 124 | * and possible races. This replaces identical code in packet, raw and |
@@ -201,10 +201,10 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) | |||
201 | 201 | ||
202 | /** | 202 | /** |
203 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. | 203 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. |
204 | * @skb - buffer to copy | 204 | * @skb: buffer to copy |
205 | * @offset - offset in the buffer to start copying from | 205 | * @offset: offset in the buffer to start copying from |
206 | * @iovec - io vector to copy to | 206 | * @to: io vector to copy to |
207 | * @len - amount of data to copy from buffer to iovec | 207 | * @len: amount of data to copy from buffer to iovec |
208 | * | 208 | * |
209 | * Note: the iovec is modified during the copy. | 209 | * Note: the iovec is modified during the copy. |
210 | */ | 210 | */ |
@@ -377,9 +377,9 @@ fault: | |||
377 | 377 | ||
378 | /** | 378 | /** |
379 | * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. | 379 | * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. |
380 | * @skb - skbuff | 380 | * @skb: skbuff |
381 | * @hlen - hardware length | 381 | * @hlen: hardware length |
382 | * @iovec - io vector | 382 | * @iov: io vector |
383 | * | 383 | * |
384 | * Caller _must_ check that skb will fit to this iovec. | 384 | * Caller _must_ check that skb will fit to this iovec. |
385 | * | 385 | * |
@@ -425,9 +425,9 @@ fault: | |||
425 | 425 | ||
426 | /** | 426 | /** |
427 | * datagram_poll - generic datagram poll | 427 | * datagram_poll - generic datagram poll |
428 | * @file - file struct | 428 | * @file: file struct |
429 | * @sock - socket | 429 | * @sock: socket |
430 | * @wait - poll table | 430 | * @wait: poll table |
431 | * | 431 | * |
432 | * Datagram poll: Again totally generic. This also handles | 432 | * Datagram poll: Again totally generic. This also handles |
433 | * sequenced packet sockets providing the socket receive queue | 433 | * sequenced packet sockets providing the socket receive queue |
diff --git a/net/core/dev.c b/net/core/dev.c index 7bd4cd4502c4..f5f005846fe1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3091,7 +3091,7 @@ void free_netdev(struct net_device *dev) | |||
3091 | void synchronize_net(void) | 3091 | void synchronize_net(void) |
3092 | { | 3092 | { |
3093 | might_sleep(); | 3093 | might_sleep(); |
3094 | synchronize_kernel(); | 3094 | synchronize_rcu(); |
3095 | } | 3095 | } |
3096 | 3096 | ||
3097 | /** | 3097 | /** |
diff --git a/net/core/iovec.c b/net/core/iovec.c index d57ace949ab8..65e4b56fbc77 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * Verify iovec. The caller must ensure that the iovec is big enough | 33 | * Verify iovec. The caller must ensure that the iovec is big enough |
34 | * to hold the message iovec. | 34 | * to hold the message iovec. |
35 | * | 35 | * |
36 | * Save time not doing verify_area. copy_*_user will make this work | 36 | * Save time not doing access_ok. copy_*_user will make this work |
37 | * in any case. | 37 | * in any case. |
38 | */ | 38 | */ |
39 | 39 | ||
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index 4859b7446c6f..d43d1201275c 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/if.h> | 17 | #include <linux/if.h> |
18 | #include <net/sock.h> | 18 | #include <net/sock.h> |
19 | #include <net/pkt_sched.h> | ||
19 | #include <linux/rtnetlink.h> | 20 | #include <linux/rtnetlink.h> |
20 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
21 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
@@ -74,6 +75,12 @@ void linkwatch_run_queue(void) | |||
74 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); | 75 | clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); |
75 | 76 | ||
76 | if (dev->flags & IFF_UP) { | 77 | if (dev->flags & IFF_UP) { |
78 | if (netif_carrier_ok(dev)) { | ||
79 | WARN_ON(dev->qdisc_sleeping == &noop_qdisc); | ||
80 | dev_activate(dev); | ||
81 | } else | ||
82 | dev_deactivate(dev); | ||
83 | |||
77 | netdev_state_change(dev); | 84 | netdev_state_change(dev); |
78 | } | 85 | } |
79 | 86 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 0a2f67bbef2e..43bdc521e20d 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1953,7 +1953,7 @@ static int neigh_stat_seq_show(struct seq_file *seq, void *v) | |||
1953 | struct neigh_statistics *st = v; | 1953 | struct neigh_statistics *st = v; |
1954 | 1954 | ||
1955 | if (v == SEQ_START_TOKEN) { | 1955 | if (v == SEQ_START_TOKEN) { |
1956 | seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs forced_gc_goal_miss\n"); | 1956 | seq_printf(seq, "entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs\n"); |
1957 | return 0; | 1957 | return 0; |
1958 | } | 1958 | } |
1959 | 1959 | ||
diff --git a/net/core/netfilter.c b/net/core/netfilter.c index e51cfa46950c..22a8f127c4aa 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c | |||
@@ -217,21 +217,10 @@ void nf_debug_ip_local_deliver(struct sk_buff *skb) | |||
217 | * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */ | 217 | * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING. */ |
218 | if (!skb->dev) { | 218 | if (!skb->dev) { |
219 | printk("ip_local_deliver: skb->dev is NULL.\n"); | 219 | printk("ip_local_deliver: skb->dev is NULL.\n"); |
220 | } | 220 | } else { |
221 | else if (strcmp(skb->dev->name, "lo") == 0) { | ||
222 | if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT) | ||
223 | | (1 << NF_IP_POST_ROUTING) | ||
224 | | (1 << NF_IP_PRE_ROUTING) | ||
225 | | (1 << NF_IP_LOCAL_IN))) { | ||
226 | printk("ip_local_deliver: bad loopback skb: "); | ||
227 | debug_print_hooks_ip(skb->nf_debug); | ||
228 | nf_dump_skb(PF_INET, skb); | ||
229 | } | ||
230 | } | ||
231 | else { | ||
232 | if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING) | 221 | if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING) |
233 | | (1<<NF_IP_LOCAL_IN))) { | 222 | | (1<<NF_IP_LOCAL_IN))) { |
234 | printk("ip_local_deliver: bad non-lo skb: "); | 223 | printk("ip_local_deliver: bad skb: "); |
235 | debug_print_hooks_ip(skb->nf_debug); | 224 | debug_print_hooks_ip(skb->nf_debug); |
236 | nf_dump_skb(PF_INET, skb); | 225 | nf_dump_skb(PF_INET, skb); |
237 | } | 226 | } |
@@ -247,8 +236,6 @@ void nf_debug_ip_loopback_xmit(struct sk_buff *newskb) | |||
247 | debug_print_hooks_ip(newskb->nf_debug); | 236 | debug_print_hooks_ip(newskb->nf_debug); |
248 | nf_dump_skb(PF_INET, newskb); | 237 | nf_dump_skb(PF_INET, newskb); |
249 | } | 238 | } |
250 | /* Clear to avoid confusing input check */ | ||
251 | newskb->nf_debug = 0; | ||
252 | } | 239 | } |
253 | 240 | ||
254 | void nf_debug_ip_finish_output2(struct sk_buff *skb) | 241 | void nf_debug_ip_finish_output2(struct sk_buff *skb) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d8c198e42f90..00caf4b318b2 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -86,30 +86,33 @@ struct sock *rtnl; | |||
86 | 86 | ||
87 | struct rtnetlink_link * rtnetlink_links[NPROTO]; | 87 | struct rtnetlink_link * rtnetlink_links[NPROTO]; |
88 | 88 | ||
89 | static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = | 89 | static const int rtm_min[RTM_NR_FAMILIES] = |
90 | { | 90 | { |
91 | NLMSG_LENGTH(sizeof(struct ifinfomsg)), | 91 | [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), |
92 | NLMSG_LENGTH(sizeof(struct ifaddrmsg)), | 92 | [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), |
93 | NLMSG_LENGTH(sizeof(struct rtmsg)), | 93 | [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), |
94 | NLMSG_LENGTH(sizeof(struct ndmsg)), | 94 | [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)), |
95 | NLMSG_LENGTH(sizeof(struct rtmsg)), | 95 | [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), |
96 | NLMSG_LENGTH(sizeof(struct tcmsg)), | 96 | [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
97 | NLMSG_LENGTH(sizeof(struct tcmsg)), | 97 | [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
98 | NLMSG_LENGTH(sizeof(struct tcmsg)), | 98 | [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), |
99 | NLMSG_LENGTH(sizeof(struct tcamsg)) | 99 | [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), |
100 | [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
101 | [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
102 | [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), | ||
100 | }; | 103 | }; |
101 | 104 | ||
102 | static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = | 105 | static const int rta_max[RTM_NR_FAMILIES] = |
103 | { | 106 | { |
104 | IFLA_MAX, | 107 | [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, |
105 | IFA_MAX, | 108 | [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, |
106 | RTA_MAX, | 109 | [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, |
107 | NDA_MAX, | 110 | [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX, |
108 | RTA_MAX, | 111 | [RTM_FAM(RTM_NEWRULE)] = RTA_MAX, |
109 | TCA_MAX, | 112 | [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, |
110 | TCA_MAX, | 113 | [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, |
111 | TCA_MAX, | 114 | [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, |
112 | TCAA_MAX | 115 | [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, |
113 | }; | 116 | }; |
114 | 117 | ||
115 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) | 118 | void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) |
@@ -606,27 +609,33 @@ static inline int rtnetlink_rcv_skb(struct sk_buff *skb) | |||
606 | 609 | ||
607 | /* | 610 | /* |
608 | * rtnetlink input queue processing routine: | 611 | * rtnetlink input queue processing routine: |
609 | * - try to acquire shared lock. If it is failed, defer processing. | 612 | * - process as much as there was in the queue upon entry. |
610 | * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, | 613 | * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, |
611 | * that will occur, when a dump started and/or acquisition of | 614 | * that will occur, when a dump started. |
612 | * exclusive lock failed. | ||
613 | */ | 615 | */ |
614 | 616 | ||
615 | static void rtnetlink_rcv(struct sock *sk, int len) | 617 | static void rtnetlink_rcv(struct sock *sk, int len) |
616 | { | 618 | { |
619 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
620 | |||
617 | do { | 621 | do { |
618 | struct sk_buff *skb; | 622 | struct sk_buff *skb; |
619 | 623 | ||
620 | if (rtnl_shlock_nowait()) | 624 | rtnl_lock(); |
621 | return; | 625 | |
626 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) | ||
627 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
622 | 628 | ||
623 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 629 | for (; qlen; qlen--) { |
630 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
624 | if (rtnetlink_rcv_skb(skb)) { | 631 | if (rtnetlink_rcv_skb(skb)) { |
625 | if (skb->len) | 632 | if (skb->len) |
626 | skb_queue_head(&sk->sk_receive_queue, | 633 | skb_queue_head(&sk->sk_receive_queue, |
627 | skb); | 634 | skb); |
628 | else | 635 | else { |
629 | kfree_skb(skb); | 636 | kfree_skb(skb); |
637 | qlen--; | ||
638 | } | ||
630 | break; | 639 | break; |
631 | } | 640 | } |
632 | kfree_skb(skb); | 641 | kfree_skb(skb); |
@@ -635,10 +644,10 @@ static void rtnetlink_rcv(struct sock *sk, int len) | |||
635 | up(&rtnl_sem); | 644 | up(&rtnl_sem); |
636 | 645 | ||
637 | netdev_run_todo(); | 646 | netdev_run_todo(); |
638 | } while (rtnl && rtnl->sk_receive_queue.qlen); | 647 | } while (qlen); |
639 | } | 648 | } |
640 | 649 | ||
641 | static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] = | 650 | static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = |
642 | { | 651 | { |
643 | [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, | 652 | [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, |
644 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, | 653 | [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, |
diff --git a/net/core/sock.c b/net/core/sock.c index 5c2f72fa1013..98171ddd7e7d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -616,10 +616,10 @@ lenout: | |||
616 | 616 | ||
617 | /** | 617 | /** |
618 | * sk_alloc - All socket objects are allocated here | 618 | * sk_alloc - All socket objects are allocated here |
619 | * @family - protocol family | 619 | * @family: protocol family |
620 | * @priority - for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) | 620 | * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) |
621 | * @prot - struct proto associated with this new sock instance | 621 | * @prot: struct proto associated with this new sock instance |
622 | * @zero_it - if we should zero the newly allocated sock | 622 | * @zero_it: if we should zero the newly allocated sock |
623 | */ | 623 | */ |
624 | struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | 624 | struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) |
625 | { | 625 | { |
@@ -970,8 +970,8 @@ static void __release_sock(struct sock *sk) | |||
970 | 970 | ||
971 | /** | 971 | /** |
972 | * sk_wait_data - wait for data to arrive at sk_receive_queue | 972 | * sk_wait_data - wait for data to arrive at sk_receive_queue |
973 | * sk - sock to wait on | 973 | * @sk: sock to wait on |
974 | * timeo - for how long | 974 | * @timeo: for how long |
975 | * | 975 | * |
976 | * Now socket state including sk->sk_err is changed only under lock, | 976 | * Now socket state including sk->sk_err is changed only under lock, |
977 | * hence we may omit checks after joining wait queue. | 977 | * hence we may omit checks after joining wait queue. |
diff --git a/net/core/stream.c b/net/core/stream.c index 1e27a57b5a97..ac9edfdf8742 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | /** | 22 | /** |
23 | * sk_stream_write_space - stream socket write_space callback. | 23 | * sk_stream_write_space - stream socket write_space callback. |
24 | * sk - socket | 24 | * @sk: socket |
25 | * | 25 | * |
26 | * FIXME: write proper description | 26 | * FIXME: write proper description |
27 | */ | 27 | */ |
@@ -43,8 +43,8 @@ EXPORT_SYMBOL(sk_stream_write_space); | |||
43 | 43 | ||
44 | /** | 44 | /** |
45 | * sk_stream_wait_connect - Wait for a socket to get into the connected state | 45 | * sk_stream_wait_connect - Wait for a socket to get into the connected state |
46 | * @sk - sock to wait on | 46 | * @sk: sock to wait on |
47 | * @timeo_p - for how long to wait | 47 | * @timeo_p: for how long to wait |
48 | * | 48 | * |
49 | * Must be called with the socket locked. | 49 | * Must be called with the socket locked. |
50 | */ | 50 | */ |
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(sk_stream_wait_connect); | |||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * sk_stream_closing - Return 1 if we still have things to send in our buffers. | 81 | * sk_stream_closing - Return 1 if we still have things to send in our buffers. |
82 | * @sk - socket to verify | 82 | * @sk: socket to verify |
83 | */ | 83 | */ |
84 | static inline int sk_stream_closing(struct sock *sk) | 84 | static inline int sk_stream_closing(struct sock *sk) |
85 | { | 85 | { |
@@ -107,8 +107,8 @@ EXPORT_SYMBOL(sk_stream_wait_close); | |||
107 | 107 | ||
108 | /** | 108 | /** |
109 | * sk_stream_wait_memory - Wait for more memory for a socket | 109 | * sk_stream_wait_memory - Wait for more memory for a socket |
110 | * @sk - socket to wait for memory | 110 | * @sk: socket to wait for memory |
111 | * @timeo_p - for how long | 111 | * @timeo_p: for how long |
112 | */ | 112 | */ |
113 | int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | 113 | int sk_stream_wait_memory(struct sock *sk, long *timeo_p) |
114 | { | 114 | { |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index c2a0346f423b..e6e23eb14428 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -1411,21 +1411,22 @@ static struct file_operations dn_dev_seq_fops = { | |||
1411 | 1411 | ||
1412 | #endif /* CONFIG_PROC_FS */ | 1412 | #endif /* CONFIG_PROC_FS */ |
1413 | 1413 | ||
1414 | static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] = | 1414 | static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = |
1415 | { | 1415 | { |
1416 | [4] = { .doit = dn_dev_rtm_newaddr, }, | 1416 | [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, }, |
1417 | [5] = { .doit = dn_dev_rtm_deladdr, }, | 1417 | [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, }, |
1418 | [6] = { .dumpit = dn_dev_dump_ifaddr, }, | 1418 | [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, }, |
1419 | |||
1420 | #ifdef CONFIG_DECNET_ROUTER | 1419 | #ifdef CONFIG_DECNET_ROUTER |
1421 | [8] = { .doit = dn_fib_rtm_newroute, }, | 1420 | [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, |
1422 | [9] = { .doit = dn_fib_rtm_delroute, }, | 1421 | [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, |
1423 | [10] = { .doit = dn_cache_getroute, .dumpit = dn_fib_dump, }, | 1422 | [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, |
1424 | [16] = { .doit = dn_fib_rtm_newrule, }, | 1423 | .dumpit = dn_fib_dump, }, |
1425 | [17] = { .doit = dn_fib_rtm_delrule, }, | 1424 | [RTM_NEWRULE - RTM_BASE] = { .doit = dn_fib_rtm_newrule, }, |
1426 | [18] = { .dumpit = dn_fib_dump_rules, }, | 1425 | [RTM_DELRULE - RTM_BASE] = { .doit = dn_fib_rtm_delrule, }, |
1426 | [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, }, | ||
1427 | #else | 1427 | #else |
1428 | [10] = { .doit = dn_cache_getroute, .dumpit = dn_cache_dump, }, | 1428 | [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, |
1429 | .dumpit = dn_cache_dump, | ||
1429 | #endif | 1430 | #endif |
1430 | 1431 | ||
1431 | }; | 1432 | }; |
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index f86a6259fd12..284a9998e53d 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c | |||
@@ -119,8 +119,9 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) | |||
119 | static void dnrmg_receive_user_sk(struct sock *sk, int len) | 119 | static void dnrmg_receive_user_sk(struct sock *sk, int len) |
120 | { | 120 | { |
121 | struct sk_buff *skb; | 121 | struct sk_buff *skb; |
122 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
122 | 123 | ||
123 | while((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 124 | for (; qlen && (skb = skb_dequeue(&sk->sk_receive_queue)); qlen--) { |
124 | dnrmg_receive_user_skb(skb); | 125 | dnrmg_receive_user_skb(skb); |
125 | kfree_skb(skb); | 126 | kfree_skb(skb); |
126 | } | 127 | } |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index eea7ef010776..abbc6d5c183e 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa) | |||
1107 | } | 1107 | } |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { | 1110 | static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = { |
1111 | [4] = { .doit = inet_rtm_newaddr, }, | 1111 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, }, |
1112 | [5] = { .doit = inet_rtm_deladdr, }, | 1112 | [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, }, |
1113 | [6] = { .dumpit = inet_dump_ifaddr, }, | 1113 | [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, }, |
1114 | [8] = { .doit = inet_rtm_newroute, }, | 1114 | [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, }, |
1115 | [9] = { .doit = inet_rtm_delroute, }, | 1115 | [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, }, |
1116 | [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, }, | 1116 | [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute, |
1117 | .dumpit = inet_dump_fib, }, | ||
1117 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1118 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1118 | [16] = { .doit = inet_rtm_newrule, }, | 1119 | [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, }, |
1119 | [17] = { .doit = inet_rtm_delrule, }, | 1120 | [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, }, |
1120 | [18] = { .dumpit = inet_dump_rules, }, | 1121 | [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, }, |
1121 | #endif | 1122 | #endif |
1122 | }; | 1123 | }; |
1123 | 1124 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 38f69532a029..24fe3e00b42b 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -111,6 +111,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
111 | #ifdef CONFIG_NETFILTER_DEBUG | 111 | #ifdef CONFIG_NETFILTER_DEBUG |
112 | nf_debug_ip_loopback_xmit(newskb); | 112 | nf_debug_ip_loopback_xmit(newskb); |
113 | #endif | 113 | #endif |
114 | nf_reset(newskb); | ||
114 | netif_rx(newskb); | 115 | netif_rx(newskb); |
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 2b87c1974be6..721ddbf522b4 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -819,6 +819,7 @@ static int tcp_error(struct sk_buff *skb, | |||
819 | */ | 819 | */ |
820 | /* FIXME: Source route IP option packets --RR */ | 820 | /* FIXME: Source route IP option packets --RR */ |
821 | if (hooknum == NF_IP_PRE_ROUTING | 821 | if (hooknum == NF_IP_PRE_ROUTING |
822 | && skb->ip_summed != CHECKSUM_UNNECESSARY | ||
822 | && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, | 823 | && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, |
823 | skb->ip_summed == CHECKSUM_HW ? skb->csum | 824 | skb->ip_summed == CHECKSUM_HW ? skb->csum |
824 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { | 825 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 9e40dffc204f..e5746b674413 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -546,20 +546,18 @@ ipq_rcv_skb(struct sk_buff *skb) | |||
546 | static void | 546 | static void |
547 | ipq_rcv_sk(struct sock *sk, int len) | 547 | ipq_rcv_sk(struct sock *sk, int len) |
548 | { | 548 | { |
549 | do { | 549 | struct sk_buff *skb; |
550 | struct sk_buff *skb; | 550 | unsigned int qlen; |
551 | 551 | ||
552 | if (down_trylock(&ipqnl_sem)) | 552 | down(&ipqnl_sem); |
553 | return; | ||
554 | 553 | ||
555 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 554 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
556 | ipq_rcv_skb(skb); | 555 | skb = skb_dequeue(&sk->sk_receive_queue); |
557 | kfree_skb(skb); | 556 | ipq_rcv_skb(skb); |
558 | } | 557 | kfree_skb(skb); |
558 | } | ||
559 | 559 | ||
560 | up(&ipqnl_sem); | 560 | up(&ipqnl_sem); |
561 | |||
562 | } while (ipqnl && ipqnl->sk_receive_queue.qlen); | ||
563 | } | 561 | } |
564 | 562 | ||
565 | static int | 563 | static int |
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 01b4a3c814d3..47449ba83eb9 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -103,13 +103,15 @@ static struct nf_hook_ops ipt_ops[] = { | |||
103 | .hook = ipt_hook, | 103 | .hook = ipt_hook, |
104 | .pf = PF_INET, | 104 | .pf = PF_INET, |
105 | .hooknum = NF_IP_PRE_ROUTING, | 105 | .hooknum = NF_IP_PRE_ROUTING, |
106 | .priority = NF_IP_PRI_RAW | 106 | .priority = NF_IP_PRI_RAW, |
107 | .owner = THIS_MODULE, | ||
107 | }, | 108 | }, |
108 | { | 109 | { |
109 | .hook = ipt_hook, | 110 | .hook = ipt_hook, |
110 | .pf = PF_INET, | 111 | .pf = PF_INET, |
111 | .hooknum = NF_IP_LOCAL_OUT, | 112 | .hooknum = NF_IP_LOCAL_OUT, |
112 | .priority = NF_IP_PRI_RAW | 113 | .priority = NF_IP_PRI_RAW, |
114 | .owner = THIS_MODULE, | ||
113 | }, | 115 | }, |
114 | }; | 116 | }; |
115 | 117 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index bb90a0c3a91e..199311746932 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -397,7 +397,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v) | |||
397 | struct rt_cache_stat *st = v; | 397 | struct rt_cache_stat *st = v; |
398 | 398 | ||
399 | if (v == SEQ_START_TOKEN) { | 399 | if (v == SEQ_START_TOKEN) { |
400 | seq_printf(seq, "entries in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n"); | 400 | seq_printf(seq, "entries in_hit in_slow_tot in_slow_mc in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n"); |
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
@@ -2843,7 +2843,7 @@ ctl_table ipv4_route_table[] = { | |||
2843 | .procname = "flush", | 2843 | .procname = "flush", |
2844 | .data = &flush_delay, | 2844 | .data = &flush_delay, |
2845 | .maxlen = sizeof(int), | 2845 | .maxlen = sizeof(int), |
2846 | .mode = 0644, | 2846 | .mode = 0200, |
2847 | .proc_handler = &ipv4_sysctl_rtcache_flush, | 2847 | .proc_handler = &ipv4_sysctl_rtcache_flush, |
2848 | .strategy = &ipv4_sysctl_rtcache_flush_strategy, | 2848 | .strategy = &ipv4_sysctl_rtcache_flush_strategy, |
2849 | }, | 2849 | }, |
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 313c1408da33..8faa8948f75c 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c | |||
@@ -777,8 +777,9 @@ static inline void tcpdiag_rcv_skb(struct sk_buff *skb) | |||
777 | static void tcpdiag_rcv(struct sock *sk, int len) | 777 | static void tcpdiag_rcv(struct sock *sk, int len) |
778 | { | 778 | { |
779 | struct sk_buff *skb; | 779 | struct sk_buff *skb; |
780 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
780 | 781 | ||
781 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 782 | while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) { |
782 | tcpdiag_rcv_skb(skb); | 783 | tcpdiag_rcv_skb(skb); |
783 | kfree_skb(skb); | 784 | kfree_skb(skb); |
784 | } | 785 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3ac6659869c4..dad98e4a5043 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -222,10 +222,13 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum) | |||
222 | int rover; | 222 | int rover; |
223 | 223 | ||
224 | spin_lock(&tcp_portalloc_lock); | 224 | spin_lock(&tcp_portalloc_lock); |
225 | rover = tcp_port_rover; | 225 | if (tcp_port_rover < low) |
226 | rover = low; | ||
227 | else | ||
228 | rover = tcp_port_rover; | ||
226 | do { | 229 | do { |
227 | rover++; | 230 | rover++; |
228 | if (rover < low || rover > high) | 231 | if (rover > high) |
229 | rover = low; | 232 | rover = low; |
230 | head = &tcp_bhash[tcp_bhashfn(rover)]; | 233 | head = &tcp_bhash[tcp_bhashfn(rover)]; |
231 | spin_lock(&head->lock); | 234 | spin_lock(&head->lock); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 7fe2afd2e669..b2b60f3e9cdd 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -8,7 +8,10 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <asm/bug.h> | ||
12 | #include <linux/compiler.h> | ||
11 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | #include <linux/inetdevice.h> | ||
12 | #include <net/xfrm.h> | 15 | #include <net/xfrm.h> |
13 | #include <net/ip.h> | 16 | #include <net/ip.h> |
14 | 17 | ||
@@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
152 | x->u.rt.rt_dst = rt0->rt_dst; | 155 | x->u.rt.rt_dst = rt0->rt_dst; |
153 | x->u.rt.rt_gateway = rt->rt_gateway; | 156 | x->u.rt.rt_gateway = rt->rt_gateway; |
154 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; | 157 | x->u.rt.rt_spec_dst = rt0->rt_spec_dst; |
158 | x->u.rt.idev = rt0->idev; | ||
159 | in_dev_hold(rt0->idev); | ||
155 | header_len -= x->u.dst.xfrm->props.header_len; | 160 | header_len -= x->u.dst.xfrm->props.header_len; |
156 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 161 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
157 | } | 162 | } |
@@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
243 | path->ops->update_pmtu(path, mtu); | 248 | path->ops->update_pmtu(path, mtu); |
244 | } | 249 | } |
245 | 250 | ||
251 | static void xfrm4_dst_destroy(struct dst_entry *dst) | ||
252 | { | ||
253 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
254 | |||
255 | if (likely(xdst->u.rt.idev)) | ||
256 | in_dev_put(xdst->u.rt.idev); | ||
257 | xfrm_dst_destroy(xdst); | ||
258 | } | ||
259 | |||
260 | static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
261 | int unregister) | ||
262 | { | ||
263 | struct xfrm_dst *xdst; | ||
264 | |||
265 | if (!unregister) | ||
266 | return; | ||
267 | |||
268 | xdst = (struct xfrm_dst *)dst; | ||
269 | if (xdst->u.rt.idev->dev == dev) { | ||
270 | struct in_device *loopback_idev = in_dev_get(&loopback_dev); | ||
271 | BUG_ON(!loopback_idev); | ||
272 | |||
273 | do { | ||
274 | in_dev_put(xdst->u.rt.idev); | ||
275 | xdst->u.rt.idev = loopback_idev; | ||
276 | in_dev_hold(loopback_idev); | ||
277 | xdst = (struct xfrm_dst *)xdst->u.dst.child; | ||
278 | } while (xdst->u.dst.xfrm); | ||
279 | |||
280 | __in_dev_put(loopback_idev); | ||
281 | } | ||
282 | |||
283 | xfrm_dst_ifdown(dst, dev); | ||
284 | } | ||
285 | |||
246 | static struct dst_ops xfrm4_dst_ops = { | 286 | static struct dst_ops xfrm4_dst_ops = { |
247 | .family = AF_INET, | 287 | .family = AF_INET, |
248 | .protocol = __constant_htons(ETH_P_IP), | 288 | .protocol = __constant_htons(ETH_P_IP), |
249 | .gc = xfrm4_garbage_collect, | 289 | .gc = xfrm4_garbage_collect, |
250 | .update_pmtu = xfrm4_update_pmtu, | 290 | .update_pmtu = xfrm4_update_pmtu, |
291 | .destroy = xfrm4_dst_destroy, | ||
292 | .ifdown = xfrm4_dst_ifdown, | ||
251 | .gc_thresh = 1024, | 293 | .gc_thresh = 1024, |
252 | .entry_size = sizeof(struct xfrm_dst), | 294 | .entry_size = sizeof(struct xfrm_dst), |
253 | }; | 295 | }; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7196ac2f2d16..7744a2592693 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3076,7 +3076,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3076 | netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); | 3076 | netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); |
3077 | } | 3077 | } |
3078 | 3078 | ||
3079 | static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { | 3079 | static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { |
3080 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, | 3080 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, |
3081 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, | 3081 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, |
3082 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, | 3082 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index c54830b89593..750943e2d34e 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -549,20 +549,18 @@ ipq_rcv_skb(struct sk_buff *skb) | |||
549 | static void | 549 | static void |
550 | ipq_rcv_sk(struct sock *sk, int len) | 550 | ipq_rcv_sk(struct sock *sk, int len) |
551 | { | 551 | { |
552 | do { | 552 | struct sk_buff *skb; |
553 | struct sk_buff *skb; | 553 | unsigned int qlen; |
554 | 554 | ||
555 | if (down_trylock(&ipqnl_sem)) | 555 | down(&ipqnl_sem); |
556 | return; | ||
557 | 556 | ||
558 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 557 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
559 | ipq_rcv_skb(skb); | 558 | skb = skb_dequeue(&sk->sk_receive_queue); |
560 | kfree_skb(skb); | 559 | ipq_rcv_skb(skb); |
561 | } | 560 | kfree_skb(skb); |
561 | } | ||
562 | 562 | ||
563 | up(&ipqnl_sem); | 563 | up(&ipqnl_sem); |
564 | |||
565 | } while (ipqnl && ipqnl->sk_receive_queue.qlen); | ||
566 | } | 564 | } |
567 | 565 | ||
568 | static int | 566 | static int |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 1352c1d9bf4d..617645bc5ed6 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -455,11 +455,11 @@ csum_copy_err: | |||
455 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | 455 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, |
456 | struct raw6_sock *rp) | 456 | struct raw6_sock *rp) |
457 | { | 457 | { |
458 | struct inet_sock *inet = inet_sk(sk); | ||
459 | struct sk_buff *skb; | 458 | struct sk_buff *skb; |
460 | int err = 0; | 459 | int err = 0; |
461 | int offset; | 460 | int offset; |
462 | int len; | 461 | int len; |
462 | int total_len; | ||
463 | u32 tmp_csum; | 463 | u32 tmp_csum; |
464 | u16 csum; | 464 | u16 csum; |
465 | 465 | ||
@@ -470,7 +470,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | |||
470 | goto out; | 470 | goto out; |
471 | 471 | ||
472 | offset = rp->offset; | 472 | offset = rp->offset; |
473 | if (offset >= inet->cork.length - 1) { | 473 | total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data); |
474 | if (offset >= total_len - 1) { | ||
474 | err = -EINVAL; | 475 | err = -EINVAL; |
475 | ip6_flush_pending_frames(sk); | 476 | ip6_flush_pending_frames(sk); |
476 | goto out; | 477 | goto out; |
@@ -514,7 +515,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | |||
514 | 515 | ||
515 | tmp_csum = csum_ipv6_magic(&fl->fl6_src, | 516 | tmp_csum = csum_ipv6_magic(&fl->fl6_src, |
516 | &fl->fl6_dst, | 517 | &fl->fl6_dst, |
517 | inet->cork.length, fl->proto, tmp_csum); | 518 | total_len, fl->proto, tmp_csum); |
518 | 519 | ||
519 | if (tmp_csum == 0) | 520 | if (tmp_csum == 0) |
520 | tmp_csum = -1; | 521 | tmp_csum = -1; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 183802902c02..3bf8a0254f81 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2005,7 +2005,7 @@ ctl_table ipv6_route_table[] = { | |||
2005 | .procname = "flush", | 2005 | .procname = "flush", |
2006 | .data = &flush_delay, | 2006 | .data = &flush_delay, |
2007 | .maxlen = sizeof(int), | 2007 | .maxlen = sizeof(int), |
2008 | .mode = 0644, | 2008 | .mode = 0200, |
2009 | .proc_handler = &ipv6_sysctl_rtcache_flush | 2009 | .proc_handler = &ipv6_sysctl_rtcache_flush |
2010 | }, | 2010 | }, |
2011 | { | 2011 | { |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4760c85e19db..0f69e800a0ad 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -139,9 +139,12 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | |||
139 | int rover; | 139 | int rover; |
140 | 140 | ||
141 | spin_lock(&tcp_portalloc_lock); | 141 | spin_lock(&tcp_portalloc_lock); |
142 | rover = tcp_port_rover; | 142 | if (tcp_port_rover < low) |
143 | rover = low; | ||
144 | else | ||
145 | rover = tcp_port_rover; | ||
143 | do { rover++; | 146 | do { rover++; |
144 | if ((rover < low) || (rover > high)) | 147 | if (rover > high) |
145 | rover = low; | 148 | rover = low; |
146 | head = &tcp_bhash[tcp_bhashfn(rover)]; | 149 | head = &tcp_bhash[tcp_bhashfn(rover)]; |
147 | spin_lock(&head->lock); | 150 | spin_lock(&head->lock); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8a4f37de4d2d..4429b1a1fe5f 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -11,7 +11,11 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <asm/bug.h> | ||
15 | #include <linux/compiler.h> | ||
14 | #include <linux/config.h> | 16 | #include <linux/config.h> |
17 | #include <linux/netdevice.h> | ||
18 | #include <net/addrconf.h> | ||
15 | #include <net/xfrm.h> | 19 | #include <net/xfrm.h> |
16 | #include <net/ip.h> | 20 | #include <net/ip.h> |
17 | #include <net/ipv6.h> | 21 | #include <net/ipv6.h> |
@@ -166,6 +170,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
166 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); | 170 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); |
167 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; | 171 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; |
168 | x->u.rt6.rt6i_src = rt0->rt6i_src; | 172 | x->u.rt6.rt6i_src = rt0->rt6i_src; |
173 | x->u.rt6.rt6i_idev = rt0->rt6i_idev; | ||
174 | in6_dev_hold(rt0->rt6i_idev); | ||
169 | header_len -= x->u.dst.xfrm->props.header_len; | 175 | header_len -= x->u.dst.xfrm->props.header_len; |
170 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 176 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
171 | } | 177 | } |
@@ -251,11 +257,48 @@ static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
251 | path->ops->update_pmtu(path, mtu); | 257 | path->ops->update_pmtu(path, mtu); |
252 | } | 258 | } |
253 | 259 | ||
260 | static void xfrm6_dst_destroy(struct dst_entry *dst) | ||
261 | { | ||
262 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
263 | |||
264 | if (likely(xdst->u.rt6.rt6i_idev)) | ||
265 | in6_dev_put(xdst->u.rt6.rt6i_idev); | ||
266 | xfrm_dst_destroy(xdst); | ||
267 | } | ||
268 | |||
269 | static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
270 | int unregister) | ||
271 | { | ||
272 | struct xfrm_dst *xdst; | ||
273 | |||
274 | if (!unregister) | ||
275 | return; | ||
276 | |||
277 | xdst = (struct xfrm_dst *)dst; | ||
278 | if (xdst->u.rt6.rt6i_idev->dev == dev) { | ||
279 | struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev); | ||
280 | BUG_ON(!loopback_idev); | ||
281 | |||
282 | do { | ||
283 | in6_dev_put(xdst->u.rt6.rt6i_idev); | ||
284 | xdst->u.rt6.rt6i_idev = loopback_idev; | ||
285 | in6_dev_hold(loopback_idev); | ||
286 | xdst = (struct xfrm_dst *)xdst->u.dst.child; | ||
287 | } while (xdst->u.dst.xfrm); | ||
288 | |||
289 | __in6_dev_put(loopback_idev); | ||
290 | } | ||
291 | |||
292 | xfrm_dst_ifdown(dst, dev); | ||
293 | } | ||
294 | |||
254 | static struct dst_ops xfrm6_dst_ops = { | 295 | static struct dst_ops xfrm6_dst_ops = { |
255 | .family = AF_INET6, | 296 | .family = AF_INET6, |
256 | .protocol = __constant_htons(ETH_P_IPV6), | 297 | .protocol = __constant_htons(ETH_P_IPV6), |
257 | .gc = xfrm6_garbage_collect, | 298 | .gc = xfrm6_garbage_collect, |
258 | .update_pmtu = xfrm6_update_pmtu, | 299 | .update_pmtu = xfrm6_update_pmtu, |
300 | .destroy = xfrm6_dst_destroy, | ||
301 | .ifdown = xfrm6_dst_ifdown, | ||
259 | .gc_thresh = 1024, | 302 | .gc_thresh = 1024, |
260 | .entry_size = sizeof(struct xfrm_dst), | 303 | .entry_size = sizeof(struct xfrm_dst), |
261 | }; | 304 | }; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 29a5fd231eac..4ee392066148 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -373,7 +373,6 @@ static int netlink_release(struct socket *sock) | |||
373 | nlk->cb->done(nlk->cb); | 373 | nlk->cb->done(nlk->cb); |
374 | netlink_destroy_callback(nlk->cb); | 374 | netlink_destroy_callback(nlk->cb); |
375 | nlk->cb = NULL; | 375 | nlk->cb = NULL; |
376 | __sock_put(sk); | ||
377 | } | 376 | } |
378 | spin_unlock(&nlk->cb_lock); | 377 | spin_unlock(&nlk->cb_lock); |
379 | 378 | ||
@@ -1099,7 +1098,6 @@ static int netlink_dump(struct sock *sk) | |||
1099 | spin_unlock(&nlk->cb_lock); | 1098 | spin_unlock(&nlk->cb_lock); |
1100 | 1099 | ||
1101 | netlink_destroy_callback(cb); | 1100 | netlink_destroy_callback(cb); |
1102 | __sock_put(sk); | ||
1103 | return 0; | 1101 | return 0; |
1104 | } | 1102 | } |
1105 | 1103 | ||
@@ -1138,7 +1136,6 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1138 | return -EBUSY; | 1136 | return -EBUSY; |
1139 | } | 1137 | } |
1140 | nlk->cb = cb; | 1138 | nlk->cb = cb; |
1141 | sock_hold(sk); | ||
1142 | spin_unlock(&nlk->cb_lock); | 1139 | spin_unlock(&nlk->cb_lock); |
1143 | 1140 | ||
1144 | netlink_dump(sk); | 1141 | netlink_dump(sk); |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 9c118baed9dc..b0941186f867 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -185,7 +185,7 @@ config NET_SCH_GRED | |||
185 | depends on NET_SCHED | 185 | depends on NET_SCHED |
186 | help | 186 | help |
187 | Say Y here if you want to use the Generic Random Early Detection | 187 | Say Y here if you want to use the Generic Random Early Detection |
188 | (RED) packet scheduling algorithm for some of your network devices | 188 | (GRED) packet scheduling algorithm for some of your network devices |
189 | (see the top of <file:net/sched/sch_red.c> for details and | 189 | (see the top of <file:net/sched/sch_red.c> for details and |
190 | references about the algorithm). | 190 | references about the algorithm). |
191 | 191 | ||
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 5e6cc371b39e..cafcb084098d 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -171,10 +171,10 @@ repeat: | |||
171 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); | 171 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); |
172 | skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); | 172 | skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd); |
173 | } | 173 | } |
174 | if (ret != TC_ACT_PIPE) | ||
175 | goto exec_done; | ||
176 | if (ret == TC_ACT_REPEAT) | 174 | if (ret == TC_ACT_REPEAT) |
177 | goto repeat; /* we need a ttl - JHS */ | 175 | goto repeat; /* we need a ttl - JHS */ |
176 | if (ret != TC_ACT_PIPE) | ||
177 | goto exec_done; | ||
178 | } | 178 | } |
179 | act = a->next; | 179 | act = a->next; |
180 | } | 180 | } |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 4323a74eea30..07977f8f2679 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -1289,6 +1289,7 @@ static int __init pktsched_init(void) | |||
1289 | 1289 | ||
1290 | subsys_initcall(pktsched_init); | 1290 | subsys_initcall(pktsched_init); |
1291 | 1291 | ||
1292 | EXPORT_SYMBOL(qdisc_lookup); | ||
1292 | EXPORT_SYMBOL(qdisc_get_rtab); | 1293 | EXPORT_SYMBOL(qdisc_get_rtab); |
1293 | EXPORT_SYMBOL(qdisc_put_rtab); | 1294 | EXPORT_SYMBOL(qdisc_put_rtab); |
1294 | EXPORT_SYMBOL(register_qdisc); | 1295 | EXPORT_SYMBOL(register_qdisc); |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 8c01e023f02e..87e48a4e1051 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -179,6 +179,7 @@ requeue: | |||
179 | netif_schedule(dev); | 179 | netif_schedule(dev); |
180 | return 1; | 180 | return 1; |
181 | } | 181 | } |
182 | BUG_ON((int) q->q.qlen < 0); | ||
182 | return q->q.qlen; | 183 | return q->q.qlen; |
183 | } | 184 | } |
184 | 185 | ||
@@ -539,6 +540,10 @@ void dev_activate(struct net_device *dev) | |||
539 | write_unlock_bh(&qdisc_tree_lock); | 540 | write_unlock_bh(&qdisc_tree_lock); |
540 | } | 541 | } |
541 | 542 | ||
543 | if (!netif_carrier_ok(dev)) | ||
544 | /* Delay activation until next carrier-on event */ | ||
545 | return; | ||
546 | |||
542 | spin_lock_bh(&dev->queue_lock); | 547 | spin_lock_bh(&dev->queue_lock); |
543 | rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); | 548 | rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); |
544 | if (dev->qdisc != &noqueue_qdisc) { | 549 | if (dev->qdisc != &noqueue_qdisc) { |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index a85935e7d53d..558cc087e602 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -717,6 +717,10 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
717 | if (q->direct_queue.qlen < q->direct_qlen) { | 717 | if (q->direct_queue.qlen < q->direct_qlen) { |
718 | __skb_queue_tail(&q->direct_queue, skb); | 718 | __skb_queue_tail(&q->direct_queue, skb); |
719 | q->direct_pkts++; | 719 | q->direct_pkts++; |
720 | } else { | ||
721 | kfree_skb(skb); | ||
722 | sch->qstats.drops++; | ||
723 | return NET_XMIT_DROP; | ||
720 | } | 724 | } |
721 | #ifdef CONFIG_NET_CLS_ACT | 725 | #ifdef CONFIG_NET_CLS_ACT |
722 | } else if (!cl) { | 726 | } else if (!cl) { |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 31c29deb139d..e0c9fbe73b15 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -138,38 +138,77 @@ static long tabledist(unsigned long mu, long sigma, | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /* Put skb in the private delayed queue. */ | 140 | /* Put skb in the private delayed queue. */ |
141 | static int delay_skb(struct Qdisc *sch, struct sk_buff *skb) | 141 | static int netem_delay(struct Qdisc *sch, struct sk_buff *skb) |
142 | { | 142 | { |
143 | struct netem_sched_data *q = qdisc_priv(sch); | 143 | struct netem_sched_data *q = qdisc_priv(sch); |
144 | struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; | ||
145 | psched_tdiff_t td; | 144 | psched_tdiff_t td; |
146 | psched_time_t now; | 145 | psched_time_t now; |
147 | 146 | ||
148 | PSCHED_GET_TIME(now); | 147 | PSCHED_GET_TIME(now); |
149 | td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist); | 148 | td = tabledist(q->latency, q->jitter, &q->delay_cor, q->delay_dist); |
150 | PSCHED_TADD2(now, td, cb->time_to_send); | ||
151 | 149 | ||
152 | /* Always queue at tail to keep packets in order */ | 150 | /* Always queue at tail to keep packets in order */ |
153 | if (likely(q->delayed.qlen < q->limit)) { | 151 | if (likely(q->delayed.qlen < q->limit)) { |
152 | struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; | ||
153 | |||
154 | PSCHED_TADD2(now, td, cb->time_to_send); | ||
155 | |||
156 | pr_debug("netem_delay: skb=%p now=%llu tosend=%llu\n", skb, | ||
157 | now, cb->time_to_send); | ||
158 | |||
154 | __skb_queue_tail(&q->delayed, skb); | 159 | __skb_queue_tail(&q->delayed, skb); |
155 | if (!timer_pending(&q->timer)) { | ||
156 | q->timer.expires = jiffies + PSCHED_US2JIFFIE(td); | ||
157 | add_timer(&q->timer); | ||
158 | } | ||
159 | return NET_XMIT_SUCCESS; | 160 | return NET_XMIT_SUCCESS; |
160 | } | 161 | } |
161 | 162 | ||
163 | pr_debug("netem_delay: queue over limit %d\n", q->limit); | ||
164 | sch->qstats.overlimits++; | ||
162 | kfree_skb(skb); | 165 | kfree_skb(skb); |
163 | return NET_XMIT_DROP; | 166 | return NET_XMIT_DROP; |
164 | } | 167 | } |
165 | 168 | ||
169 | /* | ||
170 | * Move a packet that is ready to send from the delay holding | ||
171 | * list to the underlying qdisc. | ||
172 | */ | ||
173 | static int netem_run(struct Qdisc *sch) | ||
174 | { | ||
175 | struct netem_sched_data *q = qdisc_priv(sch); | ||
176 | struct sk_buff *skb; | ||
177 | psched_time_t now; | ||
178 | |||
179 | PSCHED_GET_TIME(now); | ||
180 | |||
181 | skb = skb_peek(&q->delayed); | ||
182 | if (skb) { | ||
183 | const struct netem_skb_cb *cb | ||
184 | = (const struct netem_skb_cb *)skb->cb; | ||
185 | long delay | ||
186 | = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now)); | ||
187 | pr_debug("netem_run: skb=%p delay=%ld\n", skb, delay); | ||
188 | |||
189 | /* if more time remaining? */ | ||
190 | if (delay > 0) { | ||
191 | mod_timer(&q->timer, jiffies + delay); | ||
192 | return 1; | ||
193 | } | ||
194 | |||
195 | __skb_unlink(skb, &q->delayed); | ||
196 | |||
197 | if (q->qdisc->enqueue(skb, q->qdisc)) { | ||
198 | sch->q.qlen--; | ||
199 | sch->qstats.drops++; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
166 | static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | 206 | static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) |
167 | { | 207 | { |
168 | struct netem_sched_data *q = qdisc_priv(sch); | 208 | struct netem_sched_data *q = qdisc_priv(sch); |
169 | struct sk_buff *skb2; | ||
170 | int ret; | 209 | int ret; |
171 | 210 | ||
172 | pr_debug("netem_enqueue skb=%p @%lu\n", skb, jiffies); | 211 | pr_debug("netem_enqueue skb=%p\n", skb); |
173 | 212 | ||
174 | /* Random packet drop 0 => none, ~0 => all */ | 213 | /* Random packet drop 0 => none, ~0 => all */ |
175 | if (q->loss && q->loss >= get_crandom(&q->loss_cor)) { | 214 | if (q->loss && q->loss >= get_crandom(&q->loss_cor)) { |
@@ -180,11 +219,21 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
180 | } | 219 | } |
181 | 220 | ||
182 | /* Random duplication */ | 221 | /* Random duplication */ |
183 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor) | 222 | if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) { |
184 | && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { | 223 | struct sk_buff *skb2; |
185 | pr_debug("netem_enqueue: dup %p\n", skb2); | 224 | |
225 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
226 | if (skb2 && netem_delay(sch, skb2) == NET_XMIT_SUCCESS) { | ||
227 | struct Qdisc *qp; | ||
228 | |||
229 | /* Since one packet can generate two packets in the | ||
230 | * queue, the parent's qlen accounting gets confused, | ||
231 | * so fix it. | ||
232 | */ | ||
233 | qp = qdisc_lookup(sch->dev, TC_H_MAJ(sch->parent)); | ||
234 | if (qp) | ||
235 | qp->q.qlen++; | ||
186 | 236 | ||
187 | if (delay_skb(sch, skb2)) { | ||
188 | sch->q.qlen++; | 237 | sch->q.qlen++; |
189 | sch->bstats.bytes += skb2->len; | 238 | sch->bstats.bytes += skb2->len; |
190 | sch->bstats.packets++; | 239 | sch->bstats.packets++; |
@@ -202,7 +251,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
202 | ret = q->qdisc->enqueue(skb, q->qdisc); | 251 | ret = q->qdisc->enqueue(skb, q->qdisc); |
203 | } else { | 252 | } else { |
204 | q->counter = 0; | 253 | q->counter = 0; |
205 | ret = delay_skb(sch, skb); | 254 | ret = netem_delay(sch, skb); |
255 | netem_run(sch); | ||
206 | } | 256 | } |
207 | 257 | ||
208 | if (likely(ret == NET_XMIT_SUCCESS)) { | 258 | if (likely(ret == NET_XMIT_SUCCESS)) { |
@@ -212,6 +262,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
212 | } else | 262 | } else |
213 | sch->qstats.drops++; | 263 | sch->qstats.drops++; |
214 | 264 | ||
265 | pr_debug("netem: enqueue ret %d\n", ret); | ||
215 | return ret; | 266 | return ret; |
216 | } | 267 | } |
217 | 268 | ||
@@ -241,56 +292,35 @@ static unsigned int netem_drop(struct Qdisc* sch) | |||
241 | return len; | 292 | return len; |
242 | } | 293 | } |
243 | 294 | ||
244 | /* Dequeue packet. | ||
245 | * Move all packets that are ready to send from the delay holding | ||
246 | * list to the underlying qdisc, then just call dequeue | ||
247 | */ | ||
248 | static struct sk_buff *netem_dequeue(struct Qdisc *sch) | 295 | static struct sk_buff *netem_dequeue(struct Qdisc *sch) |
249 | { | 296 | { |
250 | struct netem_sched_data *q = qdisc_priv(sch); | 297 | struct netem_sched_data *q = qdisc_priv(sch); |
251 | struct sk_buff *skb; | 298 | struct sk_buff *skb; |
299 | int pending; | ||
300 | |||
301 | pending = netem_run(sch); | ||
252 | 302 | ||
253 | skb = q->qdisc->dequeue(q->qdisc); | 303 | skb = q->qdisc->dequeue(q->qdisc); |
254 | if (skb) | 304 | if (skb) { |
305 | pr_debug("netem_dequeue: return skb=%p\n", skb); | ||
255 | sch->q.qlen--; | 306 | sch->q.qlen--; |
307 | sch->flags &= ~TCQ_F_THROTTLED; | ||
308 | } | ||
309 | else if (pending) { | ||
310 | pr_debug("netem_dequeue: throttling\n"); | ||
311 | sch->flags |= TCQ_F_THROTTLED; | ||
312 | } | ||
313 | |||
256 | return skb; | 314 | return skb; |
257 | } | 315 | } |
258 | 316 | ||
259 | static void netem_watchdog(unsigned long arg) | 317 | static void netem_watchdog(unsigned long arg) |
260 | { | 318 | { |
261 | struct Qdisc *sch = (struct Qdisc *)arg; | 319 | struct Qdisc *sch = (struct Qdisc *)arg; |
262 | struct netem_sched_data *q = qdisc_priv(sch); | ||
263 | struct net_device *dev = sch->dev; | ||
264 | struct sk_buff *skb; | ||
265 | psched_time_t now; | ||
266 | |||
267 | pr_debug("netem_watchdog: fired @%lu\n", jiffies); | ||
268 | |||
269 | spin_lock_bh(&dev->queue_lock); | ||
270 | PSCHED_GET_TIME(now); | ||
271 | |||
272 | while ((skb = skb_peek(&q->delayed)) != NULL) { | ||
273 | const struct netem_skb_cb *cb | ||
274 | = (const struct netem_skb_cb *)skb->cb; | ||
275 | long delay | ||
276 | = PSCHED_US2JIFFIE(PSCHED_TDIFF(cb->time_to_send, now)); | ||
277 | pr_debug("netem_watchdog: skb %p@%lu %ld\n", | ||
278 | skb, jiffies, delay); | ||
279 | 320 | ||
280 | /* if more time remaining? */ | 321 | pr_debug("netem_watchdog qlen=%d\n", sch->q.qlen); |
281 | if (delay > 0) { | 322 | sch->flags &= ~TCQ_F_THROTTLED; |
282 | mod_timer(&q->timer, jiffies + delay); | 323 | netif_schedule(sch->dev); |
283 | break; | ||
284 | } | ||
285 | __skb_unlink(skb, &q->delayed); | ||
286 | |||
287 | if (q->qdisc->enqueue(skb, q->qdisc)) { | ||
288 | sch->q.qlen--; | ||
289 | sch->qstats.drops++; | ||
290 | } | ||
291 | } | ||
292 | qdisc_run(dev); | ||
293 | spin_unlock_bh(&dev->queue_lock); | ||
294 | } | 324 | } |
295 | 325 | ||
296 | static void netem_reset(struct Qdisc *sch) | 326 | static void netem_reset(struct Qdisc *sch) |
@@ -301,6 +331,7 @@ static void netem_reset(struct Qdisc *sch) | |||
301 | skb_queue_purge(&q->delayed); | 331 | skb_queue_purge(&q->delayed); |
302 | 332 | ||
303 | sch->q.qlen = 0; | 333 | sch->q.qlen = 0; |
334 | sch->flags &= ~TCQ_F_THROTTLED; | ||
304 | del_timer_sync(&q->timer); | 335 | del_timer_sync(&q->timer); |
305 | } | 336 | } |
306 | 337 | ||
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 544b75077dbd..334f61773e6d 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -125,6 +125,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
125 | sp->autoclose * HZ; | 125 | sp->autoclose * HZ; |
126 | 126 | ||
127 | /* Use SCTP specific send buffer space queues. */ | 127 | /* Use SCTP specific send buffer space queues. */ |
128 | ep->sndbuf_policy = sctp_sndbuf_policy; | ||
128 | sk->sk_write_space = sctp_write_space; | 129 | sk->sk_write_space = sctp_write_space; |
129 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 130 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
130 | 131 | ||
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index e42c74e3ec1e..c9d9ea064734 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -496,9 +496,7 @@ static void sctp_v6_inaddr_any(union sctp_addr *addr, unsigned short port) | |||
496 | /* Is this a wildcard address? */ | 496 | /* Is this a wildcard address? */ |
497 | static int sctp_v6_is_any(const union sctp_addr *addr) | 497 | static int sctp_v6_is_any(const union sctp_addr *addr) |
498 | { | 498 | { |
499 | int type; | 499 | return ipv6_addr_any(&addr->v6.sin6_addr); |
500 | type = ipv6_addr_type((struct in6_addr *)&addr->v6.sin6_addr); | ||
501 | return IPV6_ADDR_ANY == type; | ||
502 | } | 500 | } |
503 | 501 | ||
504 | /* Should this be available for binding? */ | 502 | /* Should this be available for binding? */ |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 9013f64f5219..84b5b370b09d 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -313,12 +313,12 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
313 | sk = chunk->skb->sk; | 313 | sk = chunk->skb->sk; |
314 | 314 | ||
315 | /* Allocate the new skb. */ | 315 | /* Allocate the new skb. */ |
316 | nskb = dev_alloc_skb(packet->size); | 316 | nskb = alloc_skb(packet->size + LL_MAX_HEADER, GFP_ATOMIC); |
317 | if (!nskb) | 317 | if (!nskb) |
318 | goto nomem; | 318 | goto nomem; |
319 | 319 | ||
320 | /* Make sure the outbound skb has enough header room reserved. */ | 320 | /* Make sure the outbound skb has enough header room reserved. */ |
321 | skb_reserve(nskb, packet->overhead); | 321 | skb_reserve(nskb, packet->overhead + LL_MAX_HEADER); |
322 | 322 | ||
323 | /* Set the owning socket so that we know where to get the | 323 | /* Set the owning socket so that we know where to get the |
324 | * destination IP address. | 324 | * destination IP address. |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index b9813cf3d91c..2e1f9c3556f5 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1043,6 +1043,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
1043 | sctp_max_retrans_path = 5; | 1043 | sctp_max_retrans_path = 5; |
1044 | sctp_max_retrans_init = 8; | 1044 | sctp_max_retrans_init = 8; |
1045 | 1045 | ||
1046 | /* Sendbuffer growth - do per-socket accounting */ | ||
1047 | sctp_sndbuf_policy = 0; | ||
1048 | |||
1046 | /* HB.interval - 30 seconds */ | 1049 | /* HB.interval - 30 seconds */ |
1047 | sctp_hb_interval = 30 * HZ; | 1050 | sctp_hb_interval = 30 * HZ; |
1048 | 1051 | ||
@@ -1159,8 +1162,6 @@ SCTP_STATIC __init int sctp_init(void) | |||
1159 | status = 0; | 1162 | status = 0; |
1160 | out: | 1163 | out: |
1161 | return status; | 1164 | return status; |
1162 | err_add_protocol: | ||
1163 | proto_unregister(&sctp_prot); | ||
1164 | err_ctl_sock_init: | 1165 | err_ctl_sock_init: |
1165 | sctp_v6_exit(); | 1166 | sctp_v6_exit(); |
1166 | err_v6_init: | 1167 | err_v6_init: |
@@ -1188,6 +1189,8 @@ err_bucket_cachep: | |||
1188 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); | 1189 | inet_del_protocol(&sctp_protocol, IPPROTO_SCTP); |
1189 | inet_unregister_protosw(&sctp_seqpacket_protosw); | 1190 | inet_unregister_protosw(&sctp_seqpacket_protosw); |
1190 | inet_unregister_protosw(&sctp_stream_protosw); | 1191 | inet_unregister_protosw(&sctp_stream_protosw); |
1192 | err_add_protocol: | ||
1193 | proto_unregister(&sctp_prot); | ||
1191 | goto out; | 1194 | goto out; |
1192 | } | 1195 | } |
1193 | 1196 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 1db12cc18cf7..33ac8bf47b0e 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -710,7 +710,9 @@ struct sctp_chunk *sctp_make_shutdown_complete( | |||
710 | struct sctp_chunk *retval; | 710 | struct sctp_chunk *retval; |
711 | __u8 flags = 0; | 711 | __u8 flags = 0; |
712 | 712 | ||
713 | /* Maybe set the T-bit if we have no association. */ | 713 | /* Set the T-bit if we have no association (vtag will be |
714 | * reflected) | ||
715 | */ | ||
714 | flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; | 716 | flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; |
715 | 717 | ||
716 | retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); | 718 | retval = sctp_make_chunk(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0); |
@@ -732,7 +734,7 @@ struct sctp_chunk *sctp_make_shutdown_complete( | |||
732 | } | 734 | } |
733 | 735 | ||
734 | /* Create an ABORT. Note that we set the T bit if we have no | 736 | /* Create an ABORT. Note that we set the T bit if we have no |
735 | * association. | 737 | * association, except when responding to an INIT (sctpimpguide 2.41). |
736 | */ | 738 | */ |
737 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, | 739 | struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, |
738 | const struct sctp_chunk *chunk, | 740 | const struct sctp_chunk *chunk, |
@@ -741,8 +743,16 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc, | |||
741 | struct sctp_chunk *retval; | 743 | struct sctp_chunk *retval; |
742 | __u8 flags = 0; | 744 | __u8 flags = 0; |
743 | 745 | ||
744 | /* Maybe set the T-bit if we have no association. */ | 746 | /* Set the T-bit if we have no association and 'chunk' is not |
745 | flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T; | 747 | * an INIT (vtag will be reflected). |
748 | */ | ||
749 | if (!asoc) { | ||
750 | if (chunk && chunk->chunk_hdr && | ||
751 | chunk->chunk_hdr->type == SCTP_CID_INIT) | ||
752 | flags = 0; | ||
753 | else | ||
754 | flags = SCTP_CHUNK_FLAG_T; | ||
755 | } | ||
746 | 756 | ||
747 | retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); | 757 | retval = sctp_make_chunk(asoc, SCTP_CID_ABORT, flags, hint); |
748 | 758 | ||
@@ -2744,7 +2754,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc, | |||
2744 | 2754 | ||
2745 | hint = (nstreams + 1) * sizeof(__u32); | 2755 | hint = (nstreams + 1) * sizeof(__u32); |
2746 | 2756 | ||
2747 | /* Maybe set the T-bit if we have no association. */ | ||
2748 | retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); | 2757 | retval = sctp_make_chunk(asoc, SCTP_CID_FWD_TSN, 0, hint); |
2749 | 2758 | ||
2750 | if (!retval) | 2759 | if (!retval) |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 278c56a2d076..8e01b8f09ac2 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -126,15 +126,18 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk, | |||
126 | * should stop the T2-shutdown timer and remove all knowledge of the | 126 | * should stop the T2-shutdown timer and remove all knowledge of the |
127 | * association (and thus the association enters the CLOSED state). | 127 | * association (and thus the association enters the CLOSED state). |
128 | * | 128 | * |
129 | * Verification Tag: 8.5.1(C) | 129 | * Verification Tag: 8.5.1(C), sctpimpguide 2.41. |
130 | * C) Rules for packet carrying SHUTDOWN COMPLETE: | 130 | * C) Rules for packet carrying SHUTDOWN COMPLETE: |
131 | * ... | 131 | * ... |
132 | * - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the | 132 | * - The receiver of a SHUTDOWN COMPLETE shall accept the packet |
133 | * Verification Tag field of the packet matches its own tag OR it is | 133 | * if the Verification Tag field of the packet matches its own tag and |
134 | * set to its peer's tag and the T bit is set in the Chunk Flags. | 134 | * the T bit is not set |
135 | * Otherwise, the receiver MUST silently discard the packet and take | 135 | * OR |
136 | * no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if | 136 | * it is set to its peer's tag and the T bit is set in the Chunk |
137 | * it is not in the SHUTDOWN-ACK-SENT state. | 137 | * Flags. |
138 | * Otherwise, the receiver MUST silently discard the packet | ||
139 | * and take no further action. An endpoint MUST ignore the | ||
140 | * SHUTDOWN COMPLETE if it is not in the SHUTDOWN-ACK-SENT state. | ||
138 | * | 141 | * |
139 | * Inputs | 142 | * Inputs |
140 | * (endpoint, asoc, chunk) | 143 | * (endpoint, asoc, chunk) |
@@ -2858,16 +2861,16 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, | |||
2858 | /* | 2861 | /* |
2859 | * Generate an ABORT in response to a packet. | 2862 | * Generate an ABORT in response to a packet. |
2860 | * | 2863 | * |
2861 | * Section: 8.4 Handle "Out of the blue" Packets | 2864 | * Section: 8.4 Handle "Out of the blue" Packets, sctpimpguide 2.41 |
2862 | * | 2865 | * |
2863 | * 8) The receiver should respond to the sender of the OOTB packet | 2866 | * 8) The receiver should respond to the sender of the OOTB packet with |
2864 | * with an ABORT. When sending the ABORT, the receiver of the | 2867 | * an ABORT. When sending the ABORT, the receiver of the OOTB packet |
2865 | * OOTB packet MUST fill in the Verification Tag field of the | 2868 | * MUST fill in the Verification Tag field of the outbound packet |
2866 | * outbound packet with the value found in the Verification Tag | 2869 | * with the value found in the Verification Tag field of the OOTB |
2867 | * field of the OOTB packet and set the T-bit in the Chunk Flags | 2870 | * packet and set the T-bit in the Chunk Flags to indicate that the |
2868 | * to indicate that no TCB was found. After sending this ABORT, | 2871 | * Verification Tag is reflected. After sending this ABORT, the |
2869 | * the receiver of the OOTB packet shall discard the OOTB packet | 2872 | * receiver of the OOTB packet shall discard the OOTB packet and take |
2870 | * and take no further action. | 2873 | * no further action. |
2871 | * | 2874 | * |
2872 | * Verification Tag: | 2875 | * Verification Tag: |
2873 | * | 2876 | * |
@@ -2895,6 +2898,10 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, | |||
2895 | return SCTP_DISPOSITION_NOMEM; | 2898 | return SCTP_DISPOSITION_NOMEM; |
2896 | } | 2899 | } |
2897 | 2900 | ||
2901 | /* Reflect vtag if T-Bit is set */ | ||
2902 | if (sctp_test_T_bit(abort)) | ||
2903 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
2904 | |||
2898 | /* Set the skb to the belonging sock for accounting. */ | 2905 | /* Set the skb to the belonging sock for accounting. */ |
2899 | abort->skb->sk = ep->base.sk; | 2906 | abort->skb->sk = ep->base.sk; |
2900 | 2907 | ||
@@ -3026,22 +3033,24 @@ nomem: | |||
3026 | } | 3033 | } |
3027 | 3034 | ||
3028 | /* | 3035 | /* |
3029 | * RFC 2960, 8.4 - Handle "Out of the blue" Packets | 3036 | * RFC 2960, 8.4 - Handle "Out of the blue" Packets, sctpimpguide 2.41. |
3037 | * | ||
3030 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should | 3038 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should |
3031 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. | 3039 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. |
3032 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB | 3040 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB |
3033 | * packet must fill in the Verification Tag field of the outbound | 3041 | * packet must fill in the Verification Tag field of the outbound |
3034 | * packet with the Verification Tag received in the SHUTDOWN ACK and | 3042 | * packet with the Verification Tag received in the SHUTDOWN ACK and |
3035 | * set the T-bit in the Chunk Flags to indicate that no TCB was | 3043 | * set the T-bit in the Chunk Flags to indicate that the Verification |
3036 | * found. Otherwise, | 3044 | * Tag is reflected. |
3037 | * | 3045 | * |
3038 | * 8) The receiver should respond to the sender of the OOTB packet with | 3046 | * 8) The receiver should respond to the sender of the OOTB packet with |
3039 | * an ABORT. When sending the ABORT, the receiver of the OOTB packet | 3047 | * an ABORT. When sending the ABORT, the receiver of the OOTB packet |
3040 | * MUST fill in the Verification Tag field of the outbound packet | 3048 | * MUST fill in the Verification Tag field of the outbound packet |
3041 | * with the value found in the Verification Tag field of the OOTB | 3049 | * with the value found in the Verification Tag field of the OOTB |
3042 | * packet and set the T-bit in the Chunk Flags to indicate that no | 3050 | * packet and set the T-bit in the Chunk Flags to indicate that the |
3043 | * TCB was found. After sending this ABORT, the receiver of the OOTB | 3051 | * Verification Tag is reflected. After sending this ABORT, the |
3044 | * packet shall discard the OOTB packet and take no further action. | 3052 | * receiver of the OOTB packet shall discard the OOTB packet and take |
3053 | * no further action. | ||
3045 | */ | 3054 | */ |
3046 | sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | 3055 | sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, |
3047 | const struct sctp_association *asoc, | 3056 | const struct sctp_association *asoc, |
@@ -3090,13 +3099,15 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3090 | /* | 3099 | /* |
3091 | * Handle an "Out of the blue" SHUTDOWN ACK. | 3100 | * Handle an "Out of the blue" SHUTDOWN ACK. |
3092 | * | 3101 | * |
3093 | * Section: 8.4 5) | 3102 | * Section: 8.4 5, sctpimpguide 2.41. |
3103 | * | ||
3094 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should | 3104 | * 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should |
3095 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. | 3105 | * respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE. |
3096 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet | 3106 | * When sending the SHUTDOWN COMPLETE, the receiver of the OOTB |
3097 | * must fill in the Verification Tag field of the outbound packet with | 3107 | * packet must fill in the Verification Tag field of the outbound |
3098 | * the Verification Tag received in the SHUTDOWN ACK and set the | 3108 | * packet with the Verification Tag received in the SHUTDOWN ACK and |
3099 | * T-bit in the Chunk Flags to indicate that no TCB was found. | 3109 | * set the T-bit in the Chunk Flags to indicate that the Verification |
3110 | * Tag is reflected. | ||
3100 | * | 3111 | * |
3101 | * Inputs | 3112 | * Inputs |
3102 | * (endpoint, asoc, type, arg, commands) | 3113 | * (endpoint, asoc, type, arg, commands) |
@@ -3128,6 +3139,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, | |||
3128 | return SCTP_DISPOSITION_NOMEM; | 3139 | return SCTP_DISPOSITION_NOMEM; |
3129 | } | 3140 | } |
3130 | 3141 | ||
3142 | /* Reflect vtag if T-Bit is set */ | ||
3143 | if (sctp_test_T_bit(shut)) | ||
3144 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
3145 | |||
3131 | /* Set the skb to the belonging sock for accounting. */ | 3146 | /* Set the skb to the belonging sock for accounting. */ |
3132 | shut->skb->sk = ep->base.sk; | 3147 | shut->skb->sk = ep->base.sk; |
3133 | 3148 | ||
@@ -3591,7 +3606,6 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep, | |||
3591 | * | 3606 | * |
3592 | * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST | 3607 | * 2) If the OOTB packet contains an ABORT chunk, the receiver MUST |
3593 | * silently discard the OOTB packet and take no further action. | 3608 | * silently discard the OOTB packet and take no further action. |
3594 | * Otherwise, | ||
3595 | * | 3609 | * |
3596 | * Verification Tag: No verification necessary | 3610 | * Verification Tag: No verification necessary |
3597 | * | 3611 | * |
@@ -4961,6 +4975,11 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, | |||
4961 | sctp_ootb_pkt_free(packet); | 4975 | sctp_ootb_pkt_free(packet); |
4962 | return NULL; | 4976 | return NULL; |
4963 | } | 4977 | } |
4978 | |||
4979 | /* Reflect vtag if T-Bit is set */ | ||
4980 | if (sctp_test_T_bit(abort)) | ||
4981 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
4982 | |||
4964 | /* Add specified error causes, i.e., payload, to the | 4983 | /* Add specified error causes, i.e., payload, to the |
4965 | * end of the chunk. | 4984 | * end of the chunk. |
4966 | */ | 4985 | */ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index e8c210182571..0b338eca6dc0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc) | |||
115 | struct sock *sk = asoc->base.sk; | 115 | struct sock *sk = asoc->base.sk; |
116 | int amt = 0; | 116 | int amt = 0; |
117 | 117 | ||
118 | amt = sk->sk_sndbuf - asoc->sndbuf_used; | 118 | if (asoc->ep->sndbuf_policy) { |
119 | /* make sure that no association uses more than sk_sndbuf */ | ||
120 | amt = sk->sk_sndbuf - asoc->sndbuf_used; | ||
121 | } else { | ||
122 | /* do socket level accounting */ | ||
123 | amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | ||
124 | } | ||
125 | |||
119 | if (amt < 0) | 126 | if (amt < 0) |
120 | amt = 0; | 127 | amt = 0; |
128 | |||
121 | return amt; | 129 | return amt; |
122 | } | 130 | } |
123 | 131 | ||
@@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) | |||
138 | /* The sndbuf space is tracked per association. */ | 146 | /* The sndbuf space is tracked per association. */ |
139 | sctp_association_hold(asoc); | 147 | sctp_association_hold(asoc); |
140 | 148 | ||
149 | skb_set_owner_w(chunk->skb, sk); | ||
150 | |||
141 | chunk->skb->destructor = sctp_wfree; | 151 | chunk->skb->destructor = sctp_wfree; |
142 | /* Save the chunk pointer in skb for sctp_wfree to use later. */ | 152 | /* Save the chunk pointer in skb for sctp_wfree to use later. */ |
143 | *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; | 153 | *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; |
144 | 154 | ||
145 | asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk); | 155 | asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) + |
146 | sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk); | 156 | sizeof(struct sk_buff) + |
157 | sizeof(struct sctp_chunk); | ||
158 | |||
159 | sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) + | ||
160 | sizeof(struct sk_buff) + | ||
161 | sizeof(struct sctp_chunk); | ||
162 | |||
163 | atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | ||
147 | } | 164 | } |
148 | 165 | ||
149 | /* Verify that this is a valid address. */ | 166 | /* Verify that this is a valid address. */ |
@@ -3473,7 +3490,7 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len, | |||
3473 | return -EINVAL; | 3490 | return -EINVAL; |
3474 | 3491 | ||
3475 | /* Values correspoinding to the specific association */ | 3492 | /* Values correspoinding to the specific association */ |
3476 | if (assocparams.sasoc_assoc_id != 0) { | 3493 | if (asoc) { |
3477 | assocparams.sasoc_asocmaxrxt = asoc->max_retrans; | 3494 | assocparams.sasoc_asocmaxrxt = asoc->max_retrans; |
3478 | assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; | 3495 | assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; |
3479 | assocparams.sasoc_local_rwnd = asoc->a_rwnd; | 3496 | assocparams.sasoc_local_rwnd = asoc->a_rwnd; |
@@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb) | |||
4422 | chunk = *((struct sctp_chunk **)(skb->cb)); | 4439 | chunk = *((struct sctp_chunk **)(skb->cb)); |
4423 | asoc = chunk->asoc; | 4440 | asoc = chunk->asoc; |
4424 | sk = asoc->base.sk; | 4441 | sk = asoc->base.sk; |
4425 | asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk); | 4442 | asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) + |
4426 | sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk); | 4443 | sizeof(struct sk_buff) + |
4444 | sizeof(struct sctp_chunk); | ||
4445 | |||
4446 | sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) + | ||
4447 | sizeof(struct sk_buff) + | ||
4448 | sizeof(struct sctp_chunk); | ||
4449 | |||
4450 | atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | ||
4451 | |||
4452 | sock_wfree(skb); | ||
4427 | __sctp_write_space(asoc); | 4453 | __sctp_write_space(asoc); |
4428 | 4454 | ||
4429 | sctp_association_put(asoc); | 4455 | sctp_association_put(asoc); |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 89fa20c73a5c..7fc31849312b 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -110,6 +110,14 @@ static ctl_table sctp_table[] = { | |||
110 | .proc_handler = &proc_dointvec | 110 | .proc_handler = &proc_dointvec |
111 | }, | 111 | }, |
112 | { | 112 | { |
113 | .ctl_name = NET_SCTP_SNDBUF_POLICY, | ||
114 | .procname = "sndbuf_policy", | ||
115 | .data = &sctp_sndbuf_policy, | ||
116 | .maxlen = sizeof(int), | ||
117 | .mode = 0644, | ||
118 | .proc_handler = &proc_dointvec | ||
119 | }, | ||
120 | { | ||
113 | .ctl_name = NET_SCTP_PATH_MAX_RETRANS, | 121 | .ctl_name = NET_SCTP_PATH_MAX_RETRANS, |
114 | .procname = "path_max_retrans", | 122 | .procname = "path_max_retrans", |
115 | .data = &sctp_max_retrans_path, | 123 | .data = &sctp_max_retrans_path, |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4484931018eb..67b9f035ba86 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -46,9 +46,9 @@ xdr_decode_netobj(u32 *p, struct xdr_netobj *obj) | |||
46 | 46 | ||
47 | /** | 47 | /** |
48 | * xdr_encode_opaque_fixed - Encode fixed length opaque data | 48 | * xdr_encode_opaque_fixed - Encode fixed length opaque data |
49 | * @p - pointer to current position in XDR buffer. | 49 | * @p: pointer to current position in XDR buffer. |
50 | * @ptr - pointer to data to encode (or NULL) | 50 | * @ptr: pointer to data to encode (or NULL) |
51 | * @nbytes - size of data. | 51 | * @nbytes: size of data. |
52 | * | 52 | * |
53 | * Copy the array of data of length nbytes at ptr to the XDR buffer | 53 | * Copy the array of data of length nbytes at ptr to the XDR buffer |
54 | * at position p, then align to the next 32-bit boundary by padding | 54 | * at position p, then align to the next 32-bit boundary by padding |
@@ -76,9 +76,9 @@ EXPORT_SYMBOL(xdr_encode_opaque_fixed); | |||
76 | 76 | ||
77 | /** | 77 | /** |
78 | * xdr_encode_opaque - Encode variable length opaque data | 78 | * xdr_encode_opaque - Encode variable length opaque data |
79 | * @p - pointer to current position in XDR buffer. | 79 | * @p: pointer to current position in XDR buffer. |
80 | * @ptr - pointer to data to encode (or NULL) | 80 | * @ptr: pointer to data to encode (or NULL) |
81 | * @nbytes - size of data. | 81 | * @nbytes: size of data. |
82 | * | 82 | * |
83 | * Returns the updated current XDR buffer position | 83 | * Returns the updated current XDR buffer position |
84 | */ | 84 | */ |
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index 956c17f6c548..d6844ac226f5 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c | |||
@@ -48,8 +48,8 @@ | |||
48 | #include <linux/kernel.h> | 48 | #include <linux/kernel.h> |
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | #include <linux/module.h> /* support for loadable modules */ | 50 | #include <linux/module.h> /* support for loadable modules */ |
51 | #include <linux/slab.h> /* kmalloc(), kfree() */ | 51 | #include <linux/slab.h> /* kmalloc(), kfree() */ |
52 | #include <linux/mm.h> /* verify_area(), etc. */ | 52 | #include <linux/mm.h> |
53 | #include <linux/string.h> /* inline mem*, str* functions */ | 53 | #include <linux/string.h> /* inline mem*, str* functions */ |
54 | 54 | ||
55 | #include <asm/byteorder.h> /* htons(), etc. */ | 55 | #include <asm/byteorder.h> /* htons(), etc. */ |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 80828078733d..55ed979db144 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1028,30 +1028,15 @@ static int stale_bundle(struct dst_entry *dst) | |||
1028 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); | 1028 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | static void xfrm_dst_destroy(struct dst_entry *dst) | 1031 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
1032 | { | 1032 | { |
1033 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
1034 | |||
1035 | dst_release(xdst->route); | ||
1036 | |||
1037 | if (!dst->xfrm) | ||
1038 | return; | ||
1039 | xfrm_state_put(dst->xfrm); | ||
1040 | dst->xfrm = NULL; | ||
1041 | } | ||
1042 | |||
1043 | static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
1044 | int unregister) | ||
1045 | { | ||
1046 | if (!unregister) | ||
1047 | return; | ||
1048 | |||
1049 | while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { | 1033 | while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { |
1050 | dst->dev = &loopback_dev; | 1034 | dst->dev = &loopback_dev; |
1051 | dev_hold(&loopback_dev); | 1035 | dev_hold(&loopback_dev); |
1052 | dev_put(dev); | 1036 | dev_put(dev); |
1053 | } | 1037 | } |
1054 | } | 1038 | } |
1039 | EXPORT_SYMBOL(xfrm_dst_ifdown); | ||
1055 | 1040 | ||
1056 | static void xfrm_link_failure(struct sk_buff *skb) | 1041 | static void xfrm_link_failure(struct sk_buff *skb) |
1057 | { | 1042 | { |
@@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
1262 | dst_ops->kmem_cachep = xfrm_dst_cache; | 1247 | dst_ops->kmem_cachep = xfrm_dst_cache; |
1263 | if (likely(dst_ops->check == NULL)) | 1248 | if (likely(dst_ops->check == NULL)) |
1264 | dst_ops->check = xfrm_dst_check; | 1249 | dst_ops->check = xfrm_dst_check; |
1265 | if (likely(dst_ops->destroy == NULL)) | ||
1266 | dst_ops->destroy = xfrm_dst_destroy; | ||
1267 | if (likely(dst_ops->ifdown == NULL)) | ||
1268 | dst_ops->ifdown = xfrm_dst_ifdown; | ||
1269 | if (likely(dst_ops->negative_advice == NULL)) | 1250 | if (likely(dst_ops->negative_advice == NULL)) |
1270 | dst_ops->negative_advice = xfrm_negative_advice; | 1251 | dst_ops->negative_advice = xfrm_negative_advice; |
1271 | if (likely(dst_ops->link_failure == NULL)) | 1252 | if (likely(dst_ops->link_failure == NULL)) |
@@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
1297 | xfrm_policy_afinfo[afinfo->family] = NULL; | 1278 | xfrm_policy_afinfo[afinfo->family] = NULL; |
1298 | dst_ops->kmem_cachep = NULL; | 1279 | dst_ops->kmem_cachep = NULL; |
1299 | dst_ops->check = NULL; | 1280 | dst_ops->check = NULL; |
1300 | dst_ops->destroy = NULL; | ||
1301 | dst_ops->ifdown = NULL; | ||
1302 | dst_ops->negative_advice = NULL; | 1281 | dst_ops->negative_advice = NULL; |
1303 | dst_ops->link_failure = NULL; | 1282 | dst_ops->link_failure = NULL; |
1304 | dst_ops->get_mss = NULL; | 1283 | dst_ops->get_mss = NULL; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 63661b0fd736..5ddda2c98af9 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -855,47 +855,44 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x | |||
855 | return 0; | 855 | return 0; |
856 | } | 856 | } |
857 | 857 | ||
858 | static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = { | 858 | #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) |
859 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */ | 859 | |
860 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */ | 860 | static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { |
861 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* GET SA */ | 861 | [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
862 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* NEW POLICY */ | 862 | [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), |
863 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* DEL POLICY */ | 863 | [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), |
864 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* GET POLICY */ | 864 | [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
865 | NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */ | 865 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
866 | NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ | 866 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
867 | NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ | 867 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), |
868 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ | 868 | [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), |
869 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */ | 869 | [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire), |
870 | NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */ | 870 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
871 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */ | 871 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
872 | NLMSG_LENGTH(0), /* FLUSH POLICY */ | 872 | [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), |
873 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), | ||
874 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), | ||
873 | }; | 875 | }; |
874 | 876 | ||
877 | #undef XMSGSIZE | ||
878 | |||
875 | static struct xfrm_link { | 879 | static struct xfrm_link { |
876 | int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); | 880 | int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); |
877 | int (*dump)(struct sk_buff *, struct netlink_callback *); | 881 | int (*dump)(struct sk_buff *, struct netlink_callback *); |
878 | } xfrm_dispatch[] = { | 882 | } xfrm_dispatch[XFRM_NR_MSGTYPES] = { |
879 | { .doit = xfrm_add_sa, }, | 883 | [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
880 | { .doit = xfrm_del_sa, }, | 884 | [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa }, |
881 | { | 885 | [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa, |
882 | .doit = xfrm_get_sa, | 886 | .dump = xfrm_dump_sa }, |
883 | .dump = xfrm_dump_sa, | 887 | [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
884 | }, | 888 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, |
885 | { .doit = xfrm_add_policy }, | 889 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, |
886 | { .doit = xfrm_get_policy }, | 890 | .dump = xfrm_dump_policy }, |
887 | { | 891 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, |
888 | .doit = xfrm_get_policy, | 892 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
889 | .dump = xfrm_dump_policy, | 893 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
890 | }, | 894 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, |
891 | { .doit = xfrm_alloc_userspi }, | 895 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, |
892 | {}, | ||
893 | {}, | ||
894 | { .doit = xfrm_add_policy }, | ||
895 | { .doit = xfrm_add_sa, }, | ||
896 | {}, | ||
897 | { .doit = xfrm_flush_sa }, | ||
898 | { .doit = xfrm_flush_policy }, | ||
899 | }; | 896 | }; |
900 | 897 | ||
901 | static int xfrm_done(struct netlink_callback *cb) | 898 | static int xfrm_done(struct netlink_callback *cb) |
@@ -931,7 +928,9 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
931 | return -1; | 928 | return -1; |
932 | } | 929 | } |
933 | 930 | ||
934 | if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) { | 931 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
932 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | ||
933 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | ||
935 | u32 rlen; | 934 | u32 rlen; |
936 | 935 | ||
937 | if (link->dump == NULL) | 936 | if (link->dump == NULL) |
@@ -1009,18 +1008,26 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb) | |||
1009 | 1008 | ||
1010 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 1009 | static void xfrm_netlink_rcv(struct sock *sk, int len) |
1011 | { | 1010 | { |
1011 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
1012 | |||
1012 | do { | 1013 | do { |
1013 | struct sk_buff *skb; | 1014 | struct sk_buff *skb; |
1014 | 1015 | ||
1015 | down(&xfrm_cfg_sem); | 1016 | down(&xfrm_cfg_sem); |
1016 | 1017 | ||
1017 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 1018 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) |
1019 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
1020 | |||
1021 | for (; qlen; qlen--) { | ||
1022 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
1018 | if (xfrm_user_rcv_skb(skb)) { | 1023 | if (xfrm_user_rcv_skb(skb)) { |
1019 | if (skb->len) | 1024 | if (skb->len) |
1020 | skb_queue_head(&sk->sk_receive_queue, | 1025 | skb_queue_head(&sk->sk_receive_queue, |
1021 | skb); | 1026 | skb); |
1022 | else | 1027 | else { |
1023 | kfree_skb(skb); | 1028 | kfree_skb(skb); |
1029 | qlen--; | ||
1030 | } | ||
1024 | break; | 1031 | break; |
1025 | } | 1032 | } |
1026 | kfree_skb(skb); | 1033 | kfree_skb(skb); |
@@ -1028,7 +1035,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len) | |||
1028 | 1035 | ||
1029 | up(&xfrm_cfg_sem); | 1036 | up(&xfrm_cfg_sem); |
1030 | 1037 | ||
1031 | } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen); | 1038 | } while (qlen); |
1032 | } | 1039 | } |
1033 | 1040 | ||
1034 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) | 1041 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) |