mirror of https://gitee.com/openkylin/linux.git
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix VSOCK layer handling of context ID changes, from Reilly Grant. 2) Now that we have a synchronize_net() in netdev_rx_handler_unregister(), we can't let any call sites hold locks. Unfortunately bonding does, so we have to drop the rwlock there a little bit earlier, fix from Veaceslav Falico. 3) MAC address setting loop exits one iteration too early in mlx4 driver, from Yan Burman. 4) Restore ipv6 routes properly upon ifdown/ifup of loopback, from Balakumaran Kannan. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: VSOCK: Handle changes to the VMCI context ID. net IPv6 : Fix broken IPv6 routing table after loopback down-up cbq: incorrect processing of high limits net/mlx4_en: Fix setting initial MAC address bonding: get netdev_rx_handler_unregister out of locks
This commit is contained in:
commit
da241efcd9
|
@ -1976,12 +1976,11 @@ static int __bond_release_one(struct net_device *bond_dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
write_unlock_bh(&bond->lock);
|
||||
/* unregister rx_handler early so bond_handle_frame wouldn't be called
|
||||
* for this slave anymore.
|
||||
*/
|
||||
netdev_rx_handler_unregister(slave_dev);
|
||||
write_unlock_bh(&bond->lock);
|
||||
synchronize_net();
|
||||
write_lock_bh(&bond->lock);
|
||||
|
||||
if (!all && !bond->params.fail_over_mac) {
|
||||
|
|
|
@ -411,8 +411,8 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
|
|||
|
||||
static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = ETH_ALEN - 1; i; --i) {
|
||||
int i;
|
||||
for (i = ETH_ALEN - 1; i >= 0; --i) {
|
||||
dst_mac[i] = src_mac & 0xff;
|
||||
src_mac >>= 8;
|
||||
}
|
||||
|
|
|
@ -2529,6 +2529,9 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
|
|||
static void init_loopback(struct net_device *dev)
|
||||
{
|
||||
struct inet6_dev *idev;
|
||||
struct net_device *sp_dev;
|
||||
struct inet6_ifaddr *sp_ifa;
|
||||
struct rt6_info *sp_rt;
|
||||
|
||||
/* ::1 */
|
||||
|
||||
|
@ -2540,6 +2543,30 @@ static void init_loopback(struct net_device *dev)
|
|||
}
|
||||
|
||||
add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
|
||||
|
||||
/* Add routes to other interface's IPv6 addresses */
|
||||
for_each_netdev(dev_net(dev), sp_dev) {
|
||||
if (!strcmp(sp_dev->name, dev->name))
|
||||
continue;
|
||||
|
||||
idev = __in6_dev_get(sp_dev);
|
||||
if (!idev)
|
||||
continue;
|
||||
|
||||
read_lock_bh(&idev->lock);
|
||||
list_for_each_entry(sp_ifa, &idev->addr_list, if_list) {
|
||||
|
||||
if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))
|
||||
continue;
|
||||
|
||||
sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
|
||||
|
||||
/* Failure cases are ignored */
|
||||
if (!IS_ERR(sp_rt))
|
||||
ip6_ins_rt(sp_rt);
|
||||
}
|
||||
read_unlock_bh(&idev->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
|
||||
|
|
|
@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch)
|
|||
cbq_update(q);
|
||||
if ((incr -= incr2) < 0)
|
||||
incr = 0;
|
||||
q->now += incr;
|
||||
} else {
|
||||
if (now > q->now)
|
||||
q->now = now;
|
||||
}
|
||||
q->now += incr;
|
||||
q->now_rt = now;
|
||||
|
||||
for (;;) {
|
||||
|
|
|
@ -207,7 +207,7 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr)
|
|||
struct vsock_sock *vsk;
|
||||
|
||||
list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table)
|
||||
if (vsock_addr_equals_addr_any(addr, &vsk->local_addr))
|
||||
if (addr->svm_port == vsk->local_addr.svm_port)
|
||||
return sk_vsock(vsk);
|
||||
|
||||
return NULL;
|
||||
|
@ -220,8 +220,8 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src,
|
|||
|
||||
list_for_each_entry(vsk, vsock_connected_sockets(src, dst),
|
||||
connected_table) {
|
||||
if (vsock_addr_equals_addr(src, &vsk->remote_addr)
|
||||
&& vsock_addr_equals_addr(dst, &vsk->local_addr)) {
|
||||
if (vsock_addr_equals_addr(src, &vsk->remote_addr) &&
|
||||
dst->svm_port == vsk->local_addr.svm_port) {
|
||||
return sk_vsock(vsk);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -464,19 +464,16 @@ static struct sock *vmci_transport_get_pending(
|
|||
struct vsock_sock *vlistener;
|
||||
struct vsock_sock *vpending;
|
||||
struct sock *pending;
|
||||
struct sockaddr_vm src;
|
||||
|
||||
vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
|
||||
|
||||
vlistener = vsock_sk(listener);
|
||||
|
||||
list_for_each_entry(vpending, &vlistener->pending_links,
|
||||
pending_links) {
|
||||
struct sockaddr_vm src;
|
||||
struct sockaddr_vm dst;
|
||||
|
||||
vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port);
|
||||
vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port);
|
||||
|
||||
if (vsock_addr_equals_addr(&src, &vpending->remote_addr) &&
|
||||
vsock_addr_equals_addr(&dst, &vpending->local_addr)) {
|
||||
pkt->dst_port == vpending->local_addr.svm_port) {
|
||||
pending = sk_vsock(vpending);
|
||||
sock_hold(pending);
|
||||
goto found;
|
||||
|
@ -739,10 +736,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
|
|||
*/
|
||||
bh_lock_sock(sk);
|
||||
|
||||
if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED)
|
||||
vmci_trans(vsk)->notify_ops->handle_notify_pkt(
|
||||
sk, pkt, true, &dst, &src,
|
||||
&bh_process_pkt);
|
||||
if (!sock_owned_by_user(sk)) {
|
||||
/* The local context ID may be out of date, update it. */
|
||||
vsk->local_addr.svm_cid = dst.svm_cid;
|
||||
|
||||
if (sk->sk_state == SS_CONNECTED)
|
||||
vmci_trans(vsk)->notify_ops->handle_notify_pkt(
|
||||
sk, pkt, true, &dst, &src,
|
||||
&bh_process_pkt);
|
||||
}
|
||||
|
||||
bh_unlock_sock(sk);
|
||||
|
||||
|
@ -902,6 +904,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work)
|
|||
|
||||
lock_sock(sk);
|
||||
|
||||
/* The local context ID may be out of date. */
|
||||
vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context;
|
||||
|
||||
switch (sk->sk_state) {
|
||||
case SS_LISTEN:
|
||||
vmci_transport_recv_listen(sk, pkt);
|
||||
|
@ -958,6 +963,10 @@ static int vmci_transport_recv_listen(struct sock *sk,
|
|||
pending = vmci_transport_get_pending(sk, pkt);
|
||||
if (pending) {
|
||||
lock_sock(pending);
|
||||
|
||||
/* The local context ID may be out of date. */
|
||||
vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context;
|
||||
|
||||
switch (pending->sk_state) {
|
||||
case SS_CONNECTING:
|
||||
err = vmci_transport_recv_connecting_server(sk,
|
||||
|
|
|
@ -64,16 +64,6 @@ bool vsock_addr_equals_addr(const struct sockaddr_vm *addr,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(vsock_addr_equals_addr);
|
||||
|
||||
bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr,
|
||||
const struct sockaddr_vm *other)
|
||||
{
|
||||
return (addr->svm_cid == VMADDR_CID_ANY ||
|
||||
other->svm_cid == VMADDR_CID_ANY ||
|
||||
addr->svm_cid == other->svm_cid) &&
|
||||
addr->svm_port == other->svm_port;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vsock_addr_equals_addr_any);
|
||||
|
||||
int vsock_addr_cast(const struct sockaddr *addr,
|
||||
size_t len, struct sockaddr_vm **out_addr)
|
||||
{
|
||||
|
|
|
@ -24,8 +24,6 @@ bool vsock_addr_bound(const struct sockaddr_vm *addr);
|
|||
void vsock_addr_unbind(struct sockaddr_vm *addr);
|
||||
bool vsock_addr_equals_addr(const struct sockaddr_vm *addr,
|
||||
const struct sockaddr_vm *other);
|
||||
bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr,
|
||||
const struct sockaddr_vm *other);
|
||||
int vsock_addr_cast(const struct sockaddr *addr, size_t len,
|
||||
struct sockaddr_vm **out_addr);
|
||||
|
||||
|
|
Loading…
Reference in New Issue