diff options
Diffstat (limited to 'net')
75 files changed, 541 insertions, 235 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 5f27f8e3025..f1f2f7bb666 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -167,6 +167,8 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) | |||
167 | if (unlikely(!skb)) | 167 | if (unlikely(!skb)) |
168 | goto err_free; | 168 | goto err_free; |
169 | 169 | ||
170 | skb_reset_network_header(skb); | ||
171 | skb_reset_transport_header(skb); | ||
170 | return skb; | 172 | return skb; |
171 | 173 | ||
172 | err_free: | 174 | err_free: |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 2252c2085da..d07223c834a 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -242,8 +242,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev, | |||
242 | if (brdev->payload == p_bridged) { | 242 | if (brdev->payload == p_bridged) { |
243 | skb_push(skb, 2); | 243 | skb_push(skb, 2); |
244 | memset(skb->data, 0, 2); | 244 | memset(skb->data, 0, 2); |
245 | } else { /* p_routed */ | ||
246 | skb_pull(skb, ETH_HLEN); | ||
247 | } | 245 | } |
248 | } | 246 | } |
249 | skb_debug(skb); | 247 | skb_debug(skb); |
@@ -560,12 +558,13 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) | |||
560 | spin_unlock_irqrestore(&rq->lock, flags); | 558 | spin_unlock_irqrestore(&rq->lock, flags); |
561 | 559 | ||
562 | skb_queue_walk_safe(&queue, skb, tmp) { | 560 | skb_queue_walk_safe(&queue, skb, tmp) { |
563 | struct net_device *dev = skb->dev; | 561 | struct net_device *dev; |
562 | |||
563 | br2684_push(atmvcc, skb); | ||
564 | dev = skb->dev; | ||
564 | 565 | ||
565 | dev->stats.rx_bytes -= skb->len; | 566 | dev->stats.rx_bytes -= skb->len; |
566 | dev->stats.rx_packets--; | 567 | dev->stats.rx_packets--; |
567 | |||
568 | br2684_push(atmvcc, skb); | ||
569 | } | 568 | } |
570 | 569 | ||
571 | /* initialize netdev carrier state */ | 570 | /* initialize netdev carrier state */ |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8add9b49991..117e0d16178 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
494 | BT_DBG("sk %p", sk); | 494 | BT_DBG("sk %p", sk); |
495 | 495 | ||
496 | add_wait_queue(sk_sleep(sk), &wait); | 496 | add_wait_queue(sk_sleep(sk), &wait); |
497 | set_current_state(TASK_INTERRUPTIBLE); | ||
497 | while (sk->sk_state != state) { | 498 | while (sk->sk_state != state) { |
498 | set_current_state(TASK_INTERRUPTIBLE); | ||
499 | |||
500 | if (!timeo) { | 499 | if (!timeo) { |
501 | err = -EINPROGRESS; | 500 | err = -EINPROGRESS; |
502 | break; | 501 | break; |
@@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
510 | release_sock(sk); | 509 | release_sock(sk); |
511 | timeo = schedule_timeout(timeo); | 510 | timeo = schedule_timeout(timeo); |
512 | lock_sock(sk); | 511 | lock_sock(sk); |
512 | set_current_state(TASK_INTERRUPTIBLE); | ||
513 | 513 | ||
514 | err = sock_error(sk); | 514 | err = sock_error(sk); |
515 | if (err) | 515 | if (err) |
516 | break; | 516 | break; |
517 | } | 517 | } |
518 | set_current_state(TASK_RUNNING); | 518 | __set_current_state(TASK_RUNNING); |
519 | remove_wait_queue(sk_sleep(sk), &wait); | 519 | remove_wait_queue(sk_sleep(sk), &wait); |
520 | return err; | 520 | return err; |
521 | } | 521 | } |
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 8e6c06158f8..e7ee5314f39 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h | |||
@@ -155,6 +155,7 @@ struct bnep_session { | |||
155 | unsigned int role; | 155 | unsigned int role; |
156 | unsigned long state; | 156 | unsigned long state; |
157 | unsigned long flags; | 157 | unsigned long flags; |
158 | atomic_t terminate; | ||
158 | struct task_struct *task; | 159 | struct task_struct *task; |
159 | 160 | ||
160 | struct ethhdr eh; | 161 | struct ethhdr eh; |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ca39fcf010c..d9edfe8bf9d 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -484,9 +484,11 @@ static int bnep_session(void *arg) | |||
484 | 484 | ||
485 | init_waitqueue_entry(&wait, current); | 485 | init_waitqueue_entry(&wait, current); |
486 | add_wait_queue(sk_sleep(sk), &wait); | 486 | add_wait_queue(sk_sleep(sk), &wait); |
487 | while (!kthread_should_stop()) { | 487 | while (1) { |
488 | set_current_state(TASK_INTERRUPTIBLE); | 488 | set_current_state(TASK_INTERRUPTIBLE); |
489 | 489 | ||
490 | if (atomic_read(&s->terminate)) | ||
491 | break; | ||
490 | /* RX */ | 492 | /* RX */ |
491 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | 493 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { |
492 | skb_orphan(skb); | 494 | skb_orphan(skb); |
@@ -504,7 +506,7 @@ static int bnep_session(void *arg) | |||
504 | 506 | ||
505 | schedule(); | 507 | schedule(); |
506 | } | 508 | } |
507 | set_current_state(TASK_RUNNING); | 509 | __set_current_state(TASK_RUNNING); |
508 | remove_wait_queue(sk_sleep(sk), &wait); | 510 | remove_wait_queue(sk_sleep(sk), &wait); |
509 | 511 | ||
510 | /* Cleanup session */ | 512 | /* Cleanup session */ |
@@ -640,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req) | |||
640 | down_read(&bnep_session_sem); | 642 | down_read(&bnep_session_sem); |
641 | 643 | ||
642 | s = __bnep_get_session(req->dst); | 644 | s = __bnep_get_session(req->dst); |
643 | if (s) | 645 | if (s) { |
644 | kthread_stop(s->task); | 646 | atomic_inc(&s->terminate); |
645 | else | 647 | wake_up_process(s->task); |
648 | } else | ||
646 | err = -ENOENT; | 649 | err = -ENOENT; |
647 | 650 | ||
648 | up_read(&bnep_session_sem); | 651 | up_read(&bnep_session_sem); |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 040f67b1297..50f0d135eb8 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
@@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) | |||
386 | 386 | ||
387 | capi_ctr_down(ctrl); | 387 | capi_ctr_down(ctrl); |
388 | 388 | ||
389 | kthread_stop(session->task); | 389 | atomic_inc(&session->terminate); |
390 | wake_up_process(session->task); | ||
390 | } | 391 | } |
391 | 392 | ||
392 | static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) | 393 | static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) |
diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index db43b54ac9a..c32638dddbf 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h | |||
@@ -81,6 +81,7 @@ struct cmtp_session { | |||
81 | 81 | ||
82 | char name[BTNAMSIZ]; | 82 | char name[BTNAMSIZ]; |
83 | 83 | ||
84 | atomic_t terminate; | ||
84 | struct task_struct *task; | 85 | struct task_struct *task; |
85 | 86 | ||
86 | wait_queue_head_t wait; | 87 | wait_queue_head_t wait; |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index c5b11af908b..521baa4fe83 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -292,9 +292,11 @@ static int cmtp_session(void *arg) | |||
292 | 292 | ||
293 | init_waitqueue_entry(&wait, current); | 293 | init_waitqueue_entry(&wait, current); |
294 | add_wait_queue(sk_sleep(sk), &wait); | 294 | add_wait_queue(sk_sleep(sk), &wait); |
295 | while (!kthread_should_stop()) { | 295 | while (1) { |
296 | set_current_state(TASK_INTERRUPTIBLE); | 296 | set_current_state(TASK_INTERRUPTIBLE); |
297 | 297 | ||
298 | if (atomic_read(&session->terminate)) | ||
299 | break; | ||
298 | if (sk->sk_state != BT_CONNECTED) | 300 | if (sk->sk_state != BT_CONNECTED) |
299 | break; | 301 | break; |
300 | 302 | ||
@@ -307,7 +309,7 @@ static int cmtp_session(void *arg) | |||
307 | 309 | ||
308 | schedule(); | 310 | schedule(); |
309 | } | 311 | } |
310 | set_current_state(TASK_RUNNING); | 312 | __set_current_state(TASK_RUNNING); |
311 | remove_wait_queue(sk_sleep(sk), &wait); | 313 | remove_wait_queue(sk_sleep(sk), &wait); |
312 | 314 | ||
313 | down_write(&cmtp_session_sem); | 315 | down_write(&cmtp_session_sem); |
@@ -380,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
380 | 382 | ||
381 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { | 383 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { |
382 | err = cmtp_attach_device(session); | 384 | err = cmtp_attach_device(session); |
383 | if (err < 0) | 385 | if (err < 0) { |
384 | goto detach; | 386 | atomic_inc(&session->terminate); |
387 | wake_up_process(session->task); | ||
388 | up_write(&cmtp_session_sem); | ||
389 | return err; | ||
390 | } | ||
385 | } | 391 | } |
386 | 392 | ||
387 | up_write(&cmtp_session_sem); | 393 | up_write(&cmtp_session_sem); |
388 | return 0; | 394 | return 0; |
389 | 395 | ||
390 | detach: | ||
391 | cmtp_detach_device(session); | ||
392 | |||
393 | unlink: | 396 | unlink: |
394 | __cmtp_unlink_session(session); | 397 | __cmtp_unlink_session(session); |
395 | 398 | ||
@@ -414,7 +417,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) | |||
414 | skb_queue_purge(&session->transmit); | 417 | skb_queue_purge(&session->transmit); |
415 | 418 | ||
416 | /* Stop session thread */ | 419 | /* Stop session thread */ |
417 | kthread_stop(session->task); | 420 | atomic_inc(&session->terminate); |
421 | wake_up_process(session->task); | ||
418 | } else | 422 | } else |
419 | err = -ENOENT; | 423 | err = -ENOENT; |
420 | 424 | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ec0bc3f60f2..56943add45c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg) | |||
1209 | 1209 | ||
1210 | BT_ERR("%s command tx timeout", hdev->name); | 1210 | BT_ERR("%s command tx timeout", hdev->name); |
1211 | atomic_set(&hdev->cmd_cnt, 1); | 1211 | atomic_set(&hdev->cmd_cnt, 1); |
1212 | clear_bit(HCI_RESET, &hdev->flags); | ||
1213 | tasklet_schedule(&hdev->cmd_task); | 1212 | tasklet_schedule(&hdev->cmd_task); |
1214 | } | 1213 | } |
1215 | 1214 | ||
@@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1327 | 1326 | ||
1328 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | 1327 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); |
1329 | if (!entry) { | 1328 | if (!entry) { |
1330 | return -ENOMEM; | 1329 | err = -ENOMEM; |
1331 | goto err; | 1330 | goto err; |
1332 | } | 1331 | } |
1333 | 1332 | ||
@@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg) | |||
2408 | if (hdev->sent_cmd) { | 2407 | if (hdev->sent_cmd) { |
2409 | atomic_dec(&hdev->cmd_cnt); | 2408 | atomic_dec(&hdev->cmd_cnt); |
2410 | hci_send_frame(skb); | 2409 | hci_send_frame(skb); |
2411 | mod_timer(&hdev->cmd_timer, | 2410 | if (test_bit(HCI_RESET, &hdev->flags)) |
2411 | del_timer(&hdev->cmd_timer); | ||
2412 | else | ||
2413 | mod_timer(&hdev->cmd_timer, | ||
2412 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); | 2414 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); |
2413 | } else { | 2415 | } else { |
2414 | skb_queue_head(&hdev->cmd_q, skb); | 2416 | skb_queue_head(&hdev->cmd_q, skb); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 43b4c2deb7c..fb68f344c34 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -764,6 +764,7 @@ static int hidp_session(void *arg) | |||
764 | 764 | ||
765 | up_write(&hidp_session_sem); | 765 | up_write(&hidp_session_sem); |
766 | 766 | ||
767 | kfree(session->rd_data); | ||
767 | kfree(session); | 768 | kfree(session); |
768 | return 0; | 769 | return 0; |
769 | } | 770 | } |
@@ -841,7 +842,8 @@ static int hidp_setup_input(struct hidp_session *session, | |||
841 | 842 | ||
842 | err = input_register_device(input); | 843 | err = input_register_device(input); |
843 | if (err < 0) { | 844 | if (err < 0) { |
844 | hci_conn_put_device(session->conn); | 845 | input_free_device(input); |
846 | session->input = NULL; | ||
845 | return err; | 847 | return err; |
846 | } | 848 | } |
847 | 849 | ||
@@ -1044,8 +1046,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1044 | } | 1046 | } |
1045 | 1047 | ||
1046 | err = hid_add_device(session->hid); | 1048 | err = hid_add_device(session->hid); |
1047 | if (err < 0) | 1049 | if (err < 0) { |
1048 | goto err_add_device; | 1050 | atomic_inc(&session->terminate); |
1051 | wake_up_process(session->task); | ||
1052 | up_write(&hidp_session_sem); | ||
1053 | return err; | ||
1054 | } | ||
1049 | 1055 | ||
1050 | if (session->input) { | 1056 | if (session->input) { |
1051 | hidp_send_ctrl_message(session, | 1057 | hidp_send_ctrl_message(session, |
@@ -1059,12 +1065,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1059 | up_write(&hidp_session_sem); | 1065 | up_write(&hidp_session_sem); |
1060 | return 0; | 1066 | return 0; |
1061 | 1067 | ||
1062 | err_add_device: | ||
1063 | hid_destroy_device(session->hid); | ||
1064 | session->hid = NULL; | ||
1065 | atomic_inc(&session->terminate); | ||
1066 | wake_up_process(session->task); | ||
1067 | |||
1068 | unlink: | 1068 | unlink: |
1069 | hidp_del_timer(session); | 1069 | hidp_del_timer(session); |
1070 | 1070 | ||
@@ -1090,7 +1090,6 @@ purge: | |||
1090 | failed: | 1090 | failed: |
1091 | up_write(&hidp_session_sem); | 1091 | up_write(&hidp_session_sem); |
1092 | 1092 | ||
1093 | input_free_device(session->input); | ||
1094 | kfree(session); | 1093 | kfree(session); |
1095 | return err; | 1094 | return err; |
1096 | } | 1095 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3204ba8a701..b3bdb482bbe 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1159 | int timeo = HZ/5; | 1159 | int timeo = HZ/5; |
1160 | 1160 | ||
1161 | add_wait_queue(sk_sleep(sk), &wait); | 1161 | add_wait_queue(sk_sleep(sk), &wait); |
1162 | while ((chan->unacked_frames > 0 && chan->conn)) { | 1162 | set_current_state(TASK_INTERRUPTIBLE); |
1163 | set_current_state(TASK_INTERRUPTIBLE); | 1163 | while (chan->unacked_frames > 0 && chan->conn) { |
1164 | |||
1165 | if (!timeo) | 1164 | if (!timeo) |
1166 | timeo = HZ/5; | 1165 | timeo = HZ/5; |
1167 | 1166 | ||
@@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1173 | release_sock(sk); | 1172 | release_sock(sk); |
1174 | timeo = schedule_timeout(timeo); | 1173 | timeo = schedule_timeout(timeo); |
1175 | lock_sock(sk); | 1174 | lock_sock(sk); |
1175 | set_current_state(TASK_INTERRUPTIBLE); | ||
1176 | 1176 | ||
1177 | err = sock_error(sk); | 1177 | err = sock_error(sk); |
1178 | if (err) | 1178 | if (err) |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c36b3e8739..61f1f623091 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
235 | 235 | ||
236 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | 236 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); |
237 | 237 | ||
238 | if (sk->sk_state != BT_LISTEN) { | ||
239 | err = -EBADFD; | ||
240 | goto done; | ||
241 | } | ||
242 | |||
243 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 238 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
244 | 239 | ||
245 | BT_DBG("sk %p timeo %ld", sk, timeo); | 240 | BT_DBG("sk %p timeo %ld", sk, timeo); |
246 | 241 | ||
247 | /* Wait for an incoming connection. (wake-one). */ | 242 | /* Wait for an incoming connection. (wake-one). */ |
248 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 243 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
249 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 244 | while (1) { |
250 | set_current_state(TASK_INTERRUPTIBLE); | 245 | set_current_state(TASK_INTERRUPTIBLE); |
251 | if (!timeo) { | 246 | |
252 | err = -EAGAIN; | 247 | if (sk->sk_state != BT_LISTEN) { |
248 | err = -EBADFD; | ||
253 | break; | 249 | break; |
254 | } | 250 | } |
255 | 251 | ||
256 | release_sock(sk); | 252 | nsk = bt_accept_dequeue(sk, newsock); |
257 | timeo = schedule_timeout(timeo); | 253 | if (nsk) |
258 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | 254 | break; |
259 | 255 | ||
260 | if (sk->sk_state != BT_LISTEN) { | 256 | if (!timeo) { |
261 | err = -EBADFD; | 257 | err = -EAGAIN; |
262 | break; | 258 | break; |
263 | } | 259 | } |
264 | 260 | ||
@@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
266 | err = sock_intr_errno(timeo); | 262 | err = sock_intr_errno(timeo); |
267 | break; | 263 | break; |
268 | } | 264 | } |
265 | |||
266 | release_sock(sk); | ||
267 | timeo = schedule_timeout(timeo); | ||
268 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
269 | } | 269 | } |
270 | set_current_state(TASK_RUNNING); | 270 | __set_current_state(TASK_RUNNING); |
271 | remove_wait_queue(sk_sleep(sk), &wait); | 271 | remove_wait_queue(sk_sleep(sk), &wait); |
272 | 272 | ||
273 | if (err) | 273 | if (err) |
@@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
993 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); | 993 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); |
994 | 994 | ||
995 | sk->sk_destruct = l2cap_sock_destruct; | 995 | sk->sk_destruct = l2cap_sock_destruct; |
996 | sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); | 996 | sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; |
997 | 997 | ||
998 | sock_reset_flag(sk, SOCK_ZAPPED); | 998 | sock_reset_flag(sk, SOCK_ZAPPED); |
999 | 999 | ||
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5759bb7054f..5ba3f6df665 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) | 62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) |
63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) | 63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) |
64 | 64 | ||
65 | static unsigned long rfcomm_event; | ||
66 | 65 | ||
67 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
68 | 67 | ||
@@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) | |||
120 | { | 119 | { |
121 | if (!rfcomm_thread) | 120 | if (!rfcomm_thread) |
122 | return; | 121 | return; |
123 | set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
124 | wake_up_process(rfcomm_thread); | 122 | wake_up_process(rfcomm_thread); |
125 | } | 123 | } |
126 | 124 | ||
@@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused) | |||
2038 | 2036 | ||
2039 | rfcomm_add_listener(BDADDR_ANY); | 2037 | rfcomm_add_listener(BDADDR_ANY); |
2040 | 2038 | ||
2041 | while (!kthread_should_stop()) { | 2039 | while (1) { |
2042 | set_current_state(TASK_INTERRUPTIBLE); | 2040 | set_current_state(TASK_INTERRUPTIBLE); |
2043 | if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { | 2041 | |
2044 | /* No pending events. Let's sleep. | 2042 | if (kthread_should_stop()) |
2045 | * Incoming connections and data will wake us up. */ | 2043 | break; |
2046 | schedule(); | ||
2047 | } | ||
2048 | set_current_state(TASK_RUNNING); | ||
2049 | 2044 | ||
2050 | /* Process stuff */ | 2045 | /* Process stuff */ |
2051 | clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
2052 | rfcomm_process_sessions(); | 2046 | rfcomm_process_sessions(); |
2047 | |||
2048 | schedule(); | ||
2053 | } | 2049 | } |
2050 | __set_current_state(TASK_RUNNING); | ||
2054 | 2051 | ||
2055 | rfcomm_kill_listener(); | 2052 | rfcomm_kill_listener(); |
2056 | 2053 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8f01e6b11a7..482722bbc7a 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
485 | 485 | ||
486 | lock_sock(sk); | 486 | lock_sock(sk); |
487 | 487 | ||
488 | if (sk->sk_state != BT_LISTEN) { | ||
489 | err = -EBADFD; | ||
490 | goto done; | ||
491 | } | ||
492 | |||
493 | if (sk->sk_type != SOCK_STREAM) { | 488 | if (sk->sk_type != SOCK_STREAM) { |
494 | err = -EINVAL; | 489 | err = -EINVAL; |
495 | goto done; | 490 | goto done; |
@@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
501 | 496 | ||
502 | /* Wait for an incoming connection. (wake-one). */ | 497 | /* Wait for an incoming connection. (wake-one). */ |
503 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 498 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
504 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 499 | while (1) { |
505 | set_current_state(TASK_INTERRUPTIBLE); | 500 | set_current_state(TASK_INTERRUPTIBLE); |
506 | if (!timeo) { | 501 | |
507 | err = -EAGAIN; | 502 | if (sk->sk_state != BT_LISTEN) { |
503 | err = -EBADFD; | ||
508 | break; | 504 | break; |
509 | } | 505 | } |
510 | 506 | ||
511 | release_sock(sk); | 507 | nsk = bt_accept_dequeue(sk, newsock); |
512 | timeo = schedule_timeout(timeo); | 508 | if (nsk) |
513 | lock_sock(sk); | 509 | break; |
514 | 510 | ||
515 | if (sk->sk_state != BT_LISTEN) { | 511 | if (!timeo) { |
516 | err = -EBADFD; | 512 | err = -EAGAIN; |
517 | break; | 513 | break; |
518 | } | 514 | } |
519 | 515 | ||
@@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
521 | err = sock_intr_errno(timeo); | 517 | err = sock_intr_errno(timeo); |
522 | break; | 518 | break; |
523 | } | 519 | } |
520 | |||
521 | release_sock(sk); | ||
522 | timeo = schedule_timeout(timeo); | ||
523 | lock_sock(sk); | ||
524 | } | 524 | } |
525 | set_current_state(TASK_RUNNING); | 525 | __set_current_state(TASK_RUNNING); |
526 | remove_wait_queue(sk_sleep(sk), &wait); | 526 | remove_wait_queue(sk_sleep(sk), &wait); |
527 | 527 | ||
528 | if (err) | 528 | if (err) |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 4c3621b5e0a..8270f05e3f1 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
564 | 564 | ||
565 | lock_sock(sk); | 565 | lock_sock(sk); |
566 | 566 | ||
567 | if (sk->sk_state != BT_LISTEN) { | ||
568 | err = -EBADFD; | ||
569 | goto done; | ||
570 | } | ||
571 | |||
572 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 567 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
573 | 568 | ||
574 | BT_DBG("sk %p timeo %ld", sk, timeo); | 569 | BT_DBG("sk %p timeo %ld", sk, timeo); |
575 | 570 | ||
576 | /* Wait for an incoming connection. (wake-one). */ | 571 | /* Wait for an incoming connection. (wake-one). */ |
577 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 572 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
578 | while (!(ch = bt_accept_dequeue(sk, newsock))) { | 573 | while (1) { |
579 | set_current_state(TASK_INTERRUPTIBLE); | 574 | set_current_state(TASK_INTERRUPTIBLE); |
580 | if (!timeo) { | 575 | |
581 | err = -EAGAIN; | 576 | if (sk->sk_state != BT_LISTEN) { |
577 | err = -EBADFD; | ||
582 | break; | 578 | break; |
583 | } | 579 | } |
584 | 580 | ||
585 | release_sock(sk); | 581 | ch = bt_accept_dequeue(sk, newsock); |
586 | timeo = schedule_timeout(timeo); | 582 | if (ch) |
587 | lock_sock(sk); | 583 | break; |
588 | 584 | ||
589 | if (sk->sk_state != BT_LISTEN) { | 585 | if (!timeo) { |
590 | err = -EBADFD; | 586 | err = -EAGAIN; |
591 | break; | 587 | break; |
592 | } | 588 | } |
593 | 589 | ||
@@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
595 | err = sock_intr_errno(timeo); | 591 | err = sock_intr_errno(timeo); |
596 | break; | 592 | break; |
597 | } | 593 | } |
594 | |||
595 | release_sock(sk); | ||
596 | timeo = schedule_timeout(timeo); | ||
597 | lock_sock(sk); | ||
598 | } | 598 | } |
599 | set_current_state(TASK_RUNNING); | 599 | __set_current_state(TASK_RUNNING); |
600 | remove_wait_queue(sk_sleep(sk), &wait); | 600 | remove_wait_queue(sk_sleep(sk), &wait); |
601 | 601 | ||
602 | if (err) | 602 | if (err) |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 3176e2e13d9..e73815456ad 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -231,6 +231,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
231 | int br_add_bridge(struct net *net, const char *name) | 231 | int br_add_bridge(struct net *net, const char *name) |
232 | { | 232 | { |
233 | struct net_device *dev; | 233 | struct net_device *dev; |
234 | int res; | ||
234 | 235 | ||
235 | dev = alloc_netdev(sizeof(struct net_bridge), name, | 236 | dev = alloc_netdev(sizeof(struct net_bridge), name, |
236 | br_dev_setup); | 237 | br_dev_setup); |
@@ -240,7 +241,10 @@ int br_add_bridge(struct net *net, const char *name) | |||
240 | 241 | ||
241 | dev_net_set(dev, net); | 242 | dev_net_set(dev, net); |
242 | 243 | ||
243 | return register_netdev(dev); | 244 | res = register_netdev(dev); |
245 | if (res) | ||
246 | free_netdev(dev); | ||
247 | return res; | ||
244 | } | 248 | } |
245 | 249 | ||
246 | int br_del_bridge(struct net *net, const char *name) | 250 | int br_del_bridge(struct net *net, const char *name) |
@@ -417,6 +421,7 @@ put_back: | |||
417 | int br_del_if(struct net_bridge *br, struct net_device *dev) | 421 | int br_del_if(struct net_bridge *br, struct net_device *dev) |
418 | { | 422 | { |
419 | struct net_bridge_port *p; | 423 | struct net_bridge_port *p; |
424 | bool changed_addr; | ||
420 | 425 | ||
421 | p = br_port_get_rtnl(dev); | 426 | p = br_port_get_rtnl(dev); |
422 | if (!p || p->br != br) | 427 | if (!p || p->br != br) |
@@ -425,9 +430,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
425 | del_nbp(p); | 430 | del_nbp(p); |
426 | 431 | ||
427 | spin_lock_bh(&br->lock); | 432 | spin_lock_bh(&br->lock); |
428 | br_stp_recalculate_bridge_id(br); | 433 | changed_addr = br_stp_recalculate_bridge_id(br); |
429 | spin_unlock_bh(&br->lock); | 434 | spin_unlock_bh(&br->lock); |
430 | 435 | ||
436 | if (changed_addr) | ||
437 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
438 | |||
431 | netdev_update_features(br->dev); | 439 | netdev_update_features(br->dev); |
432 | 440 | ||
433 | return 0; | 441 | return 0; |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2d85ca7111d..995cbe0ac0b 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -1456,7 +1456,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1456 | { | 1456 | { |
1457 | struct sk_buff *skb2; | 1457 | struct sk_buff *skb2; |
1458 | const struct ipv6hdr *ip6h; | 1458 | const struct ipv6hdr *ip6h; |
1459 | struct icmp6hdr *icmp6h; | 1459 | u8 icmp6_type; |
1460 | u8 nexthdr; | 1460 | u8 nexthdr; |
1461 | unsigned len; | 1461 | unsigned len; |
1462 | int offset; | 1462 | int offset; |
@@ -1502,9 +1502,9 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1502 | __skb_pull(skb2, offset); | 1502 | __skb_pull(skb2, offset); |
1503 | skb_reset_transport_header(skb2); | 1503 | skb_reset_transport_header(skb2); |
1504 | 1504 | ||
1505 | icmp6h = icmp6_hdr(skb2); | 1505 | icmp6_type = icmp6_hdr(skb2)->icmp6_type; |
1506 | 1506 | ||
1507 | switch (icmp6h->icmp6_type) { | 1507 | switch (icmp6_type) { |
1508 | case ICMPV6_MGM_QUERY: | 1508 | case ICMPV6_MGM_QUERY: |
1509 | case ICMPV6_MGM_REPORT: | 1509 | case ICMPV6_MGM_REPORT: |
1510 | case ICMPV6_MGM_REDUCTION: | 1510 | case ICMPV6_MGM_REDUCTION: |
@@ -1520,16 +1520,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1520 | err = pskb_trim_rcsum(skb2, len); | 1520 | err = pskb_trim_rcsum(skb2, len); |
1521 | if (err) | 1521 | if (err) |
1522 | goto out; | 1522 | goto out; |
1523 | err = -EINVAL; | ||
1523 | } | 1524 | } |
1524 | 1525 | ||
1526 | ip6h = ipv6_hdr(skb2); | ||
1527 | |||
1525 | switch (skb2->ip_summed) { | 1528 | switch (skb2->ip_summed) { |
1526 | case CHECKSUM_COMPLETE: | 1529 | case CHECKSUM_COMPLETE: |
1527 | if (!csum_fold(skb2->csum)) | 1530 | if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len, |
1531 | IPPROTO_ICMPV6, skb2->csum)) | ||
1528 | break; | 1532 | break; |
1529 | /*FALLTHROUGH*/ | 1533 | /*FALLTHROUGH*/ |
1530 | case CHECKSUM_NONE: | 1534 | case CHECKSUM_NONE: |
1531 | skb2->csum = 0; | 1535 | skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr, |
1532 | if (skb_checksum_complete(skb2)) | 1536 | &ip6h->daddr, |
1537 | skb2->len, | ||
1538 | IPPROTO_ICMPV6, 0)); | ||
1539 | if (__skb_checksum_complete(skb2)) | ||
1533 | goto out; | 1540 | goto out; |
1534 | } | 1541 | } |
1535 | 1542 | ||
@@ -1537,7 +1544,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1537 | 1544 | ||
1538 | BR_INPUT_SKB_CB(skb)->igmp = 1; | 1545 | BR_INPUT_SKB_CB(skb)->igmp = 1; |
1539 | 1546 | ||
1540 | switch (icmp6h->icmp6_type) { | 1547 | switch (icmp6_type) { |
1541 | case ICMPV6_MGM_REPORT: | 1548 | case ICMPV6_MGM_REPORT: |
1542 | { | 1549 | { |
1543 | struct mld_msg *mld; | 1550 | struct mld_msg *mld; |
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 6545ee9591d..a76b6213555 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
34 | struct net_device *dev = ptr; | 34 | struct net_device *dev = ptr; |
35 | struct net_bridge_port *p; | 35 | struct net_bridge_port *p; |
36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
37 | bool changed_addr; | ||
37 | int err; | 38 | int err; |
38 | 39 | ||
39 | /* register of bridge completed, add sysfs entries */ | 40 | /* register of bridge completed, add sysfs entries */ |
@@ -57,8 +58,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
57 | case NETDEV_CHANGEADDR: | 58 | case NETDEV_CHANGEADDR: |
58 | spin_lock_bh(&br->lock); | 59 | spin_lock_bh(&br->lock); |
59 | br_fdb_changeaddr(p, dev->dev_addr); | 60 | br_fdb_changeaddr(p, dev->dev_addr); |
60 | br_stp_recalculate_bridge_id(br); | 61 | changed_addr = br_stp_recalculate_bridge_id(br); |
61 | spin_unlock_bh(&br->lock); | 62 | spin_unlock_bh(&br->lock); |
63 | |||
64 | if (changed_addr) | ||
65 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
66 | |||
62 | break; | 67 | break; |
63 | 68 | ||
64 | case NETDEV_CHANGE: | 69 | case NETDEV_CHANGE: |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 2b5ca1a0054..5864cc49136 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1198,7 +1198,8 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) | |||
1198 | 1198 | ||
1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { | 1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { |
1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); | 1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); |
1201 | return ERR_PTR(-EINVAL); | 1201 | ret = -EINVAL; |
1202 | goto free_chainstack; | ||
1202 | } | 1203 | } |
1203 | 1204 | ||
1204 | table->private = newinfo; | 1205 | table->private = newinfo; |
diff --git a/net/core/Makefile b/net/core/Makefile index 8a04dd22cf7..0d357b1c4e5 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | 5 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ |
6 | gen_stats.o gen_estimator.o net_namespace.o | 6 | gen_stats.o gen_estimator.o net_namespace.o secure_seq.o |
7 | 7 | ||
8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
9 | 9 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8fab9b0bb20..1334d7e56f0 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1319,11 +1319,15 @@ static void neigh_proxy_process(unsigned long arg) | |||
1319 | 1319 | ||
1320 | if (tdif <= 0) { | 1320 | if (tdif <= 0) { |
1321 | struct net_device *dev = skb->dev; | 1321 | struct net_device *dev = skb->dev; |
1322 | |||
1322 | __skb_unlink(skb, &tbl->proxy_queue); | 1323 | __skb_unlink(skb, &tbl->proxy_queue); |
1323 | if (tbl->proxy_redo && netif_running(dev)) | 1324 | if (tbl->proxy_redo && netif_running(dev)) { |
1325 | rcu_read_lock(); | ||
1324 | tbl->proxy_redo(skb); | 1326 | tbl->proxy_redo(skb); |
1325 | else | 1327 | rcu_read_unlock(); |
1328 | } else { | ||
1326 | kfree_skb(skb); | 1329 | kfree_skb(skb); |
1330 | } | ||
1327 | 1331 | ||
1328 | dev_put(dev); | 1332 | dev_put(dev); |
1329 | } else if (!sched_next || tdif < sched_next) | 1333 | } else if (!sched_next || tdif < sched_next) |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index adf84dd8c7b..52622517e0d 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -558,13 +558,14 @@ int __netpoll_rx(struct sk_buff *skb) | |||
558 | if (skb_shared(skb)) | 558 | if (skb_shared(skb)) |
559 | goto out; | 559 | goto out; |
560 | 560 | ||
561 | iph = (struct iphdr *)skb->data; | ||
562 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 561 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
563 | goto out; | 562 | goto out; |
563 | iph = (struct iphdr *)skb->data; | ||
564 | if (iph->ihl < 5 || iph->version != 4) | 564 | if (iph->ihl < 5 || iph->version != 4) |
565 | goto out; | 565 | goto out; |
566 | if (!pskb_may_pull(skb, iph->ihl*4)) | 566 | if (!pskb_may_pull(skb, iph->ihl*4)) |
567 | goto out; | 567 | goto out; |
568 | iph = (struct iphdr *)skb->data; | ||
568 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) | 569 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) |
569 | goto out; | 570 | goto out; |
570 | 571 | ||
@@ -579,6 +580,7 @@ int __netpoll_rx(struct sk_buff *skb) | |||
579 | if (pskb_trim_rcsum(skb, len)) | 580 | if (pskb_trim_rcsum(skb, len)) |
580 | goto out; | 581 | goto out; |
581 | 582 | ||
583 | iph = (struct iphdr *)skb->data; | ||
582 | if (iph->protocol != IPPROTO_UDP) | 584 | if (iph->protocol != IPPROTO_UDP) |
583 | goto out; | 585 | goto out; |
584 | 586 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 4c1ef026d69..811b53fb330 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -192,7 +192,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
192 | goto error; | 192 | goto error; |
193 | 193 | ||
194 | cred->uid = cred->euid = p->creds.uid; | 194 | cred->uid = cred->euid = p->creds.uid; |
195 | cred->gid = cred->egid = p->creds.uid; | 195 | cred->gid = cred->egid = p->creds.gid; |
196 | put_cred(p->cred); | 196 | put_cred(p->cred); |
197 | p->cred = cred; | 197 | p->cred = cred; |
198 | } | 198 | } |
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c new file mode 100644 index 00000000000..45329d7c9dd --- /dev/null +++ b/net/core/secure_seq.c | |||
@@ -0,0 +1,184 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/cryptohash.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/cache.h> | ||
6 | #include <linux/random.h> | ||
7 | #include <linux/hrtimer.h> | ||
8 | #include <linux/ktime.h> | ||
9 | #include <linux/string.h> | ||
10 | |||
11 | #include <net/secure_seq.h> | ||
12 | |||
13 | static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | ||
14 | |||
15 | static int __init net_secret_init(void) | ||
16 | { | ||
17 | get_random_bytes(net_secret, sizeof(net_secret)); | ||
18 | return 0; | ||
19 | } | ||
20 | late_initcall(net_secret_init); | ||
21 | |||
22 | static u32 seq_scale(u32 seq) | ||
23 | { | ||
24 | /* | ||
25 | * As close as possible to RFC 793, which | ||
26 | * suggests using a 250 kHz clock. | ||
27 | * Further reading shows this assumes 2 Mb/s networks. | ||
28 | * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. | ||
29 | * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but | ||
30 | * we also need to limit the resolution so that the u32 seq | ||
31 | * overlaps less than one time per MSL (2 minutes). | ||
32 | * Choosing a clock of 64 ns period is OK. (period of 274 s) | ||
33 | */ | ||
34 | return seq + (ktime_to_ns(ktime_get_real()) >> 6); | ||
35 | } | ||
36 | |||
37 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
38 | __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, | ||
39 | __be16 sport, __be16 dport) | ||
40 | { | ||
41 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
42 | u32 hash[MD5_DIGEST_WORDS]; | ||
43 | u32 i; | ||
44 | |||
45 | memcpy(hash, saddr, 16); | ||
46 | for (i = 0; i < 4; i++) | ||
47 | secret[i] = net_secret[i] + daddr[i]; | ||
48 | secret[4] = net_secret[4] + | ||
49 | (((__force u16)sport << 16) + (__force u16)dport); | ||
50 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
51 | secret[i] = net_secret[i]; | ||
52 | |||
53 | md5_transform(hash, secret); | ||
54 | |||
55 | return seq_scale(hash[0]); | ||
56 | } | ||
57 | EXPORT_SYMBOL(secure_tcpv6_sequence_number); | ||
58 | |||
59 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, | ||
60 | __be16 dport) | ||
61 | { | ||
62 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
63 | u32 hash[MD5_DIGEST_WORDS]; | ||
64 | u32 i; | ||
65 | |||
66 | memcpy(hash, saddr, 16); | ||
67 | for (i = 0; i < 4; i++) | ||
68 | secret[i] = net_secret[i] + (__force u32) daddr[i]; | ||
69 | secret[4] = net_secret[4] + (__force u32)dport; | ||
70 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
71 | secret[i] = net_secret[i]; | ||
72 | |||
73 | md5_transform(hash, secret); | ||
74 | |||
75 | return hash[0]; | ||
76 | } | ||
77 | #endif | ||
78 | |||
79 | #ifdef CONFIG_INET | ||
80 | __u32 secure_ip_id(__be32 daddr) | ||
81 | { | ||
82 | u32 hash[MD5_DIGEST_WORDS]; | ||
83 | |||
84 | hash[0] = (__force __u32) daddr; | ||
85 | hash[1] = net_secret[13]; | ||
86 | hash[2] = net_secret[14]; | ||
87 | hash[3] = net_secret[15]; | ||
88 | |||
89 | md5_transform(hash, net_secret); | ||
90 | |||
91 | return hash[0]; | ||
92 | } | ||
93 | |||
94 | __u32 secure_ipv6_id(const __be32 daddr[4]) | ||
95 | { | ||
96 | __u32 hash[4]; | ||
97 | |||
98 | memcpy(hash, daddr, 16); | ||
99 | md5_transform(hash, net_secret); | ||
100 | |||
101 | return hash[0]; | ||
102 | } | ||
103 | |||
104 | __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | ||
105 | __be16 sport, __be16 dport) | ||
106 | { | ||
107 | u32 hash[MD5_DIGEST_WORDS]; | ||
108 | |||
109 | hash[0] = (__force u32)saddr; | ||
110 | hash[1] = (__force u32)daddr; | ||
111 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
112 | hash[3] = net_secret[15]; | ||
113 | |||
114 | md5_transform(hash, net_secret); | ||
115 | |||
116 | return seq_scale(hash[0]); | ||
117 | } | ||
118 | |||
119 | u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) | ||
120 | { | ||
121 | u32 hash[MD5_DIGEST_WORDS]; | ||
122 | |||
123 | hash[0] = (__force u32)saddr; | ||
124 | hash[1] = (__force u32)daddr; | ||
125 | hash[2] = (__force u32)dport ^ net_secret[14]; | ||
126 | hash[3] = net_secret[15]; | ||
127 | |||
128 | md5_transform(hash, net_secret); | ||
129 | |||
130 | return hash[0]; | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); | ||
133 | #endif | ||
134 | |||
135 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | ||
136 | u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, | ||
137 | __be16 sport, __be16 dport) | ||
138 | { | ||
139 | u32 hash[MD5_DIGEST_WORDS]; | ||
140 | u64 seq; | ||
141 | |||
142 | hash[0] = (__force u32)saddr; | ||
143 | hash[1] = (__force u32)daddr; | ||
144 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
145 | hash[3] = net_secret[15]; | ||
146 | |||
147 | md5_transform(hash, net_secret); | ||
148 | |||
149 | seq = hash[0] | (((u64)hash[1]) << 32); | ||
150 | seq += ktime_to_ns(ktime_get_real()); | ||
151 | seq &= (1ull << 48) - 1; | ||
152 | |||
153 | return seq; | ||
154 | } | ||
155 | EXPORT_SYMBOL(secure_dccp_sequence_number); | ||
156 | |||
157 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
158 | u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | ||
159 | __be16 sport, __be16 dport) | ||
160 | { | ||
161 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
162 | u32 hash[MD5_DIGEST_WORDS]; | ||
163 | u64 seq; | ||
164 | u32 i; | ||
165 | |||
166 | memcpy(hash, saddr, 16); | ||
167 | for (i = 0; i < 4; i++) | ||
168 | secret[i] = net_secret[i] + daddr[i]; | ||
169 | secret[4] = net_secret[4] + | ||
170 | (((__force u16)sport << 16) + (__force u16)dport); | ||
171 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
172 | secret[i] = net_secret[i]; | ||
173 | |||
174 | md5_transform(hash, secret); | ||
175 | |||
176 | seq = hash[0] | (((u64)hash[1]) << 32); | ||
177 | seq += ktime_to_ns(ktime_get_real()); | ||
178 | seq &= (1ull << 48) - 1; | ||
179 | |||
180 | return seq; | ||
181 | } | ||
182 | EXPORT_SYMBOL(secure_dccpv6_sequence_number); | ||
183 | #endif | ||
184 | #endif | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2beda824636..27002dffe7e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1369,8 +1369,21 @@ pull_pages: | |||
1369 | } | 1369 | } |
1370 | EXPORT_SYMBOL(__pskb_pull_tail); | 1370 | EXPORT_SYMBOL(__pskb_pull_tail); |
1371 | 1371 | ||
1372 | /* Copy some data bits from skb to kernel buffer. */ | 1372 | /** |
1373 | 1373 | * skb_copy_bits - copy bits from skb to kernel buffer | |
1374 | * @skb: source skb | ||
1375 | * @offset: offset in source | ||
1376 | * @to: destination buffer | ||
1377 | * @len: number of bytes to copy | ||
1378 | * | ||
1379 | * Copy the specified number of bytes from the source skb to the | ||
1380 | * destination buffer. | ||
1381 | * | ||
1382 | * CAUTION ! : | ||
1383 | * If its prototype is ever changed, | ||
1384 | * check arch/{*}/net/{*}.S files, | ||
1385 | * since it is called from BPF assembly code. | ||
1386 | */ | ||
1374 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | 1387 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) |
1375 | { | 1388 | { |
1376 | int start = skb_headlen(skb); | 1389 | int start = skb_headlen(skb); |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 8c36adfd191..332639b56f4 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <net/timewait_sock.h> | 26 | #include <net/timewait_sock.h> |
27 | #include <net/tcp_states.h> | 27 | #include <net/tcp_states.h> |
28 | #include <net/xfrm.h> | 28 | #include <net/xfrm.h> |
29 | #include <net/secure_seq.h> | ||
29 | 30 | ||
30 | #include "ackvec.h" | 31 | #include "ackvec.h" |
31 | #include "ccid.h" | 32 | #include "ccid.h" |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 8dc4348774a..b74f76117dc 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <net/transp_v6.h> | 29 | #include <net/transp_v6.h> |
30 | #include <net/ip6_checksum.h> | 30 | #include <net/ip6_checksum.h> |
31 | #include <net/xfrm.h> | 31 | #include <net/xfrm.h> |
32 | #include <net/secure_seq.h> | ||
32 | 33 | ||
33 | #include "dccp.h" | 34 | #include "dccp.h" |
34 | #include "ipv6.h" | 35 | #include "ipv6.h" |
@@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) | |||
69 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); | 70 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); |
70 | } | 71 | } |
71 | 72 | ||
72 | static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | 73 | static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
73 | __be16 sport, __be16 dport ) | ||
74 | { | ||
75 | return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); | ||
76 | } | ||
77 | |||
78 | static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) | ||
79 | { | 74 | { |
80 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, | 75 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
81 | ipv6_hdr(skb)->saddr.s6_addr32, | 76 | ipv6_hdr(skb)->saddr.s6_addr32, |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f1d27f6c935..d577199eabd 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -767,7 +767,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) | |||
767 | break; | 767 | break; |
768 | for (i=0; i<nsrcs; i++) { | 768 | for (i=0; i<nsrcs; i++) { |
769 | /* skip inactive filters */ | 769 | /* skip inactive filters */ |
770 | if (pmc->sfcount[MCAST_INCLUDE] || | 770 | if (psf->sf_count[MCAST_INCLUDE] || |
771 | pmc->sfcount[MCAST_EXCLUDE] != | 771 | pmc->sfcount[MCAST_EXCLUDE] != |
772 | psf->sf_count[MCAST_EXCLUDE]) | 772 | psf->sf_count[MCAST_EXCLUDE]) |
773 | continue; | 773 | continue; |
@@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, | |||
1718 | 1718 | ||
1719 | pmc->sfcount[sfmode]--; | 1719 | pmc->sfcount[sfmode]--; |
1720 | for (j=0; j<i; j++) | 1720 | for (j=0; j<i; j++) |
1721 | (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); | 1721 | (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); |
1722 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { | 1722 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { |
1723 | #ifdef CONFIG_IP_MULTICAST | 1723 | #ifdef CONFIG_IP_MULTICAST |
1724 | struct ip_sf_list *psf; | 1724 | struct ip_sf_list *psf; |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 3c0369a3a66..984ec656b03 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <net/inet_connection_sock.h> | 22 | #include <net/inet_connection_sock.h> |
23 | #include <net/inet_hashtables.h> | 23 | #include <net/inet_hashtables.h> |
24 | #include <net/secure_seq.h> | ||
24 | #include <net/ip.h> | 25 | #include <net/ip.h> |
25 | 26 | ||
26 | /* | 27 | /* |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index e38213817d0..86f13c67ea8 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/net.h> | 19 | #include <linux/net.h> |
20 | #include <net/ip.h> | 20 | #include <net/ip.h> |
21 | #include <net/inetpeer.h> | 21 | #include <net/inetpeer.h> |
22 | #include <net/secure_seq.h> | ||
22 | 23 | ||
23 | /* | 24 | /* |
24 | * Theory of operations. | 25 | * Theory of operations. |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ccaaa851ab4..8c6563361ab 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -122,6 +122,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
122 | newskb->pkt_type = PACKET_LOOPBACK; | 122 | newskb->pkt_type = PACKET_LOOPBACK; |
123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
124 | WARN_ON(!skb_dst(newskb)); | 124 | WARN_ON(!skb_dst(newskb)); |
125 | skb_dst_force(newskb); | ||
125 | netif_rx_ni(newskb); | 126 | netif_rx_ni(newskb); |
126 | return 0; | 127 | return 0; |
127 | } | 128 | } |
@@ -204,9 +205,15 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
204 | skb = skb2; | 205 | skb = skb2; |
205 | } | 206 | } |
206 | 207 | ||
208 | rcu_read_lock(); | ||
207 | neigh = dst_get_neighbour(dst); | 209 | neigh = dst_get_neighbour(dst); |
208 | if (neigh) | 210 | if (neigh) { |
209 | return neigh_output(neigh, skb); | 211 | int res = neigh_output(neigh, skb); |
212 | |||
213 | rcu_read_unlock(); | ||
214 | return res; | ||
215 | } | ||
216 | rcu_read_unlock(); | ||
210 | 217 | ||
211 | if (net_ratelimit()) | 218 | if (net_ratelimit()) |
212 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); | 219 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ab0c9efd1ef..8905e92f896 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); | |||
1067 | */ | 1067 | */ |
1068 | 1068 | ||
1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
1070 | char __user *optval, int __user *optlen) | 1070 | char __user *optval, int __user *optlen, unsigned flags) |
1071 | { | 1071 | { |
1072 | struct inet_sock *inet = inet_sk(sk); | 1072 | struct inet_sock *inet = inet_sk(sk); |
1073 | int val; | 1073 | int val; |
@@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1240 | 1240 | ||
1241 | msg.msg_control = optval; | 1241 | msg.msg_control = optval; |
1242 | msg.msg_controllen = len; | 1242 | msg.msg_controllen = len; |
1243 | msg.msg_flags = 0; | 1243 | msg.msg_flags = flags; |
1244 | 1244 | ||
1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { | 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { |
1246 | struct in_pktinfo info; | 1246 | struct in_pktinfo info; |
@@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
1294 | { | 1294 | { |
1295 | int err; | 1295 | int err; |
1296 | 1296 | ||
1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); |
1298 | #ifdef CONFIG_NETFILTER | 1298 | #ifdef CONFIG_NETFILTER |
1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && | 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && |
@@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
1328 | ip_getsockopt); | 1328 | ip_getsockopt); |
1329 | 1329 | ||
1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, |
1331 | MSG_CMSG_COMPAT); | ||
1331 | 1332 | ||
1332 | #ifdef CONFIG_NETFILTER | 1333 | #ifdef CONFIG_NETFILTER |
1333 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1334 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 2e97e3ec1eb..929b27bdeb7 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
18 | struct rtable *rt; | 18 | struct rtable *rt; |
19 | struct flowi4 fl4 = {}; | 19 | struct flowi4 fl4 = {}; |
20 | __be32 saddr = iph->saddr; | 20 | __be32 saddr = iph->saddr; |
21 | __u8 flags = 0; | 21 | __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
22 | unsigned int hh_len; | 22 | unsigned int hh_len; |
23 | 23 | ||
24 | if (!skb->sk && addr_type != RTN_LOCAL) { | 24 | if (addr_type == RTN_UNSPEC) |
25 | if (addr_type == RTN_UNSPEC) | 25 | addr_type = inet_addr_type(net, saddr); |
26 | addr_type = inet_addr_type(net, saddr); | 26 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) |
27 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) | 27 | flags |= FLOWI_FLAG_ANYSRC; |
28 | flags |= FLOWI_FLAG_ANYSRC; | 28 | else |
29 | else | 29 | saddr = 0; |
30 | saddr = 0; | ||
31 | } | ||
32 | 30 | ||
33 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause | 31 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause |
34 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. | 32 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. |
@@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
38 | fl4.flowi4_tos = RT_TOS(iph->tos); | 36 | fl4.flowi4_tos = RT_TOS(iph->tos); |
39 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 37 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
40 | fl4.flowi4_mark = skb->mark; | 38 | fl4.flowi4_mark = skb->mark; |
41 | fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; | 39 | fl4.flowi4_flags = flags; |
42 | rt = ip_route_output_key(net, &fl4); | 40 | rt = ip_route_output_key(net, &fl4); |
43 | if (IS_ERR(rt)) | 41 | if (IS_ERR(rt)) |
44 | return -1; | 42 | return -1; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c index 3e61faf23a9..f52d41ea069 100644 --- a/net/ipv4/netfilter/nf_nat_proto_common.c +++ b/net/ipv4/netfilter/nf_nat_proto_common.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
13 | 13 | ||
14 | #include <linux/netfilter.h> | 14 | #include <linux/netfilter.h> |
15 | #include <net/secure_seq.h> | ||
15 | #include <net/netfilter/nf_nat.h> | 16 | #include <net/netfilter/nf_nat.h> |
16 | #include <net/netfilter/nf_nat_core.h> | 17 | #include <net/netfilter/nf_nat_core.h> |
17 | #include <net/netfilter/nf_nat_rule.h> | 18 | #include <net/netfilter/nf_nat_rule.h> |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 1457acb39ce..61714bd5292 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
564 | RT_SCOPE_UNIVERSE, | 564 | RT_SCOPE_UNIVERSE, |
565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
566 | FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); | 566 | inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, |
567 | daddr, saddr, 0, 0); | ||
567 | 568 | ||
568 | if (!inet->hdrincl) { | 569 | if (!inet->hdrincl) { |
569 | err = raw_probe_proto_opt(&fl4, msg); | 570 | err = raw_probe_proto_opt(&fl4, msg); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1730689f560..075212e41b8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -109,6 +109,7 @@ | |||
109 | #include <linux/sysctl.h> | 109 | #include <linux/sysctl.h> |
110 | #endif | 110 | #endif |
111 | #include <net/atmclip.h> | 111 | #include <net/atmclip.h> |
112 | #include <net/secure_seq.h> | ||
112 | 113 | ||
113 | #define RT_FL_TOS(oldflp4) \ | 114 | #define RT_FL_TOS(oldflp4) \ |
114 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) | 115 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) |
@@ -721,7 +722,7 @@ static inline bool compare_hash_inputs(const struct rtable *rt1, | |||
721 | { | 722 | { |
722 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | | 723 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | |
723 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 724 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
724 | (rt1->rt_iif ^ rt2->rt_iif)) == 0); | 725 | (rt1->rt_route_iif ^ rt2->rt_route_iif)) == 0); |
725 | } | 726 | } |
726 | 727 | ||
727 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | 728 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) |
@@ -730,8 +731,8 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | |||
730 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 731 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
731 | (rt1->rt_mark ^ rt2->rt_mark) | | 732 | (rt1->rt_mark ^ rt2->rt_mark) | |
732 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | | 733 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
733 | (rt1->rt_oif ^ rt2->rt_oif) | | 734 | (rt1->rt_route_iif ^ rt2->rt_route_iif) | |
734 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; | 735 | (rt1->rt_oif ^ rt2->rt_oif)) == 0; |
735 | } | 736 | } |
736 | 737 | ||
737 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | 738 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) |
@@ -1628,16 +1629,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | |||
1628 | { | 1629 | { |
1629 | struct rtable *rt = (struct rtable *) dst; | 1630 | struct rtable *rt = (struct rtable *) dst; |
1630 | __be32 orig_gw = rt->rt_gateway; | 1631 | __be32 orig_gw = rt->rt_gateway; |
1631 | struct neighbour *n; | 1632 | struct neighbour *n, *old_n; |
1632 | 1633 | ||
1633 | dst_confirm(&rt->dst); | 1634 | dst_confirm(&rt->dst); |
1634 | 1635 | ||
1635 | neigh_release(dst_get_neighbour(&rt->dst)); | ||
1636 | dst_set_neighbour(&rt->dst, NULL); | ||
1637 | |||
1638 | rt->rt_gateway = peer->redirect_learned.a4; | 1636 | rt->rt_gateway = peer->redirect_learned.a4; |
1639 | rt_bind_neighbour(rt); | 1637 | |
1640 | n = dst_get_neighbour(&rt->dst); | 1638 | n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); |
1639 | if (IS_ERR(n)) | ||
1640 | return PTR_ERR(n); | ||
1641 | old_n = xchg(&rt->dst._neighbour, n); | ||
1642 | if (old_n) | ||
1643 | neigh_release(old_n); | ||
1641 | if (!n || !(n->nud_state & NUD_VALID)) { | 1644 | if (!n || !(n->nud_state & NUD_VALID)) { |
1642 | if (n) | 1645 | if (n) |
1643 | neigh_event_send(n, NULL); | 1646 | neigh_event_send(n, NULL); |
@@ -2317,8 +2320,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2317 | rth = rcu_dereference(rth->dst.rt_next)) { | 2320 | rth = rcu_dereference(rth->dst.rt_next)) { |
2318 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | | 2321 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | |
2319 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | | 2322 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
2320 | (rth->rt_iif ^ iif) | | 2323 | (rth->rt_route_iif ^ iif) | |
2321 | rth->rt_oif | | ||
2322 | (rth->rt_key_tos ^ tos)) == 0 && | 2324 | (rth->rt_key_tos ^ tos)) == 0 && |
2323 | rth->rt_mark == skb->mark && | 2325 | rth->rt_mark == skb->mark && |
2324 | net_eq(dev_net(rth->dst.dev), net) && | 2326 | net_eq(dev_net(rth->dst.dev), net) && |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 92bb9434b33..3bc5c8f7c71 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -276,7 +276,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
276 | int mss; | 276 | int mss; |
277 | struct rtable *rt; | 277 | struct rtable *rt; |
278 | __u8 rcv_wscale; | 278 | __u8 rcv_wscale; |
279 | bool ecn_ok; | 279 | bool ecn_ok = false; |
280 | 280 | ||
281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
282 | goto out; | 282 | goto out; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 955b8e65b69..1c12b8ec849 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <net/timewait_sock.h> | 72 | #include <net/timewait_sock.h> |
73 | #include <net/xfrm.h> | 73 | #include <net/xfrm.h> |
74 | #include <net/netdma.h> | 74 | #include <net/netdma.h> |
75 | #include <net/secure_seq.h> | ||
75 | 76 | ||
76 | #include <linux/inet.h> | 77 | #include <linux/inet.h> |
77 | #include <linux/ipv6.h> | 78 | #include <linux/ipv6.h> |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a55500cc0b2..f012ebd87b4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
656 | * layer address of our nexhop router | 656 | * layer address of our nexhop router |
657 | */ | 657 | */ |
658 | 658 | ||
659 | if (dst_get_neighbour(&rt->dst) == NULL) | 659 | if (dst_get_neighbour_raw(&rt->dst) == NULL) |
660 | ifa->flags &= ~IFA_F_OPTIMISTIC; | 660 | ifa->flags &= ~IFA_F_OPTIMISTIC; |
661 | 661 | ||
662 | ifa->idev = idev; | 662 | ifa->idev = idev; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 16560336eb7..9ef1831746e 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -33,6 +33,11 @@ | |||
33 | #include <linux/errqueue.h> | 33 | #include <linux/errqueue.h> |
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | 35 | ||
36 | static inline int ipv6_mapped_addr_any(const struct in6_addr *a) | ||
37 | { | ||
38 | return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0)); | ||
39 | } | ||
40 | |||
36 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 41 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
37 | { | 42 | { |
38 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | 43 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
@@ -102,10 +107,12 @@ ipv4_connected: | |||
102 | 107 | ||
103 | ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); | 108 | ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); |
104 | 109 | ||
105 | if (ipv6_addr_any(&np->saddr)) | 110 | if (ipv6_addr_any(&np->saddr) || |
111 | ipv6_mapped_addr_any(&np->saddr)) | ||
106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 112 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
107 | 113 | ||
108 | if (ipv6_addr_any(&np->rcv_saddr)) { | 114 | if (ipv6_addr_any(&np->rcv_saddr) || |
115 | ipv6_mapped_addr_any(&np->rcv_saddr)) { | ||
109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, | 116 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, |
110 | &np->rcv_saddr); | 117 | &np->rcv_saddr); |
111 | if (sk->sk_prot->rehash) | 118 | if (sk->sk_prot->rehash) |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index b5319723370..73f1a00a96a 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <net/inet_connection_sock.h> | 20 | #include <net/inet_connection_sock.h> |
21 | #include <net/inet_hashtables.h> | 21 | #include <net/inet_hashtables.h> |
22 | #include <net/inet6_hashtables.h> | 22 | #include <net/inet6_hashtables.h> |
23 | #include <net/secure_seq.h> | ||
23 | #include <net/ip.h> | 24 | #include <net/ip.h> |
24 | 25 | ||
25 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) | 26 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 54a4678955b..320d91d20ad 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) | |||
1455 | RT6_TRACE("aging clone %p\n", rt); | 1455 | RT6_TRACE("aging clone %p\n", rt); |
1456 | return -1; | 1456 | return -1; |
1457 | } else if ((rt->rt6i_flags & RTF_GATEWAY) && | 1457 | } else if ((rt->rt6i_flags & RTF_GATEWAY) && |
1458 | (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) { | 1458 | (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) { |
1459 | RT6_TRACE("purging route %p via non-router but gateway\n", | 1459 | RT6_TRACE("purging route %p via non-router but gateway\n", |
1460 | rt); | 1460 | rt); |
1461 | return -1; | 1461 | return -1; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 32e5339db0c..4c882cf4e8a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -135,10 +135,15 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
135 | skb->len); | 135 | skb->len); |
136 | } | 136 | } |
137 | 137 | ||
138 | rcu_read_lock(); | ||
138 | neigh = dst_get_neighbour(dst); | 139 | neigh = dst_get_neighbour(dst); |
139 | if (neigh) | 140 | if (neigh) { |
140 | return neigh_output(neigh, skb); | 141 | int res = neigh_output(neigh, skb); |
141 | 142 | ||
143 | rcu_read_unlock(); | ||
144 | return res; | ||
145 | } | ||
146 | rcu_read_unlock(); | ||
142 | IP6_INC_STATS_BH(dev_net(dst->dev), | 147 | IP6_INC_STATS_BH(dev_net(dst->dev), |
143 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 148 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
144 | kfree_skb(skb); | 149 | kfree_skb(skb); |
@@ -975,12 +980,14 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
975 | * dst entry and replace it instead with the | 980 | * dst entry and replace it instead with the |
976 | * dst entry of the nexthop router | 981 | * dst entry of the nexthop router |
977 | */ | 982 | */ |
983 | rcu_read_lock(); | ||
978 | n = dst_get_neighbour(*dst); | 984 | n = dst_get_neighbour(*dst); |
979 | if (n && !(n->nud_state & NUD_VALID)) { | 985 | if (n && !(n->nud_state & NUD_VALID)) { |
980 | struct inet6_ifaddr *ifp; | 986 | struct inet6_ifaddr *ifp; |
981 | struct flowi6 fl_gw6; | 987 | struct flowi6 fl_gw6; |
982 | int redirect; | 988 | int redirect; |
983 | 989 | ||
990 | rcu_read_unlock(); | ||
984 | ifp = ipv6_get_ifaddr(net, &fl6->saddr, | 991 | ifp = ipv6_get_ifaddr(net, &fl6->saddr, |
985 | (*dst)->dev, 1); | 992 | (*dst)->dev, 1); |
986 | 993 | ||
@@ -1000,6 +1007,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
1000 | if ((err = (*dst)->error)) | 1007 | if ((err = (*dst)->error)) |
1001 | goto out_err_release; | 1008 | goto out_err_release; |
1002 | } | 1009 | } |
1010 | } else { | ||
1011 | rcu_read_unlock(); | ||
1003 | } | 1012 | } |
1004 | #endif | 1013 | #endif |
1005 | 1014 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 9cb191ecaba..147ede38ab4 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -913,7 +913,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt, | |||
913 | } | 913 | } |
914 | 914 | ||
915 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | 915 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, |
916 | char __user *optval, int __user *optlen) | 916 | char __user *optval, int __user *optlen, unsigned flags) |
917 | { | 917 | { |
918 | struct ipv6_pinfo *np = inet6_sk(sk); | 918 | struct ipv6_pinfo *np = inet6_sk(sk); |
919 | int len; | 919 | int len; |
@@ -962,7 +962,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
962 | 962 | ||
963 | msg.msg_control = optval; | 963 | msg.msg_control = optval; |
964 | msg.msg_controllen = len; | 964 | msg.msg_controllen = len; |
965 | msg.msg_flags = 0; | 965 | msg.msg_flags = flags; |
966 | 966 | ||
967 | lock_sock(sk); | 967 | lock_sock(sk); |
968 | skb = np->pktoptions; | 968 | skb = np->pktoptions; |
@@ -1222,7 +1222,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1222 | if(level != SOL_IPV6) | 1222 | if(level != SOL_IPV6) |
1223 | return -ENOPROTOOPT; | 1223 | return -ENOPROTOOPT; |
1224 | 1224 | ||
1225 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | 1225 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0); |
1226 | #ifdef CONFIG_NETFILTER | 1226 | #ifdef CONFIG_NETFILTER |
1227 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1227 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
1228 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { | 1228 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { |
@@ -1264,7 +1264,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1264 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1264 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
1265 | ipv6_getsockopt); | 1265 | ipv6_getsockopt); |
1266 | 1266 | ||
1267 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | 1267 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, |
1268 | MSG_CMSG_COMPAT); | ||
1268 | #ifdef CONFIG_NETFILTER | 1269 | #ifdef CONFIG_NETFILTER |
1269 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1270 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
1270 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { | 1271 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 3e6ebcdb477..ee7839f4d6e 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1059,7 +1059,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
1059 | break; | 1059 | break; |
1060 | for (i=0; i<nsrcs; i++) { | 1060 | for (i=0; i<nsrcs; i++) { |
1061 | /* skip inactive filters */ | 1061 | /* skip inactive filters */ |
1062 | if (pmc->mca_sfcount[MCAST_INCLUDE] || | 1062 | if (psf->sf_count[MCAST_INCLUDE] || |
1063 | pmc->mca_sfcount[MCAST_EXCLUDE] != | 1063 | pmc->mca_sfcount[MCAST_EXCLUDE] != |
1064 | psf->sf_count[MCAST_EXCLUDE]) | 1064 | psf->sf_count[MCAST_EXCLUDE]) |
1065 | continue; | 1065 | continue; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e8987da0666..9e69eb0ec6d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -364,7 +364,7 @@ out: | |||
364 | #ifdef CONFIG_IPV6_ROUTER_PREF | 364 | #ifdef CONFIG_IPV6_ROUTER_PREF |
365 | static void rt6_probe(struct rt6_info *rt) | 365 | static void rt6_probe(struct rt6_info *rt) |
366 | { | 366 | { |
367 | struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; | 367 | struct neighbour *neigh; |
368 | /* | 368 | /* |
369 | * Okay, this does not seem to be appropriate | 369 | * Okay, this does not seem to be appropriate |
370 | * for now, however, we need to check if it | 370 | * for now, however, we need to check if it |
@@ -373,8 +373,10 @@ static void rt6_probe(struct rt6_info *rt) | |||
373 | * Router Reachability Probe MUST be rate-limited | 373 | * Router Reachability Probe MUST be rate-limited |
374 | * to no more than one per minute. | 374 | * to no more than one per minute. |
375 | */ | 375 | */ |
376 | rcu_read_lock(); | ||
377 | neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; | ||
376 | if (!neigh || (neigh->nud_state & NUD_VALID)) | 378 | if (!neigh || (neigh->nud_state & NUD_VALID)) |
377 | return; | 379 | goto out; |
378 | read_lock_bh(&neigh->lock); | 380 | read_lock_bh(&neigh->lock); |
379 | if (!(neigh->nud_state & NUD_VALID) && | 381 | if (!(neigh->nud_state & NUD_VALID) && |
380 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { | 382 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { |
@@ -387,8 +389,11 @@ static void rt6_probe(struct rt6_info *rt) | |||
387 | target = (struct in6_addr *)&neigh->primary_key; | 389 | target = (struct in6_addr *)&neigh->primary_key; |
388 | addrconf_addr_solict_mult(target, &mcaddr); | 390 | addrconf_addr_solict_mult(target, &mcaddr); |
389 | ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); | 391 | ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); |
390 | } else | 392 | } else { |
391 | read_unlock_bh(&neigh->lock); | 393 | read_unlock_bh(&neigh->lock); |
394 | } | ||
395 | out: | ||
396 | rcu_read_unlock(); | ||
392 | } | 397 | } |
393 | #else | 398 | #else |
394 | static inline void rt6_probe(struct rt6_info *rt) | 399 | static inline void rt6_probe(struct rt6_info *rt) |
@@ -412,8 +417,11 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) | |||
412 | 417 | ||
413 | static inline int rt6_check_neigh(struct rt6_info *rt) | 418 | static inline int rt6_check_neigh(struct rt6_info *rt) |
414 | { | 419 | { |
415 | struct neighbour *neigh = dst_get_neighbour(&rt->dst); | 420 | struct neighbour *neigh; |
416 | int m; | 421 | int m; |
422 | |||
423 | rcu_read_lock(); | ||
424 | neigh = dst_get_neighbour(&rt->dst); | ||
417 | if (rt->rt6i_flags & RTF_NONEXTHOP || | 425 | if (rt->rt6i_flags & RTF_NONEXTHOP || |
418 | !(rt->rt6i_flags & RTF_GATEWAY)) | 426 | !(rt->rt6i_flags & RTF_GATEWAY)) |
419 | m = 1; | 427 | m = 1; |
@@ -430,6 +438,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt) | |||
430 | read_unlock_bh(&neigh->lock); | 438 | read_unlock_bh(&neigh->lock); |
431 | } else | 439 | } else |
432 | m = 0; | 440 | m = 0; |
441 | rcu_read_unlock(); | ||
433 | return m; | 442 | return m; |
434 | } | 443 | } |
435 | 444 | ||
@@ -769,7 +778,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, | |||
769 | rt->rt6i_dst.plen = 128; | 778 | rt->rt6i_dst.plen = 128; |
770 | rt->rt6i_flags |= RTF_CACHE; | 779 | rt->rt6i_flags |= RTF_CACHE; |
771 | rt->dst.flags |= DST_HOST; | 780 | rt->dst.flags |= DST_HOST; |
772 | dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst))); | 781 | dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst))); |
773 | } | 782 | } |
774 | return rt; | 783 | return rt; |
775 | } | 784 | } |
@@ -803,7 +812,7 @@ restart: | |||
803 | dst_hold(&rt->dst); | 812 | dst_hold(&rt->dst); |
804 | read_unlock_bh(&table->tb6_lock); | 813 | read_unlock_bh(&table->tb6_lock); |
805 | 814 | ||
806 | if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 815 | if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
807 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); | 816 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); |
808 | else if (!(rt->dst.flags & DST_HOST)) | 817 | else if (!(rt->dst.flags & DST_HOST)) |
809 | nrt = rt6_alloc_clone(rt, &fl6->daddr); | 818 | nrt = rt6_alloc_clone(rt, &fl6->daddr); |
@@ -1587,7 +1596,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, | |||
1587 | dst_confirm(&rt->dst); | 1596 | dst_confirm(&rt->dst); |
1588 | 1597 | ||
1589 | /* Duplicate redirect: silently ignore. */ | 1598 | /* Duplicate redirect: silently ignore. */ |
1590 | if (neigh == dst_get_neighbour(&rt->dst)) | 1599 | if (neigh == dst_get_neighbour_raw(&rt->dst)) |
1591 | goto out; | 1600 | goto out; |
1592 | 1601 | ||
1593 | nrt = ip6_rt_copy(rt, dest); | 1602 | nrt = ip6_rt_copy(rt, dest); |
@@ -1682,7 +1691,7 @@ again: | |||
1682 | 1. It is connected route. Action: COW | 1691 | 1. It is connected route. Action: COW |
1683 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. | 1692 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. |
1684 | */ | 1693 | */ |
1685 | if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 1694 | if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
1686 | nrt = rt6_alloc_cow(rt, daddr, saddr); | 1695 | nrt = rt6_alloc_cow(rt, daddr, saddr); |
1687 | else | 1696 | else |
1688 | nrt = rt6_alloc_clone(rt, daddr); | 1697 | nrt = rt6_alloc_clone(rt, daddr); |
@@ -2326,6 +2335,7 @@ static int rt6_fill_node(struct net *net, | |||
2326 | struct nlmsghdr *nlh; | 2335 | struct nlmsghdr *nlh; |
2327 | long expires; | 2336 | long expires; |
2328 | u32 table; | 2337 | u32 table; |
2338 | struct neighbour *n; | ||
2329 | 2339 | ||
2330 | if (prefix) { /* user wants prefix routes only */ | 2340 | if (prefix) { /* user wants prefix routes only */ |
2331 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { | 2341 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { |
@@ -2414,8 +2424,11 @@ static int rt6_fill_node(struct net *net, | |||
2414 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) | 2424 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) |
2415 | goto nla_put_failure; | 2425 | goto nla_put_failure; |
2416 | 2426 | ||
2417 | if (dst_get_neighbour(&rt->dst)) | 2427 | rcu_read_lock(); |
2418 | NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key); | 2428 | n = dst_get_neighbour(&rt->dst); |
2429 | if (n) | ||
2430 | NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key); | ||
2431 | rcu_read_unlock(); | ||
2419 | 2432 | ||
2420 | if (rt->dst.dev) | 2433 | if (rt->dst.dev) |
2421 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); | 2434 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); |
@@ -2608,12 +2621,14 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) | |||
2608 | #else | 2621 | #else |
2609 | seq_puts(m, "00000000000000000000000000000000 00 "); | 2622 | seq_puts(m, "00000000000000000000000000000000 00 "); |
2610 | #endif | 2623 | #endif |
2624 | rcu_read_lock(); | ||
2611 | n = dst_get_neighbour(&rt->dst); | 2625 | n = dst_get_neighbour(&rt->dst); |
2612 | if (n) { | 2626 | if (n) { |
2613 | seq_printf(m, "%pi6", n->primary_key); | 2627 | seq_printf(m, "%pi6", n->primary_key); |
2614 | } else { | 2628 | } else { |
2615 | seq_puts(m, "00000000000000000000000000000000"); | 2629 | seq_puts(m, "00000000000000000000000000000000"); |
2616 | } | 2630 | } |
2631 | rcu_read_unlock(); | ||
2617 | seq_printf(m, " %08x %08x %08x %08x %8s\n", | 2632 | seq_printf(m, " %08x %08x %08x %08x %8s\n", |
2618 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), | 2633 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), |
2619 | rt->dst.__use, rt->rt6i_flags, | 2634 | rt->dst.__use, rt->rt6i_flags, |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 07bf1085458..00b15ac7a70 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -672,6 +672,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
672 | if (skb->protocol != htons(ETH_P_IPV6)) | 672 | if (skb->protocol != htons(ETH_P_IPV6)) |
673 | goto tx_error; | 673 | goto tx_error; |
674 | 674 | ||
675 | if (tos == 1) | ||
676 | tos = ipv6_get_dsfield(iph6); | ||
677 | |||
675 | /* ISATAP (RFC4214) - must come before 6to4 */ | 678 | /* ISATAP (RFC4214) - must come before 6to4 */ |
676 | if (dev->priv_flags & IFF_ISATAP) { | 679 | if (dev->priv_flags & IFF_ISATAP) { |
677 | struct neighbour *neigh = NULL; | 680 | struct neighbour *neigh = NULL; |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 89d5bf80622..ac838965ff3 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -165,7 +165,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
165 | int mss; | 165 | int mss; |
166 | struct dst_entry *dst; | 166 | struct dst_entry *dst; |
167 | __u8 rcv_wscale; | 167 | __u8 rcv_wscale; |
168 | bool ecn_ok; | 168 | bool ecn_ok = false; |
169 | 169 | ||
170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
171 | goto out; | 171 | goto out; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 78aa53492b3..d1fb63f4aeb 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <net/timewait_sock.h> | 61 | #include <net/timewait_sock.h> |
62 | #include <net/netdma.h> | 62 | #include <net/netdma.h> |
63 | #include <net/inet_common.h> | 63 | #include <net/inet_common.h> |
64 | #include <net/secure_seq.h> | ||
64 | 65 | ||
65 | #include <asm/uaccess.h> | 66 | #include <asm/uaccess.h> |
66 | 67 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 866f269183c..acb44230b25 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1012,7 +1012,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1012 | cancel_work_sync(&local->reconfig_filter); | 1012 | cancel_work_sync(&local->reconfig_filter); |
1013 | 1013 | ||
1014 | ieee80211_clear_tx_pending(local); | 1014 | ieee80211_clear_tx_pending(local); |
1015 | sta_info_stop(local); | ||
1016 | rate_control_deinitialize(local); | 1015 | rate_control_deinitialize(local); |
1017 | 1016 | ||
1018 | if (skb_queue_len(&local->skb_queue) || | 1017 | if (skb_queue_len(&local->skb_queue) || |
@@ -1024,6 +1023,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1024 | 1023 | ||
1025 | destroy_workqueue(local->workqueue); | 1024 | destroy_workqueue(local->workqueue); |
1026 | wiphy_unregister(local->hw.wiphy); | 1025 | wiphy_unregister(local->hw.wiphy); |
1026 | sta_info_stop(local); | ||
1027 | ieee80211_wep_free(local); | 1027 | ieee80211_wep_free(local); |
1028 | ieee80211_led_exit(local); | 1028 | ieee80211_led_exit(local); |
1029 | kfree(local->int_scan_req); | 1029 | kfree(local->int_scan_req); |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index be43fd805bd..2b771dc708a 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -3771,6 +3771,7 @@ err_sock: | |||
3771 | void ip_vs_control_cleanup(void) | 3771 | void ip_vs_control_cleanup(void) |
3772 | { | 3772 | { |
3773 | EnterFunction(2); | 3773 | EnterFunction(2); |
3774 | unregister_netdevice_notifier(&ip_vs_dst_notifier); | ||
3774 | ip_vs_genl_unregister(); | 3775 | ip_vs_genl_unregister(); |
3775 | nf_unregister_sockopt(&ip_vs_sockopts); | 3776 | nf_unregister_sockopt(&ip_vs_sockopts); |
3776 | LeaveFunction(2); | 3777 | LeaveFunction(2); |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5b466cd1272..84d0fd47636 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -312,6 +312,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
312 | } | 312 | } |
313 | break; | 313 | break; |
314 | case NF_STOLEN: | 314 | case NF_STOLEN: |
315 | break; | ||
315 | default: | 316 | default: |
316 | kfree_skb(skb); | 317 | kfree_skb(skb); |
317 | } | 318 | } |
diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile index ea750e9df65..d2732fc952e 100644 --- a/net/netlabel/Makefile +++ b/net/netlabel/Makefile | |||
@@ -1,8 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the NetLabel subsystem. | 2 | # Makefile for the NetLabel subsystem. |
3 | # | 3 | # |
4 | # Feb 9, 2006, Paul Moore <paul.moore@hp.com> | ||
5 | # | ||
6 | 4 | ||
7 | # base objects | 5 | # base objects |
8 | obj-y := netlabel_user.o netlabel_kapi.o | 6 | obj-y := netlabel_user.o netlabel_kapi.o |
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c index c0519139679..96b749dacc3 100644 --- a/net/netlabel/netlabel_addrlist.c +++ b/net/netlabel/netlabel_addrlist.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h index 2b9644e19de..fdbc1d2c735 100644 --- a/net/netlabel/netlabel_addrlist.h +++ b/net/netlabel/netlabel_addrlist.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index dd53a36d89a..6bf878335d9 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h index af7f3355103..d24d774bfd6 100644 --- a/net/netlabel/netlabel_cipso_v4.h +++ b/net/netlabel/netlabel_cipso_v4.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 2aa975e5452..7d8083cde34 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h index 0261dda3f2d..bfcc0f7024c 100644 --- a/net/netlabel/netlabel_domainhash.h +++ b/net/netlabel/netlabel_domainhash.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index b528dd928d3..9c24de10a65 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * system manages static and dynamic label mappings for network protocols such | 5 | * system manages static and dynamic label mappings for network protocols such |
6 | * as CIPSO and RIPSO. | 6 | * as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -341,11 +341,11 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
341 | 341 | ||
342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | 342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); |
343 | if (entry == NULL) | 343 | if (entry == NULL) |
344 | return -ENOMEM; | 344 | goto out_entry; |
345 | if (domain != NULL) { | 345 | if (domain != NULL) { |
346 | entry->domain = kstrdup(domain, GFP_ATOMIC); | 346 | entry->domain = kstrdup(domain, GFP_ATOMIC); |
347 | if (entry->domain == NULL) | 347 | if (entry->domain == NULL) |
348 | goto cfg_cipsov4_map_add_failure; | 348 | goto out_domain; |
349 | } | 349 | } |
350 | 350 | ||
351 | if (addr == NULL && mask == NULL) { | 351 | if (addr == NULL && mask == NULL) { |
@@ -354,13 +354,13 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
354 | } else if (addr != NULL && mask != NULL) { | 354 | } else if (addr != NULL && mask != NULL) { |
355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); | 355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); |
356 | if (addrmap == NULL) | 356 | if (addrmap == NULL) |
357 | goto cfg_cipsov4_map_add_failure; | 357 | goto out_addrmap; |
358 | INIT_LIST_HEAD(&addrmap->list4); | 358 | INIT_LIST_HEAD(&addrmap->list4); |
359 | INIT_LIST_HEAD(&addrmap->list6); | 359 | INIT_LIST_HEAD(&addrmap->list6); |
360 | 360 | ||
361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); | 361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); |
362 | if (addrinfo == NULL) | 362 | if (addrinfo == NULL) |
363 | goto cfg_cipsov4_map_add_failure; | 363 | goto out_addrinfo; |
364 | addrinfo->type_def.cipsov4 = doi_def; | 364 | addrinfo->type_def.cipsov4 = doi_def; |
365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; | 365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; |
366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; | 366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; |
@@ -374,7 +374,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; | 374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; |
375 | } else { | 375 | } else { |
376 | ret_val = -EINVAL; | 376 | ret_val = -EINVAL; |
377 | goto cfg_cipsov4_map_add_failure; | 377 | goto out_addrmap; |
378 | } | 378 | } |
379 | 379 | ||
380 | ret_val = netlbl_domhsh_add(entry, audit_info); | 380 | ret_val = netlbl_domhsh_add(entry, audit_info); |
@@ -384,11 +384,15 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
384 | return 0; | 384 | return 0; |
385 | 385 | ||
386 | cfg_cipsov4_map_add_failure: | 386 | cfg_cipsov4_map_add_failure: |
387 | cipso_v4_doi_putdef(doi_def); | 387 | kfree(addrinfo); |
388 | out_addrinfo: | ||
389 | kfree(addrmap); | ||
390 | out_addrmap: | ||
388 | kfree(entry->domain); | 391 | kfree(entry->domain); |
392 | out_domain: | ||
389 | kfree(entry); | 393 | kfree(entry); |
390 | kfree(addrmap); | 394 | out_entry: |
391 | kfree(addrinfo); | 395 | cipso_v4_doi_putdef(doi_def); |
392 | return ret_val; | 396 | return ret_val; |
393 | } | 397 | } |
394 | 398 | ||
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index dff8a080924..bfa55586977 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h index 8db37f4c10f..5a9f31ce579 100644 --- a/net/netlabel/netlabel_mgmt.h +++ b/net/netlabel/netlabel_mgmt.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index f1ecf848e3a..e6e823656f9 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system. The NetLabel system manages static and dynamic label | 5 | * NetLabel system. The NetLabel system manages static and dynamic label |
6 | * mappings for network protocols such as CIPSO and RIPSO. | 6 | * mappings for network protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 0bc8dc3f9e3..700af49022a 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system. The NetLabel system manages static and dynamic label | 5 | * NetLabel system. The NetLabel system manages static and dynamic label |
6 | * mappings for network protocols such as CIPSO and RIPSO. | 6 | * mappings for network protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index a3fd75ac3fa..9fae63f1029 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index f4fc4c9ad56..81969785e27 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 102fc212cd6..e051398fdf6 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -196,8 +196,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | |||
196 | 196 | ||
197 | skb2->skb_iif = skb->dev->ifindex; | 197 | skb2->skb_iif = skb->dev->ifindex; |
198 | skb2->dev = dev; | 198 | skb2->dev = dev; |
199 | dev_queue_xmit(skb2); | 199 | err = dev_queue_xmit(skb2); |
200 | err = 0; | ||
201 | 200 | ||
202 | out: | 201 | out: |
203 | if (err) { | 202 | if (err) { |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2a318f2dc3e..b5d56a22b1d 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -112,7 +112,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc *sch) | |||
112 | 112 | ||
113 | for (prio = 0; prio < q->bands; prio++) { | 113 | for (prio = 0; prio < q->bands; prio++) { |
114 | struct Qdisc *qdisc = q->queues[prio]; | 114 | struct Qdisc *qdisc = q->queues[prio]; |
115 | struct sk_buff *skb = qdisc->dequeue(qdisc); | 115 | struct sk_buff *skb = qdisc_dequeue_peeked(qdisc); |
116 | if (skb) { | 116 | if (skb) { |
117 | qdisc_bstats_update(sch, skb); | 117 | qdisc_bstats_update(sch, skb); |
118 | sch->q.qlen--; | 118 | sch->q.qlen--; |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 4536ee64383..4f5510e2bd6 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
410 | /* Return Congestion Notification only if we dropped a packet | 410 | /* Return Congestion Notification only if we dropped a packet |
411 | * from this flow. | 411 | * from this flow. |
412 | */ | 412 | */ |
413 | return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; | 413 | if (qlen != slot->qlen) |
414 | return NET_XMIT_CN; | ||
415 | |||
416 | /* As we dropped a packet, better let upper stack know this */ | ||
417 | qdisc_tree_decrease_qlen(sch, 1); | ||
418 | return NET_XMIT_SUCCESS; | ||
414 | } | 419 | } |
415 | 420 | ||
416 | static struct sk_buff * | 421 | static struct sk_buff * |
diff --git a/net/socket.c b/net/socket.c index b1cbbcd9255..ffe92ca32f2 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) | |||
1871 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) | 1871 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) |
1872 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) | 1872 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) |
1873 | 1873 | ||
1874 | struct used_address { | ||
1875 | struct sockaddr_storage name; | ||
1876 | unsigned int name_len; | ||
1877 | }; | ||
1878 | |||
1874 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | 1879 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
1875 | struct msghdr *msg_sys, unsigned flags, int nosec) | 1880 | struct msghdr *msg_sys, unsigned flags, |
1881 | struct used_address *used_address) | ||
1876 | { | 1882 | { |
1877 | struct compat_msghdr __user *msg_compat = | 1883 | struct compat_msghdr __user *msg_compat = |
1878 | (struct compat_msghdr __user *)msg; | 1884 | (struct compat_msghdr __user *)msg; |
@@ -1953,8 +1959,30 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
1953 | 1959 | ||
1954 | if (sock->file->f_flags & O_NONBLOCK) | 1960 | if (sock->file->f_flags & O_NONBLOCK) |
1955 | msg_sys->msg_flags |= MSG_DONTWAIT; | 1961 | msg_sys->msg_flags |= MSG_DONTWAIT; |
1956 | err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, | 1962 | /* |
1957 | total_len); | 1963 | * If this is sendmmsg() and current destination address is same as |
1964 | * previously succeeded address, omit asking LSM's decision. | ||
1965 | * used_address->name_len is initialized to UINT_MAX so that the first | ||
1966 | * destination address never matches. | ||
1967 | */ | ||
1968 | if (used_address && msg_sys->msg_name && | ||
1969 | used_address->name_len == msg_sys->msg_namelen && | ||
1970 | !memcmp(&used_address->name, msg_sys->msg_name, | ||
1971 | used_address->name_len)) { | ||
1972 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); | ||
1973 | goto out_freectl; | ||
1974 | } | ||
1975 | err = sock_sendmsg(sock, msg_sys, total_len); | ||
1976 | /* | ||
1977 | * If this is sendmmsg() and sending to current destination address was | ||
1978 | * successful, remember it. | ||
1979 | */ | ||
1980 | if (used_address && err >= 0) { | ||
1981 | used_address->name_len = msg_sys->msg_namelen; | ||
1982 | if (msg_sys->msg_name) | ||
1983 | memcpy(&used_address->name, msg_sys->msg_name, | ||
1984 | used_address->name_len); | ||
1985 | } | ||
1958 | 1986 | ||
1959 | out_freectl: | 1987 | out_freectl: |
1960 | if (ctl_buf != ctl) | 1988 | if (ctl_buf != ctl) |
@@ -1979,7 +2007,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) | |||
1979 | if (!sock) | 2007 | if (!sock) |
1980 | goto out; | 2008 | goto out; |
1981 | 2009 | ||
1982 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); | 2010 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
1983 | 2011 | ||
1984 | fput_light(sock->file, fput_needed); | 2012 | fput_light(sock->file, fput_needed); |
1985 | out: | 2013 | out: |
@@ -1998,6 +2026,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
1998 | struct mmsghdr __user *entry; | 2026 | struct mmsghdr __user *entry; |
1999 | struct compat_mmsghdr __user *compat_entry; | 2027 | struct compat_mmsghdr __user *compat_entry; |
2000 | struct msghdr msg_sys; | 2028 | struct msghdr msg_sys; |
2029 | struct used_address used_address; | ||
2030 | |||
2031 | if (vlen > UIO_MAXIOV) | ||
2032 | vlen = UIO_MAXIOV; | ||
2001 | 2033 | ||
2002 | datagrams = 0; | 2034 | datagrams = 0; |
2003 | 2035 | ||
@@ -2005,27 +2037,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2005 | if (!sock) | 2037 | if (!sock) |
2006 | return err; | 2038 | return err; |
2007 | 2039 | ||
2008 | err = sock_error(sock->sk); | 2040 | used_address.name_len = UINT_MAX; |
2009 | if (err) | ||
2010 | goto out_put; | ||
2011 | |||
2012 | entry = mmsg; | 2041 | entry = mmsg; |
2013 | compat_entry = (struct compat_mmsghdr __user *)mmsg; | 2042 | compat_entry = (struct compat_mmsghdr __user *)mmsg; |
2043 | err = 0; | ||
2014 | 2044 | ||
2015 | while (datagrams < vlen) { | 2045 | while (datagrams < vlen) { |
2016 | /* | ||
2017 | * No need to ask LSM for more than the first datagram. | ||
2018 | */ | ||
2019 | if (MSG_CMSG_COMPAT & flags) { | 2046 | if (MSG_CMSG_COMPAT & flags) { |
2020 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, | 2047 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
2021 | &msg_sys, flags, datagrams); | 2048 | &msg_sys, flags, &used_address); |
2022 | if (err < 0) | 2049 | if (err < 0) |
2023 | break; | 2050 | break; |
2024 | err = __put_user(err, &compat_entry->msg_len); | 2051 | err = __put_user(err, &compat_entry->msg_len); |
2025 | ++compat_entry; | 2052 | ++compat_entry; |
2026 | } else { | 2053 | } else { |
2027 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, | 2054 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
2028 | &msg_sys, flags, datagrams); | 2055 | &msg_sys, flags, &used_address); |
2029 | if (err < 0) | 2056 | if (err < 0) |
2030 | break; | 2057 | break; |
2031 | err = put_user(err, &entry->msg_len); | 2058 | err = put_user(err, &entry->msg_len); |
@@ -2037,29 +2064,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2037 | ++datagrams; | 2064 | ++datagrams; |
2038 | } | 2065 | } |
2039 | 2066 | ||
2040 | out_put: | ||
2041 | fput_light(sock->file, fput_needed); | 2067 | fput_light(sock->file, fput_needed); |
2042 | 2068 | ||
2043 | if (err == 0) | 2069 | /* We only return an error if no datagrams were able to be sent */ |
2044 | return datagrams; | 2070 | if (datagrams != 0) |
2045 | |||
2046 | if (datagrams != 0) { | ||
2047 | /* | ||
2048 | * We may send less entries than requested (vlen) if the | ||
2049 | * sock is non blocking... | ||
2050 | */ | ||
2051 | if (err != -EAGAIN) { | ||
2052 | /* | ||
2053 | * ... or if sendmsg returns an error after we | ||
2054 | * send some datagrams, where we record the | ||
2055 | * error to return on the next call or if the | ||
2056 | * app asks about it using getsockopt(SO_ERROR). | ||
2057 | */ | ||
2058 | sock->sk->sk_err = -err; | ||
2059 | } | ||
2060 | |||
2061 | return datagrams; | 2071 | return datagrams; |
2062 | } | ||
2063 | 2072 | ||
2064 | return err; | 2073 | return err; |
2065 | } | 2074 | } |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 9b6a4d1ea8f..f4385e45a5f 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -187,6 +187,7 @@ EXPORT_SYMBOL_GPL(xprt_load_transport); | |||
187 | /** | 187 | /** |
188 | * xprt_reserve_xprt - serialize write access to transports | 188 | * xprt_reserve_xprt - serialize write access to transports |
189 | * @task: task that is requesting access to the transport | 189 | * @task: task that is requesting access to the transport |
190 | * @xprt: pointer to the target transport | ||
190 | * | 191 | * |
191 | * This prevents mixing the payload of separate requests, and prevents | 192 | * This prevents mixing the payload of separate requests, and prevents |
192 | * transport connects from colliding with writes. No congestion control | 193 | * transport connects from colliding with writes. No congestion control |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 645437cfc46..c14865172da 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -616,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy) | |||
616 | if (res) | 616 | if (res) |
617 | goto out_rm_dev; | 617 | goto out_rm_dev; |
618 | 618 | ||
619 | rtnl_lock(); | ||
620 | rdev->wiphy.registered = true; | ||
621 | rtnl_unlock(); | ||
619 | return 0; | 622 | return 0; |
620 | 623 | ||
621 | out_rm_dev: | 624 | out_rm_dev: |
@@ -647,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
647 | { | 650 | { |
648 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 651 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
649 | 652 | ||
653 | rtnl_lock(); | ||
654 | rdev->wiphy.registered = false; | ||
655 | rtnl_unlock(); | ||
656 | |||
650 | rfkill_unregister(rdev->rfkill); | 657 | rfkill_unregister(rdev->rfkill); |
651 | 658 | ||
652 | /* protect the device list */ | 659 | /* protect the device list */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 28d2aa109be..e83e7fee3bc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3464,7 +3464,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3464 | tmp) { | 3464 | tmp) { |
3465 | enum ieee80211_band band = nla_type(attr); | 3465 | enum ieee80211_band band = nla_type(attr); |
3466 | 3466 | ||
3467 | if (band < 0 || band > IEEE80211_NUM_BANDS) { | 3467 | if (band < 0 || band >= IEEE80211_NUM_BANDS) { |
3468 | err = -EINVAL; | 3468 | err = -EINVAL; |
3469 | goto out_free; | 3469 | goto out_free; |
3470 | } | 3470 | } |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index c6e4ca6a7d2..ff574597a85 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) | |||
93 | 93 | ||
94 | if (rdev->ops->suspend) { | 94 | if (rdev->ops->suspend) { |
95 | rtnl_lock(); | 95 | rtnl_lock(); |
96 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | 96 | if (rdev->wiphy.registered) |
97 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | ||
97 | rtnl_unlock(); | 98 | rtnl_unlock(); |
98 | } | 99 | } |
99 | 100 | ||
@@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev) | |||
112 | 113 | ||
113 | if (rdev->ops->resume) { | 114 | if (rdev->ops->resume) { |
114 | rtnl_lock(); | 115 | rtnl_lock(); |
115 | ret = rdev->ops->resume(&rdev->wiphy); | 116 | if (rdev->wiphy.registered) |
117 | ret = rdev->ops->resume(&rdev->wiphy); | ||
116 | rtnl_unlock(); | 118 | rtnl_unlock(); |
117 | } | 119 | } |
118 | 120 | ||
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 58064d9e565..791ab2e77f3 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { | |||
462 | .desc = { | 462 | .desc = { |
463 | .sadb_alg_id = SADB_X_EALG_AESCTR, | 463 | .sadb_alg_id = SADB_X_EALG_AESCTR, |
464 | .sadb_alg_ivlen = 8, | 464 | .sadb_alg_ivlen = 8, |
465 | .sadb_alg_minbits = 128, | 465 | .sadb_alg_minbits = 160, |
466 | .sadb_alg_maxbits = 256 | 466 | .sadb_alg_maxbits = 288 |
467 | } | 467 | } |
468 | }, | 468 | }, |
469 | }; | 469 | }; |