diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 27 | ||||
-rw-r--r-- | net/sched/sch_cbq.c | 5 | ||||
-rw-r--r-- | net/vmw_vsock/af_vsock.c | 6 | ||||
-rw-r--r-- | net/vmw_vsock/vmci_transport.c | 31 | ||||
-rw-r--r-- | net/vmw_vsock/vsock_addr.c | 10 | ||||
-rw-r--r-- | net/vmw_vsock/vsock_addr.h | 2 |
8 files changed, 57 insertions, 31 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6bbd90e1123c..a51241b2e621 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1976,12 +1976,11 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1976 | return -EINVAL; | 1976 | return -EINVAL; |
1977 | } | 1977 | } |
1978 | 1978 | ||
1979 | write_unlock_bh(&bond->lock); | ||
1979 | /* unregister rx_handler early so bond_handle_frame wouldn't be called | 1980 | /* unregister rx_handler early so bond_handle_frame wouldn't be called |
1980 | * for this slave anymore. | 1981 | * for this slave anymore. |
1981 | */ | 1982 | */ |
1982 | netdev_rx_handler_unregister(slave_dev); | 1983 | netdev_rx_handler_unregister(slave_dev); |
1983 | write_unlock_bh(&bond->lock); | ||
1984 | synchronize_net(); | ||
1985 | write_lock_bh(&bond->lock); | 1984 | write_lock_bh(&bond->lock); |
1986 | 1985 | ||
1987 | if (!all && !bond->params.fail_over_mac) { | 1986 | if (!all && !bond->params.fail_over_mac) { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index f278b10ef714..30d78f806dc3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -411,8 +411,8 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
411 | 411 | ||
412 | static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac) | 412 | static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac) |
413 | { | 413 | { |
414 | unsigned int i; | 414 | int i; |
415 | for (i = ETH_ALEN - 1; i; --i) { | 415 | for (i = ETH_ALEN - 1; i >= 0; --i) { |
416 | dst_mac[i] = src_mac & 0xff; | 416 | dst_mac[i] = src_mac & 0xff; |
417 | src_mac >>= 8; | 417 | src_mac >>= 8; |
418 | } | 418 | } |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 26512250e095..a459c4f5b769 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2529,6 +2529,9 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2529 | static void init_loopback(struct net_device *dev) | 2529 | static void init_loopback(struct net_device *dev) |
2530 | { | 2530 | { |
2531 | struct inet6_dev *idev; | 2531 | struct inet6_dev *idev; |
2532 | struct net_device *sp_dev; | ||
2533 | struct inet6_ifaddr *sp_ifa; | ||
2534 | struct rt6_info *sp_rt; | ||
2532 | 2535 | ||
2533 | /* ::1 */ | 2536 | /* ::1 */ |
2534 | 2537 | ||
@@ -2540,6 +2543,30 @@ static void init_loopback(struct net_device *dev) | |||
2540 | } | 2543 | } |
2541 | 2544 | ||
2542 | add_addr(idev, &in6addr_loopback, 128, IFA_HOST); | 2545 | add_addr(idev, &in6addr_loopback, 128, IFA_HOST); |
2546 | |||
2547 | /* Add routes to other interface's IPv6 addresses */ | ||
2548 | for_each_netdev(dev_net(dev), sp_dev) { | ||
2549 | if (!strcmp(sp_dev->name, dev->name)) | ||
2550 | continue; | ||
2551 | |||
2552 | idev = __in6_dev_get(sp_dev); | ||
2553 | if (!idev) | ||
2554 | continue; | ||
2555 | |||
2556 | read_lock_bh(&idev->lock); | ||
2557 | list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { | ||
2558 | |||
2559 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) | ||
2560 | continue; | ||
2561 | |||
2562 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | ||
2563 | |||
2564 | /* Failure cases are ignored */ | ||
2565 | if (!IS_ERR(sp_rt)) | ||
2566 | ip6_ins_rt(sp_rt); | ||
2567 | } | ||
2568 | read_unlock_bh(&idev->lock); | ||
2569 | } | ||
2543 | } | 2570 | } |
2544 | 2571 | ||
2545 | static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) | 2572 | static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 13aa47aa2ffb..1bc210ffcba2 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch) | |||
962 | cbq_update(q); | 962 | cbq_update(q); |
963 | if ((incr -= incr2) < 0) | 963 | if ((incr -= incr2) < 0) |
964 | incr = 0; | 964 | incr = 0; |
965 | q->now += incr; | ||
966 | } else { | ||
967 | if (now > q->now) | ||
968 | q->now = now; | ||
965 | } | 969 | } |
966 | q->now += incr; | ||
967 | q->now_rt = now; | 970 | q->now_rt = now; |
968 | 971 | ||
969 | for (;;) { | 972 | for (;;) { |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca511c4f388a..d8079daf1bde 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -207,7 +207,7 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) | |||
207 | struct vsock_sock *vsk; | 207 | struct vsock_sock *vsk; |
208 | 208 | ||
209 | list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) | 209 | list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) |
210 | if (vsock_addr_equals_addr_any(addr, &vsk->local_addr)) | 210 | if (addr->svm_port == vsk->local_addr.svm_port) |
211 | return sk_vsock(vsk); | 211 | return sk_vsock(vsk); |
212 | 212 | ||
213 | return NULL; | 213 | return NULL; |
@@ -220,8 +220,8 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, | |||
220 | 220 | ||
221 | list_for_each_entry(vsk, vsock_connected_sockets(src, dst), | 221 | list_for_each_entry(vsk, vsock_connected_sockets(src, dst), |
222 | connected_table) { | 222 | connected_table) { |
223 | if (vsock_addr_equals_addr(src, &vsk->remote_addr) | 223 | if (vsock_addr_equals_addr(src, &vsk->remote_addr) && |
224 | && vsock_addr_equals_addr(dst, &vsk->local_addr)) { | 224 | dst->svm_port == vsk->local_addr.svm_port) { |
225 | return sk_vsock(vsk); | 225 | return sk_vsock(vsk); |
226 | } | 226 | } |
227 | } | 227 | } |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index a70ace83a153..1f6508e249ae 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
@@ -464,19 +464,16 @@ static struct sock *vmci_transport_get_pending( | |||
464 | struct vsock_sock *vlistener; | 464 | struct vsock_sock *vlistener; |
465 | struct vsock_sock *vpending; | 465 | struct vsock_sock *vpending; |
466 | struct sock *pending; | 466 | struct sock *pending; |
467 | struct sockaddr_vm src; | ||
468 | |||
469 | vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); | ||
467 | 470 | ||
468 | vlistener = vsock_sk(listener); | 471 | vlistener = vsock_sk(listener); |
469 | 472 | ||
470 | list_for_each_entry(vpending, &vlistener->pending_links, | 473 | list_for_each_entry(vpending, &vlistener->pending_links, |
471 | pending_links) { | 474 | pending_links) { |
472 | struct sockaddr_vm src; | ||
473 | struct sockaddr_vm dst; | ||
474 | |||
475 | vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); | ||
476 | vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port); | ||
477 | |||
478 | if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && | 475 | if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && |
479 | vsock_addr_equals_addr(&dst, &vpending->local_addr)) { | 476 | pkt->dst_port == vpending->local_addr.svm_port) { |
480 | pending = sk_vsock(vpending); | 477 | pending = sk_vsock(vpending); |
481 | sock_hold(pending); | 478 | sock_hold(pending); |
482 | goto found; | 479 | goto found; |
@@ -739,10 +736,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) | |||
739 | */ | 736 | */ |
740 | bh_lock_sock(sk); | 737 | bh_lock_sock(sk); |
741 | 738 | ||
742 | if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) | 739 | if (!sock_owned_by_user(sk)) { |
743 | vmci_trans(vsk)->notify_ops->handle_notify_pkt( | 740 | /* The local context ID may be out of date, update it. */ |
744 | sk, pkt, true, &dst, &src, | 741 | vsk->local_addr.svm_cid = dst.svm_cid; |
745 | &bh_process_pkt); | 742 | |
743 | if (sk->sk_state == SS_CONNECTED) | ||
744 | vmci_trans(vsk)->notify_ops->handle_notify_pkt( | ||
745 | sk, pkt, true, &dst, &src, | ||
746 | &bh_process_pkt); | ||
747 | } | ||
746 | 748 | ||
747 | bh_unlock_sock(sk); | 749 | bh_unlock_sock(sk); |
748 | 750 | ||
@@ -902,6 +904,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work) | |||
902 | 904 | ||
903 | lock_sock(sk); | 905 | lock_sock(sk); |
904 | 906 | ||
907 | /* The local context ID may be out of date. */ | ||
908 | vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context; | ||
909 | |||
905 | switch (sk->sk_state) { | 910 | switch (sk->sk_state) { |
906 | case SS_LISTEN: | 911 | case SS_LISTEN: |
907 | vmci_transport_recv_listen(sk, pkt); | 912 | vmci_transport_recv_listen(sk, pkt); |
@@ -958,6 +963,10 @@ static int vmci_transport_recv_listen(struct sock *sk, | |||
958 | pending = vmci_transport_get_pending(sk, pkt); | 963 | pending = vmci_transport_get_pending(sk, pkt); |
959 | if (pending) { | 964 | if (pending) { |
960 | lock_sock(pending); | 965 | lock_sock(pending); |
966 | |||
967 | /* The local context ID may be out of date. */ | ||
968 | vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context; | ||
969 | |||
961 | switch (pending->sk_state) { | 970 | switch (pending->sk_state) { |
962 | case SS_CONNECTING: | 971 | case SS_CONNECTING: |
963 | err = vmci_transport_recv_connecting_server(sk, | 972 | err = vmci_transport_recv_connecting_server(sk, |
diff --git a/net/vmw_vsock/vsock_addr.c b/net/vmw_vsock/vsock_addr.c index b7df1aea7c59..ec2611b4ea0e 100644 --- a/net/vmw_vsock/vsock_addr.c +++ b/net/vmw_vsock/vsock_addr.c | |||
@@ -64,16 +64,6 @@ bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, | |||
64 | } | 64 | } |
65 | EXPORT_SYMBOL_GPL(vsock_addr_equals_addr); | 65 | EXPORT_SYMBOL_GPL(vsock_addr_equals_addr); |
66 | 66 | ||
67 | bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, | ||
68 | const struct sockaddr_vm *other) | ||
69 | { | ||
70 | return (addr->svm_cid == VMADDR_CID_ANY || | ||
71 | other->svm_cid == VMADDR_CID_ANY || | ||
72 | addr->svm_cid == other->svm_cid) && | ||
73 | addr->svm_port == other->svm_port; | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(vsock_addr_equals_addr_any); | ||
76 | |||
77 | int vsock_addr_cast(const struct sockaddr *addr, | 67 | int vsock_addr_cast(const struct sockaddr *addr, |
78 | size_t len, struct sockaddr_vm **out_addr) | 68 | size_t len, struct sockaddr_vm **out_addr) |
79 | { | 69 | { |
diff --git a/net/vmw_vsock/vsock_addr.h b/net/vmw_vsock/vsock_addr.h index cdfbcefdf843..9ccd5316eac0 100644 --- a/net/vmw_vsock/vsock_addr.h +++ b/net/vmw_vsock/vsock_addr.h | |||
@@ -24,8 +24,6 @@ bool vsock_addr_bound(const struct sockaddr_vm *addr); | |||
24 | void vsock_addr_unbind(struct sockaddr_vm *addr); | 24 | void vsock_addr_unbind(struct sockaddr_vm *addr); |
25 | bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, | 25 | bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, |
26 | const struct sockaddr_vm *other); | 26 | const struct sockaddr_vm *other); |
27 | bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, | ||
28 | const struct sockaddr_vm *other); | ||
29 | int vsock_addr_cast(const struct sockaddr *addr, size_t len, | 27 | int vsock_addr_cast(const struct sockaddr *addr, size_t len, |
30 | struct sockaddr_vm **out_addr); | 28 | struct sockaddr_vm **out_addr); |
31 | 29 | ||