diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/compat.c | 10 | ||||
| -rw-r--r-- | net/core/iovec.c | 20 | ||||
| -rw-r--r-- | net/core/pktgen.c | 7 | ||||
| -rw-r--r-- | net/dccp/ccid.h | 34 | ||||
| -rw-r--r-- | net/dccp/ccids/ccid2.c | 23 | ||||
| -rw-r--r-- | net/dccp/ccids/ccid2.h | 5 | ||||
| -rw-r--r-- | net/dccp/ccids/ccid3.c | 12 | ||||
| -rw-r--r-- | net/dccp/dccp.h | 5 | ||||
| -rw-r--r-- | net/dccp/output.c | 209 | ||||
| -rw-r--r-- | net/dccp/proto.c | 21 | ||||
| -rw-r--r-- | net/dccp/timer.c | 27 | ||||
| -rw-r--r-- | net/ipv4/fib_frontend.c | 2 | ||||
| -rw-r--r-- | net/ipv4/fib_hash.c | 18 | ||||
| -rw-r--r-- | net/ipv4/fib_trie.c | 5 | ||||
| -rw-r--r-- | net/mac80211/debugfs_key.c | 6 | ||||
| -rw-r--r-- | net/mac80211/main.c | 5 | ||||
| -rw-r--r-- | net/netfilter/xt_socket.c | 7 |
17 files changed, 274 insertions, 142 deletions
diff --git a/net/compat.c b/net/compat.c index 63d260e81472..3649d5895361 100644 --- a/net/compat.c +++ b/net/compat.c | |||
| @@ -41,10 +41,12 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov, | |||
| 41 | compat_size_t len; | 41 | compat_size_t len; |
| 42 | 42 | ||
| 43 | if (get_user(len, &uiov32->iov_len) || | 43 | if (get_user(len, &uiov32->iov_len) || |
| 44 | get_user(buf, &uiov32->iov_base)) { | 44 | get_user(buf, &uiov32->iov_base)) |
| 45 | tot_len = -EFAULT; | 45 | return -EFAULT; |
| 46 | break; | 46 | |
| 47 | } | 47 | if (len > INT_MAX - tot_len) |
| 48 | len = INT_MAX - tot_len; | ||
| 49 | |||
| 48 | tot_len += len; | 50 | tot_len += len; |
| 49 | kiov->iov_base = compat_ptr(buf); | 51 | kiov->iov_base = compat_ptr(buf); |
| 50 | kiov->iov_len = (__kernel_size_t) len; | 52 | kiov->iov_len = (__kernel_size_t) len; |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 72aceb1fe4fa..c40f27e7d208 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
| @@ -35,10 +35,9 @@ | |||
| 35 | * in any case. | 35 | * in any case. |
| 36 | */ | 36 | */ |
| 37 | 37 | ||
| 38 | long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) | 38 | int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) |
| 39 | { | 39 | { |
| 40 | int size, ct; | 40 | int size, ct, err; |
| 41 | long err; | ||
| 42 | 41 | ||
| 43 | if (m->msg_namelen) { | 42 | if (m->msg_namelen) { |
| 44 | if (mode == VERIFY_READ) { | 43 | if (mode == VERIFY_READ) { |
| @@ -62,14 +61,13 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, | |||
| 62 | err = 0; | 61 | err = 0; |
| 63 | 62 | ||
| 64 | for (ct = 0; ct < m->msg_iovlen; ct++) { | 63 | for (ct = 0; ct < m->msg_iovlen; ct++) { |
| 65 | err += iov[ct].iov_len; | 64 | size_t len = iov[ct].iov_len; |
| 66 | /* | 65 | |
| 67 | * Goal is not to verify user data, but to prevent returning | 66 | if (len > INT_MAX - err) { |
| 68 | * negative value, which is interpreted as errno. | 67 | len = INT_MAX - err; |
| 69 | * Overflow is still possible, but it is harmless. | 68 | iov[ct].iov_len = len; |
| 70 | */ | 69 | } |
| 71 | if (err < 0) | 70 | err += len; |
| 72 | return -EMSGSIZE; | ||
| 73 | } | 71 | } |
| 74 | 72 | ||
| 75 | return err; | 73 | return err; |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 679b797d06b1..fbce4b05a53e 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -887,10 +887,11 @@ static ssize_t pktgen_if_write(struct file *file, | |||
| 887 | i += len; | 887 | i += len; |
| 888 | 888 | ||
| 889 | if (debug) { | 889 | if (debug) { |
| 890 | char tb[count + 1]; | 890 | size_t copy = min(count, 1023); |
| 891 | if (copy_from_user(tb, user_buffer, count)) | 891 | char tb[copy + 1]; |
| 892 | if (copy_from_user(tb, user_buffer, copy)) | ||
| 892 | return -EFAULT; | 893 | return -EFAULT; |
| 893 | tb[count] = 0; | 894 | tb[copy] = 0; |
| 894 | printk(KERN_DEBUG "pktgen: %s,%lu buffer -:%s:-\n", name, | 895 | printk(KERN_DEBUG "pktgen: %s,%lu buffer -:%s:-\n", name, |
| 895 | (unsigned long)count, tb); | 896 | (unsigned long)count, tb); |
| 896 | } | 897 | } |
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 117fb093dcaf..75c3582a7678 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
| @@ -134,13 +134,41 @@ static inline int ccid_get_current_tx_ccid(struct dccp_sock *dp) | |||
| 134 | extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk); | 134 | extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk); |
| 135 | extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk); | 135 | extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk); |
| 136 | 136 | ||
| 137 | /* | ||
| 138 | * Congestion control of queued data packets via CCID decision. | ||
| 139 | * | ||
| 140 | * The TX CCID performs its congestion-control by indicating whether and when a | ||
| 141 | * queued packet may be sent, using the return code of ccid_hc_tx_send_packet(). | ||
| 142 | * The following modes are supported via the symbolic constants below: | ||
| 143 | * - timer-based pacing (CCID returns a delay value in milliseconds); | ||
| 144 | * - autonomous dequeueing (CCID internally schedules dccps_xmitlet). | ||
| 145 | */ | ||
| 146 | |||
| 147 | enum ccid_dequeueing_decision { | ||
| 148 | CCID_PACKET_SEND_AT_ONCE = 0x00000, /* "green light": no delay */ | ||
| 149 | CCID_PACKET_DELAY_MAX = 0x0FFFF, /* maximum delay in msecs */ | ||
| 150 | CCID_PACKET_DELAY = 0x10000, /* CCID msec-delay mode */ | ||
| 151 | CCID_PACKET_WILL_DEQUEUE_LATER = 0x20000, /* CCID autonomous mode */ | ||
| 152 | CCID_PACKET_ERR = 0xF0000, /* error condition */ | ||
| 153 | }; | ||
| 154 | |||
| 155 | static inline int ccid_packet_dequeue_eval(const int return_code) | ||
| 156 | { | ||
| 157 | if (return_code < 0) | ||
| 158 | return CCID_PACKET_ERR; | ||
| 159 | if (return_code == 0) | ||
| 160 | return CCID_PACKET_SEND_AT_ONCE; | ||
| 161 | if (return_code <= CCID_PACKET_DELAY_MAX) | ||
| 162 | return CCID_PACKET_DELAY; | ||
| 163 | return return_code; | ||
| 164 | } | ||
| 165 | |||
| 137 | static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, | 166 | static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, |
| 138 | struct sk_buff *skb) | 167 | struct sk_buff *skb) |
| 139 | { | 168 | { |
| 140 | int rc = 0; | ||
| 141 | if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL) | 169 | if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL) |
| 142 | rc = ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb); | 170 | return ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb); |
| 143 | return rc; | 171 | return CCID_PACKET_SEND_AT_ONCE; |
| 144 | } | 172 | } |
| 145 | 173 | ||
| 146 | static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, | 174 | static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, |
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index d850e291f87c..6576eae9e779 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
| @@ -78,12 +78,9 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc) | |||
| 78 | 78 | ||
| 79 | static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | 79 | static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) |
| 80 | { | 80 | { |
| 81 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | 81 | if (ccid2_cwnd_network_limited(ccid2_hc_tx_sk(sk))) |
| 82 | 82 | return CCID_PACKET_WILL_DEQUEUE_LATER; | |
| 83 | if (hc->tx_pipe < hc->tx_cwnd) | 83 | return CCID_PACKET_SEND_AT_ONCE; |
| 84 | return 0; | ||
| 85 | |||
| 86 | return 1; /* XXX CCID should dequeue when ready instead of polling */ | ||
| 87 | } | 84 | } |
| 88 | 85 | ||
| 89 | static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) | 86 | static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) |
| @@ -115,6 +112,7 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) | |||
| 115 | { | 112 | { |
| 116 | struct sock *sk = (struct sock *)data; | 113 | struct sock *sk = (struct sock *)data; |
| 117 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | 114 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); |
| 115 | const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); | ||
| 118 | 116 | ||
| 119 | bh_lock_sock(sk); | 117 | bh_lock_sock(sk); |
| 120 | if (sock_owned_by_user(sk)) { | 118 | if (sock_owned_by_user(sk)) { |
| @@ -129,8 +127,6 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) | |||
| 129 | if (hc->tx_rto > DCCP_RTO_MAX) | 127 | if (hc->tx_rto > DCCP_RTO_MAX) |
| 130 | hc->tx_rto = DCCP_RTO_MAX; | 128 | hc->tx_rto = DCCP_RTO_MAX; |
| 131 | 129 | ||
| 132 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); | ||
| 133 | |||
| 134 | /* adjust pipe, cwnd etc */ | 130 | /* adjust pipe, cwnd etc */ |
| 135 | hc->tx_ssthresh = hc->tx_cwnd / 2; | 131 | hc->tx_ssthresh = hc->tx_cwnd / 2; |
| 136 | if (hc->tx_ssthresh < 2) | 132 | if (hc->tx_ssthresh < 2) |
| @@ -146,6 +142,12 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) | |||
| 146 | hc->tx_rpseq = 0; | 142 | hc->tx_rpseq = 0; |
| 147 | hc->tx_rpdupack = -1; | 143 | hc->tx_rpdupack = -1; |
| 148 | ccid2_change_l_ack_ratio(sk, 1); | 144 | ccid2_change_l_ack_ratio(sk, 1); |
| 145 | |||
| 146 | /* if we were blocked before, we may now send cwnd=1 packet */ | ||
| 147 | if (sender_was_blocked) | ||
| 148 | tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); | ||
| 149 | /* restart backed-off timer */ | ||
| 150 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); | ||
| 149 | out: | 151 | out: |
| 150 | bh_unlock_sock(sk); | 152 | bh_unlock_sock(sk); |
| 151 | sock_put(sk); | 153 | sock_put(sk); |
| @@ -434,6 +436,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
| 434 | { | 436 | { |
| 435 | struct dccp_sock *dp = dccp_sk(sk); | 437 | struct dccp_sock *dp = dccp_sk(sk); |
| 436 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | 438 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); |
| 439 | const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); | ||
| 437 | u64 ackno, seqno; | 440 | u64 ackno, seqno; |
| 438 | struct ccid2_seq *seqp; | 441 | struct ccid2_seq *seqp; |
| 439 | unsigned char *vector; | 442 | unsigned char *vector; |
| @@ -631,6 +634,10 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
| 631 | sk_stop_timer(sk, &hc->tx_rtotimer); | 634 | sk_stop_timer(sk, &hc->tx_rtotimer); |
| 632 | else | 635 | else |
| 633 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); | 636 | sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); |
| 637 | |||
| 638 | /* check if incoming Acks allow pending packets to be sent */ | ||
| 639 | if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) | ||
| 640 | tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); | ||
| 634 | } | 641 | } |
| 635 | 642 | ||
| 636 | static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) | 643 | static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) |
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index 9731c2dc1487..25cb6b216eda 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h | |||
| @@ -81,6 +81,11 @@ struct ccid2_hc_tx_sock { | |||
| 81 | u64 tx_high_ack; | 81 | u64 tx_high_ack; |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc) | ||
| 85 | { | ||
| 86 | return hc->tx_pipe >= hc->tx_cwnd; | ||
| 87 | } | ||
| 88 | |||
| 84 | struct ccid2_hc_rx_sock { | 89 | struct ccid2_hc_rx_sock { |
| 85 | int rx_data; | 90 | int rx_data; |
| 86 | }; | 91 | }; |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 3060a60ed5ab..3d604e1349c0 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
| @@ -268,11 +268,11 @@ out: | |||
| 268 | sock_put(sk); | 268 | sock_put(sk); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | /* | 271 | /** |
| 272 | * returns | 272 | * ccid3_hc_tx_send_packet - Delay-based dequeueing of TX packets |
| 273 | * > 0: delay (in msecs) that should pass before actually sending | 273 | * @skb: next packet candidate to send on @sk |
| 274 | * = 0: can send immediately | 274 | * This function uses the convention of ccid_packet_dequeue_eval() and |
| 275 | * < 0: error condition; do not send packet | 275 | * returns a millisecond-delay value between 0 and t_mbi = 64000 msec. |
| 276 | */ | 276 | */ |
| 277 | static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | 277 | static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) |
| 278 | { | 278 | { |
| @@ -348,7 +348,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | |||
| 348 | 348 | ||
| 349 | /* set the nominal send time for the next following packet */ | 349 | /* set the nominal send time for the next following packet */ |
| 350 | hc->tx_t_nom = ktime_add_us(hc->tx_t_nom, hc->tx_t_ipi); | 350 | hc->tx_t_nom = ktime_add_us(hc->tx_t_nom, hc->tx_t_ipi); |
| 351 | return 0; | 351 | return CCID_PACKET_SEND_AT_ONCE; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) | 354 | static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 3eb264b60823..a8ed459508b2 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
| @@ -243,8 +243,9 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, | |||
| 243 | extern void dccp_send_sync(struct sock *sk, const u64 seq, | 243 | extern void dccp_send_sync(struct sock *sk, const u64 seq, |
| 244 | const enum dccp_pkt_type pkt_type); | 244 | const enum dccp_pkt_type pkt_type); |
| 245 | 245 | ||
| 246 | extern void dccp_write_xmit(struct sock *sk, int block); | 246 | extern void dccp_write_xmit(struct sock *sk); |
| 247 | extern void dccp_write_space(struct sock *sk); | 247 | extern void dccp_write_space(struct sock *sk); |
| 248 | extern void dccp_flush_write_queue(struct sock *sk, long *time_budget); | ||
| 248 | 249 | ||
| 249 | extern void dccp_init_xmit_timers(struct sock *sk); | 250 | extern void dccp_init_xmit_timers(struct sock *sk); |
| 250 | static inline void dccp_clear_xmit_timers(struct sock *sk) | 251 | static inline void dccp_clear_xmit_timers(struct sock *sk) |
diff --git a/net/dccp/output.c b/net/dccp/output.c index a988fe9ffcba..45b91853f5ae 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
| @@ -209,108 +209,150 @@ void dccp_write_space(struct sock *sk) | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | /** | 211 | /** |
| 212 | * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet | 212 | * dccp_wait_for_ccid - Await CCID send permission |
| 213 | * @sk: socket to wait for | 213 | * @sk: socket to wait for |
| 214 | * @skb: current skb to pass on for waiting | 214 | * @delay: timeout in jiffies |
| 215 | * @delay: sleep timeout in milliseconds (> 0) | 215 | * This is used by CCIDs which need to delay the send time in process context. |
| 216 | * This function is called by default when the socket is closed, and | ||
| 217 | * when a non-zero linger time is set on the socket. For consistency | ||
| 218 | */ | 216 | */ |
| 219 | static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay) | 217 | static int dccp_wait_for_ccid(struct sock *sk, unsigned long delay) |
| 220 | { | 218 | { |
| 221 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 222 | DEFINE_WAIT(wait); | 219 | DEFINE_WAIT(wait); |
| 223 | unsigned long jiffdelay; | 220 | long remaining; |
| 224 | int rc; | 221 | |
| 222 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 223 | sk->sk_write_pending++; | ||
| 224 | release_sock(sk); | ||
| 225 | |||
| 226 | remaining = schedule_timeout(delay); | ||
| 227 | |||
| 228 | lock_sock(sk); | ||
| 229 | sk->sk_write_pending--; | ||
| 230 | finish_wait(sk_sleep(sk), &wait); | ||
| 231 | |||
| 232 | if (signal_pending(current) || sk->sk_err) | ||
| 233 | return -1; | ||
| 234 | return remaining; | ||
| 235 | } | ||
| 236 | |||
| 237 | /** | ||
| 238 | * dccp_xmit_packet - Send data packet under control of CCID | ||
| 239 | * Transmits next-queued payload and informs CCID to account for the packet. | ||
| 240 | */ | ||
| 241 | static void dccp_xmit_packet(struct sock *sk) | ||
| 242 | { | ||
| 243 | int err, len; | ||
| 244 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 245 | struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue); | ||
| 225 | 246 | ||
| 226 | do { | 247 | if (unlikely(skb == NULL)) |
| 227 | dccp_pr_debug("delayed send by %d msec\n", delay); | 248 | return; |
| 228 | jiffdelay = msecs_to_jiffies(delay); | 249 | len = skb->len; |
| 229 | 250 | ||
| 230 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 251 | if (sk->sk_state == DCCP_PARTOPEN) { |
| 252 | const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD; | ||
| 253 | /* | ||
| 254 | * See 8.1.5 - Handshake Completion. | ||
| 255 | * | ||
| 256 | * For robustness we resend Confirm options until the client has | ||
| 257 | * entered OPEN. During the initial feature negotiation, the MPS | ||
| 258 | * is smaller than usual, reduced by the Change/Confirm options. | ||
| 259 | */ | ||
| 260 | if (!list_empty(&dp->dccps_featneg) && len > cur_mps) { | ||
| 261 | DCCP_WARN("Payload too large (%d) for featneg.\n", len); | ||
| 262 | dccp_send_ack(sk); | ||
| 263 | dccp_feat_list_purge(&dp->dccps_featneg); | ||
| 264 | } | ||
| 231 | 265 | ||
| 232 | sk->sk_write_pending++; | 266 | inet_csk_schedule_ack(sk); |
| 233 | release_sock(sk); | 267 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, |
| 234 | schedule_timeout(jiffdelay); | 268 | inet_csk(sk)->icsk_rto, |
| 235 | lock_sock(sk); | 269 | DCCP_RTO_MAX); |
| 236 | sk->sk_write_pending--; | 270 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK; |
| 271 | } else if (dccp_ack_pending(sk)) { | ||
| 272 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATAACK; | ||
| 273 | } else { | ||
| 274 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_DATA; | ||
| 275 | } | ||
| 276 | |||
| 277 | err = dccp_transmit_skb(sk, skb); | ||
| 278 | if (err) | ||
| 279 | dccp_pr_debug("transmit_skb() returned err=%d\n", err); | ||
| 280 | /* | ||
| 281 | * Register this one as sent even if an error occurred. To the remote | ||
| 282 | * end a local packet drop is indistinguishable from network loss, i.e. | ||
| 283 | * any local drop will eventually be reported via receiver feedback. | ||
| 284 | */ | ||
| 285 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); | ||
| 286 | } | ||
| 237 | 287 | ||
| 238 | if (sk->sk_err) | 288 | /** |
| 239 | goto do_error; | 289 | * dccp_flush_write_queue - Drain queue at end of connection |
| 240 | if (signal_pending(current)) | 290 | * Since dccp_sendmsg queues packets without waiting for them to be sent, it may |
| 241 | goto do_interrupted; | 291 | * happen that the TX queue is not empty at the end of a connection. We give the |
| 292 | * HC-sender CCID a grace period of up to @time_budget jiffies. If this function | ||
| 293 | * returns with a non-empty write queue, it will be purged later. | ||
| 294 | */ | ||
| 295 | void dccp_flush_write_queue(struct sock *sk, long *time_budget) | ||
| 296 | { | ||
| 297 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 298 | struct sk_buff *skb; | ||
| 299 | long delay, rc; | ||
| 242 | 300 | ||
| 301 | while (*time_budget > 0 && (skb = skb_peek(&sk->sk_write_queue))) { | ||
| 243 | rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); | 302 | rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); |
| 244 | } while ((delay = rc) > 0); | 303 | |
| 245 | out: | 304 | switch (ccid_packet_dequeue_eval(rc)) { |
| 246 | finish_wait(sk_sleep(sk), &wait); | 305 | case CCID_PACKET_WILL_DEQUEUE_LATER: |
| 247 | return rc; | 306 | /* |
| 248 | 307 | * If the CCID determines when to send, the next sending | |
| 249 | do_error: | 308 | * time is unknown or the CCID may not even send again |
| 250 | rc = -EPIPE; | 309 | * (e.g. remote host crashes or lost Ack packets). |
| 251 | goto out; | 310 | */ |
| 252 | do_interrupted: | 311 | DCCP_WARN("CCID did not manage to send all packets\n"); |
| 253 | rc = -EINTR; | 312 | return; |
| 254 | goto out; | 313 | case CCID_PACKET_DELAY: |
| 314 | delay = msecs_to_jiffies(rc); | ||
| 315 | if (delay > *time_budget) | ||
| 316 | return; | ||
| 317 | rc = dccp_wait_for_ccid(sk, delay); | ||
| 318 | if (rc < 0) | ||
| 319 | return; | ||
| 320 | *time_budget -= (delay - rc); | ||
| 321 | /* check again if we can send now */ | ||
| 322 | break; | ||
| 323 | case CCID_PACKET_SEND_AT_ONCE: | ||
| 324 | dccp_xmit_packet(sk); | ||
| 325 | break; | ||
| 326 | case CCID_PACKET_ERR: | ||
| 327 | skb_dequeue(&sk->sk_write_queue); | ||
| 328 | kfree_skb(skb); | ||
| 329 | dccp_pr_debug("packet discarded due to err=%ld\n", rc); | ||
| 330 | } | ||
| 331 | } | ||
| 255 | } | 332 | } |
| 256 | 333 | ||
| 257 | void dccp_write_xmit(struct sock *sk, int block) | 334 | void dccp_write_xmit(struct sock *sk) |
| 258 | { | 335 | { |
| 259 | struct dccp_sock *dp = dccp_sk(sk); | 336 | struct dccp_sock *dp = dccp_sk(sk); |
| 260 | struct sk_buff *skb; | 337 | struct sk_buff *skb; |
| 261 | 338 | ||
| 262 | while ((skb = skb_peek(&sk->sk_write_queue))) { | 339 | while ((skb = skb_peek(&sk->sk_write_queue))) { |
| 263 | int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); | 340 | int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); |
| 264 | |||
| 265 | if (err > 0) { | ||
| 266 | if (!block) { | ||
| 267 | sk_reset_timer(sk, &dp->dccps_xmit_timer, | ||
| 268 | msecs_to_jiffies(err)+jiffies); | ||
| 269 | break; | ||
| 270 | } else | ||
| 271 | err = dccp_wait_for_ccid(sk, skb, err); | ||
| 272 | if (err && err != -EINTR) | ||
| 273 | DCCP_BUG("err=%d after dccp_wait_for_ccid", err); | ||
| 274 | } | ||
| 275 | 341 | ||
| 276 | skb_dequeue(&sk->sk_write_queue); | 342 | switch (ccid_packet_dequeue_eval(rc)) { |
| 277 | if (err == 0) { | 343 | case CCID_PACKET_WILL_DEQUEUE_LATER: |
| 278 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | 344 | return; |
| 279 | const int len = skb->len; | 345 | case CCID_PACKET_DELAY: |
| 280 | 346 | sk_reset_timer(sk, &dp->dccps_xmit_timer, | |
| 281 | if (sk->sk_state == DCCP_PARTOPEN) { | 347 | jiffies + msecs_to_jiffies(rc)); |
| 282 | const u32 cur_mps = dp->dccps_mss_cache - DCCP_FEATNEG_OVERHEAD; | 348 | return; |
| 283 | /* | 349 | case CCID_PACKET_SEND_AT_ONCE: |
| 284 | * See 8.1.5 - Handshake Completion. | 350 | dccp_xmit_packet(sk); |
| 285 | * | 351 | break; |
| 286 | * For robustness we resend Confirm options until the client has | 352 | case CCID_PACKET_ERR: |
| 287 | * entered OPEN. During the initial feature negotiation, the MPS | 353 | skb_dequeue(&sk->sk_write_queue); |
| 288 | * is smaller than usual, reduced by the Change/Confirm options. | ||
| 289 | */ | ||
| 290 | if (!list_empty(&dp->dccps_featneg) && len > cur_mps) { | ||
| 291 | DCCP_WARN("Payload too large (%d) for featneg.\n", len); | ||
| 292 | dccp_send_ack(sk); | ||
| 293 | dccp_feat_list_purge(&dp->dccps_featneg); | ||
| 294 | } | ||
| 295 | |||
| 296 | inet_csk_schedule_ack(sk); | ||
| 297 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, | ||
| 298 | inet_csk(sk)->icsk_rto, | ||
| 299 | DCCP_RTO_MAX); | ||
| 300 | dcb->dccpd_type = DCCP_PKT_DATAACK; | ||
| 301 | } else if (dccp_ack_pending(sk)) | ||
| 302 | dcb->dccpd_type = DCCP_PKT_DATAACK; | ||
| 303 | else | ||
| 304 | dcb->dccpd_type = DCCP_PKT_DATA; | ||
| 305 | |||
| 306 | err = dccp_transmit_skb(sk, skb); | ||
| 307 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); | ||
| 308 | if (err) | ||
| 309 | DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", | ||
| 310 | err); | ||
| 311 | } else { | ||
| 312 | dccp_pr_debug("packet discarded due to err=%d\n", err); | ||
| 313 | kfree_skb(skb); | 354 | kfree_skb(skb); |
| 355 | dccp_pr_debug("packet discarded due to err=%d\n", rc); | ||
| 314 | } | 356 | } |
| 315 | } | 357 | } |
| 316 | } | 358 | } |
| @@ -622,7 +664,6 @@ void dccp_send_close(struct sock *sk, const int active) | |||
| 622 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; | 664 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE; |
| 623 | 665 | ||
| 624 | if (active) { | 666 | if (active) { |
| 625 | dccp_write_xmit(sk, 1); | ||
| 626 | dccp_skb_entail(sk, skb); | 667 | dccp_skb_entail(sk, skb); |
| 627 | dccp_transmit_skb(sk, skb_clone(skb, prio)); | 668 | dccp_transmit_skb(sk, skb_clone(skb, prio)); |
| 628 | /* | 669 | /* |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 7e5fc04eb6d1..ef343d53fcea 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
| @@ -726,7 +726,13 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 726 | goto out_discard; | 726 | goto out_discard; |
| 727 | 727 | ||
| 728 | skb_queue_tail(&sk->sk_write_queue, skb); | 728 | skb_queue_tail(&sk->sk_write_queue, skb); |
| 729 | dccp_write_xmit(sk,0); | 729 | /* |
| 730 | * The xmit_timer is set if the TX CCID is rate-based and will expire | ||
| 731 | * when congestion control permits to release further packets into the | ||
| 732 | * network. Window-based CCIDs do not use this timer. | ||
| 733 | */ | ||
| 734 | if (!timer_pending(&dp->dccps_xmit_timer)) | ||
| 735 | dccp_write_xmit(sk); | ||
| 730 | out_release: | 736 | out_release: |
| 731 | release_sock(sk); | 737 | release_sock(sk); |
| 732 | return rc ? : len; | 738 | return rc ? : len; |
| @@ -951,9 +957,22 @@ void dccp_close(struct sock *sk, long timeout) | |||
| 951 | /* Check zero linger _after_ checking for unread data. */ | 957 | /* Check zero linger _after_ checking for unread data. */ |
| 952 | sk->sk_prot->disconnect(sk, 0); | 958 | sk->sk_prot->disconnect(sk, 0); |
| 953 | } else if (sk->sk_state != DCCP_CLOSED) { | 959 | } else if (sk->sk_state != DCCP_CLOSED) { |
| 960 | /* | ||
| 961 | * Normal connection termination. May need to wait if there are | ||
| 962 | * still packets in the TX queue that are delayed by the CCID. | ||
| 963 | */ | ||
| 964 | dccp_flush_write_queue(sk, &timeout); | ||
| 954 | dccp_terminate_connection(sk); | 965 | dccp_terminate_connection(sk); |
| 955 | } | 966 | } |
| 956 | 967 | ||
| 968 | /* | ||
| 969 | * Flush write queue. This may be necessary in several cases: | ||
| 970 | * - we have been closed by the peer but still have application data; | ||
| 971 | * - abortive termination (unread data or zero linger time), | ||
| 972 | * - normal termination but queue could not be flushed within time limit | ||
| 973 | */ | ||
| 974 | __skb_queue_purge(&sk->sk_write_queue); | ||
| 975 | |||
| 957 | sk_stream_wait_close(sk, timeout); | 976 | sk_stream_wait_close(sk, timeout); |
| 958 | 977 | ||
| 959 | adjudge_to_death: | 978 | adjudge_to_death: |
diff --git a/net/dccp/timer.c b/net/dccp/timer.c index 1a9aa05d4dc4..7587870b7040 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c | |||
| @@ -237,32 +237,35 @@ out: | |||
| 237 | sock_put(sk); | 237 | sock_put(sk); |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | /* Transmit-delay timer: used by the CCIDs to delay actual send time */ | 240 | /** |
| 241 | static void dccp_write_xmit_timer(unsigned long data) | 241 | * dccp_write_xmitlet - Workhorse for CCID packet dequeueing interface |
| 242 | * See the comments above %ccid_dequeueing_decision for supported modes. | ||
| 243 | */ | ||
| 244 | static void dccp_write_xmitlet(unsigned long data) | ||
| 242 | { | 245 | { |
| 243 | struct sock *sk = (struct sock *)data; | 246 | struct sock *sk = (struct sock *)data; |
| 244 | struct dccp_sock *dp = dccp_sk(sk); | ||
| 245 | 247 | ||
| 246 | bh_lock_sock(sk); | 248 | bh_lock_sock(sk); |
| 247 | if (sock_owned_by_user(sk)) | 249 | if (sock_owned_by_user(sk)) |
| 248 | sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1); | 250 | sk_reset_timer(sk, &dccp_sk(sk)->dccps_xmit_timer, jiffies + 1); |
| 249 | else | 251 | else |
| 250 | dccp_write_xmit(sk, 0); | 252 | dccp_write_xmit(sk); |
| 251 | bh_unlock_sock(sk); | 253 | bh_unlock_sock(sk); |
| 252 | sock_put(sk); | ||
| 253 | } | 254 | } |
| 254 | 255 | ||
| 255 | static void dccp_init_write_xmit_timer(struct sock *sk) | 256 | static void dccp_write_xmit_timer(unsigned long data) |
| 256 | { | 257 | { |
| 257 | struct dccp_sock *dp = dccp_sk(sk); | 258 | dccp_write_xmitlet(data); |
| 258 | 259 | sock_put((struct sock *)data); | |
| 259 | setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer, | ||
| 260 | (unsigned long)sk); | ||
| 261 | } | 260 | } |
| 262 | 261 | ||
| 263 | void dccp_init_xmit_timers(struct sock *sk) | 262 | void dccp_init_xmit_timers(struct sock *sk) |
| 264 | { | 263 | { |
| 265 | dccp_init_write_xmit_timer(sk); | 264 | struct dccp_sock *dp = dccp_sk(sk); |
| 265 | |||
| 266 | tasklet_init(&dp->dccps_xmitlet, dccp_write_xmitlet, (unsigned long)sk); | ||
| 267 | setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer, | ||
| 268 | (unsigned long)sk); | ||
| 266 | inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer, | 269 | inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer, |
| 267 | &dccp_keepalive_timer); | 270 | &dccp_keepalive_timer); |
| 268 | } | 271 | } |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 36e27c2107de..eb6f69a8f27a 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -1052,7 +1052,7 @@ static void ip_fib_net_exit(struct net *net) | |||
| 1052 | hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { | 1052 | hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { |
| 1053 | hlist_del(node); | 1053 | hlist_del(node); |
| 1054 | fib_table_flush(tb); | 1054 | fib_table_flush(tb); |
| 1055 | kfree(tb); | 1055 | fib_free_table(tb); |
| 1056 | } | 1056 | } |
| 1057 | } | 1057 | } |
| 1058 | kfree(net->ipv4.fib_table_hash); | 1058 | kfree(net->ipv4.fib_table_hash); |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index b232375a0b75..b3acb0417b21 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
| @@ -716,6 +716,24 @@ int fib_table_flush(struct fib_table *tb) | |||
| 716 | return found; | 716 | return found; |
| 717 | } | 717 | } |
| 718 | 718 | ||
| 719 | void fib_free_table(struct fib_table *tb) | ||
| 720 | { | ||
| 721 | struct fn_hash *table = (struct fn_hash *) tb->tb_data; | ||
| 722 | struct fn_zone *fz, *next; | ||
| 723 | |||
| 724 | next = table->fn_zone_list; | ||
| 725 | while (next != NULL) { | ||
| 726 | fz = next; | ||
| 727 | next = fz->fz_next; | ||
| 728 | |||
| 729 | if (fz->fz_hash != fz->fz_embedded_hash) | ||
| 730 | fz_hash_free(fz->fz_hash, fz->fz_divisor); | ||
| 731 | |||
| 732 | kfree(fz); | ||
| 733 | } | ||
| 734 | |||
| 735 | kfree(tb); | ||
| 736 | } | ||
| 719 | 737 | ||
| 720 | static inline int | 738 | static inline int |
| 721 | fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, | 739 | fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b14450895102..200eb538fbb3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
| @@ -1797,6 +1797,11 @@ int fib_table_flush(struct fib_table *tb) | |||
| 1797 | return found; | 1797 | return found; |
| 1798 | } | 1798 | } |
| 1799 | 1799 | ||
| 1800 | void fib_free_table(struct fib_table *tb) | ||
| 1801 | { | ||
| 1802 | kfree(tb); | ||
| 1803 | } | ||
| 1804 | |||
| 1800 | void fib_table_select_default(struct fib_table *tb, | 1805 | void fib_table_select_default(struct fib_table *tb, |
| 1801 | const struct flowi *flp, | 1806 | const struct flowi *flp, |
| 1802 | struct fib_result *res) | 1807 | struct fib_result *res) |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 4aa47d074a79..1243d1db5c59 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
| @@ -203,9 +203,13 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf, | |||
| 203 | size_t count, loff_t *ppos) | 203 | size_t count, loff_t *ppos) |
| 204 | { | 204 | { |
| 205 | struct ieee80211_key *key = file->private_data; | 205 | struct ieee80211_key *key = file->private_data; |
| 206 | int i, res, bufsize = 2 * key->conf.keylen + 2; | 206 | int i, bufsize = 2 * key->conf.keylen + 2; |
| 207 | char *buf = kmalloc(bufsize, GFP_KERNEL); | 207 | char *buf = kmalloc(bufsize, GFP_KERNEL); |
| 208 | char *p = buf; | 208 | char *p = buf; |
| 209 | ssize_t res; | ||
| 210 | |||
| 211 | if (!buf) | ||
| 212 | return -ENOMEM; | ||
| 209 | 213 | ||
| 210 | for (i = 0; i < key->conf.keylen; i++) | 214 | for (i = 0; i < key->conf.keylen; i++) |
| 211 | p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]); | 215 | p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6b322fa681f5..107a0cbe52ac 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -677,10 +677,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 677 | /* | 677 | /* |
| 678 | * Calculate scan IE length -- we need this to alloc | 678 | * Calculate scan IE length -- we need this to alloc |
| 679 | * memory and to subtract from the driver limit. It | 679 | * memory and to subtract from the driver limit. It |
| 680 | * includes the (extended) supported rates and HT | 680 | * includes the DS Params, (extended) supported rates, and HT |
| 681 | * information -- SSID is the driver's responsibility. | 681 | * information -- SSID is the driver's responsibility. |
| 682 | */ | 682 | */ |
| 683 | local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */ | 683 | local->scan_ies_len = 4 + max_bitrates /* (ext) supp rates */ + |
| 684 | 3 /* DS Params */; | ||
| 684 | if (supp_ht) | 685 | if (supp_ht) |
| 685 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); | 686 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); |
| 686 | 687 | ||
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index d94a858dc52a..00d6ae838303 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c | |||
| @@ -195,7 +195,7 @@ socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 195 | static int | 195 | static int |
| 196 | extract_icmp6_fields(const struct sk_buff *skb, | 196 | extract_icmp6_fields(const struct sk_buff *skb, |
| 197 | unsigned int outside_hdrlen, | 197 | unsigned int outside_hdrlen, |
| 198 | u8 *protocol, | 198 | int *protocol, |
| 199 | struct in6_addr **raddr, | 199 | struct in6_addr **raddr, |
| 200 | struct in6_addr **laddr, | 200 | struct in6_addr **laddr, |
| 201 | __be16 *rport, | 201 | __be16 *rport, |
| @@ -252,8 +252,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 252 | struct sock *sk; | 252 | struct sock *sk; |
| 253 | struct in6_addr *daddr, *saddr; | 253 | struct in6_addr *daddr, *saddr; |
| 254 | __be16 dport, sport; | 254 | __be16 dport, sport; |
| 255 | int thoff; | 255 | int thoff, tproto; |
| 256 | u8 tproto; | ||
| 257 | const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; | 256 | const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; |
| 258 | 257 | ||
| 259 | tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); | 258 | tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); |
| @@ -305,7 +304,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 305 | sk = NULL; | 304 | sk = NULL; |
| 306 | } | 305 | } |
| 307 | 306 | ||
| 308 | pr_debug("proto %hhu %pI6:%hu -> %pI6:%hu " | 307 | pr_debug("proto %hhd %pI6:%hu -> %pI6:%hu " |
| 309 | "(orig %pI6:%hu) sock %p\n", | 308 | "(orig %pI6:%hu) sock %p\n", |
| 310 | tproto, saddr, ntohs(sport), | 309 | tproto, saddr, ntohs(sport), |
| 311 | daddr, ntohs(dport), | 310 | daddr, ntohs(dport), |
