diff options
Diffstat (limited to 'drivers/net/ipvlan/ipvlan_main.c')
-rw-r--r-- | drivers/net/ipvlan/ipvlan_main.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 1701ede2df89..77b92a0fe557 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c | |||
@@ -511,7 +511,7 @@ static void ipvlan_link_delete(struct net_device *dev, struct list_head *head) | |||
511 | if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { | 511 | if (ipvlan->ipv6cnt > 0 || ipvlan->ipv4cnt > 0) { |
512 | list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { | 512 | list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) { |
513 | ipvlan_ht_addr_del(addr, !dev->dismantle); | 513 | ipvlan_ht_addr_del(addr, !dev->dismantle); |
514 | list_del_rcu(&addr->anode); | 514 | list_del(&addr->anode); |
515 | } | 515 | } |
516 | } | 516 | } |
517 | list_del_rcu(&ipvlan->pnode); | 517 | list_del_rcu(&ipvlan->pnode); |
@@ -613,7 +613,7 @@ static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) | |||
613 | { | 613 | { |
614 | struct ipvl_addr *addr; | 614 | struct ipvl_addr *addr; |
615 | 615 | ||
616 | if (ipvlan_addr_busy(ipvlan, ip6_addr, true)) { | 616 | if (ipvlan_addr_busy(ipvlan->port, ip6_addr, true)) { |
617 | netif_err(ipvlan, ifup, ipvlan->dev, | 617 | netif_err(ipvlan, ifup, ipvlan->dev, |
618 | "Failed to add IPv6=%pI6c addr for %s intf\n", | 618 | "Failed to add IPv6=%pI6c addr for %s intf\n", |
619 | ip6_addr, ipvlan->dev->name); | 619 | ip6_addr, ipvlan->dev->name); |
@@ -626,9 +626,13 @@ static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) | |||
626 | addr->master = ipvlan; | 626 | addr->master = ipvlan; |
627 | memcpy(&addr->ip6addr, ip6_addr, sizeof(struct in6_addr)); | 627 | memcpy(&addr->ip6addr, ip6_addr, sizeof(struct in6_addr)); |
628 | addr->atype = IPVL_IPV6; | 628 | addr->atype = IPVL_IPV6; |
629 | list_add_tail_rcu(&addr->anode, &ipvlan->addrs); | 629 | list_add_tail(&addr->anode, &ipvlan->addrs); |
630 | ipvlan->ipv6cnt++; | 630 | ipvlan->ipv6cnt++; |
631 | ipvlan_ht_addr_add(ipvlan, addr); | 631 | /* If the interface is not up, the address will be added to the hash |
632 | * list by ipvlan_open. | ||
633 | */ | ||
634 | if (netif_running(ipvlan->dev)) | ||
635 | ipvlan_ht_addr_add(ipvlan, addr); | ||
632 | 636 | ||
633 | return 0; | 637 | return 0; |
634 | } | 638 | } |
@@ -637,12 +641,12 @@ static void ipvlan_del_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr) | |||
637 | { | 641 | { |
638 | struct ipvl_addr *addr; | 642 | struct ipvl_addr *addr; |
639 | 643 | ||
640 | addr = ipvlan_ht_addr_lookup(ipvlan->port, ip6_addr, true); | 644 | addr = ipvlan_find_addr(ipvlan, ip6_addr, true); |
641 | if (!addr) | 645 | if (!addr) |
642 | return; | 646 | return; |
643 | 647 | ||
644 | ipvlan_ht_addr_del(addr, true); | 648 | ipvlan_ht_addr_del(addr, true); |
645 | list_del_rcu(&addr->anode); | 649 | list_del(&addr->anode); |
646 | ipvlan->ipv6cnt--; | 650 | ipvlan->ipv6cnt--; |
647 | WARN_ON(ipvlan->ipv6cnt < 0); | 651 | WARN_ON(ipvlan->ipv6cnt < 0); |
648 | kfree_rcu(addr, rcu); | 652 | kfree_rcu(addr, rcu); |
@@ -681,7 +685,7 @@ static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) | |||
681 | { | 685 | { |
682 | struct ipvl_addr *addr; | 686 | struct ipvl_addr *addr; |
683 | 687 | ||
684 | if (ipvlan_addr_busy(ipvlan, ip4_addr, false)) { | 688 | if (ipvlan_addr_busy(ipvlan->port, ip4_addr, false)) { |
685 | netif_err(ipvlan, ifup, ipvlan->dev, | 689 | netif_err(ipvlan, ifup, ipvlan->dev, |
686 | "Failed to add IPv4=%pI4 on %s intf.\n", | 690 | "Failed to add IPv4=%pI4 on %s intf.\n", |
687 | ip4_addr, ipvlan->dev->name); | 691 | ip4_addr, ipvlan->dev->name); |
@@ -694,9 +698,13 @@ static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) | |||
694 | addr->master = ipvlan; | 698 | addr->master = ipvlan; |
695 | memcpy(&addr->ip4addr, ip4_addr, sizeof(struct in_addr)); | 699 | memcpy(&addr->ip4addr, ip4_addr, sizeof(struct in_addr)); |
696 | addr->atype = IPVL_IPV4; | 700 | addr->atype = IPVL_IPV4; |
697 | list_add_tail_rcu(&addr->anode, &ipvlan->addrs); | 701 | list_add_tail(&addr->anode, &ipvlan->addrs); |
698 | ipvlan->ipv4cnt++; | 702 | ipvlan->ipv4cnt++; |
699 | ipvlan_ht_addr_add(ipvlan, addr); | 703 | /* If the interface is not up, the address will be added to the hash |
704 | * list by ipvlan_open. | ||
705 | */ | ||
706 | if (netif_running(ipvlan->dev)) | ||
707 | ipvlan_ht_addr_add(ipvlan, addr); | ||
700 | ipvlan_set_broadcast_mac_filter(ipvlan, true); | 708 | ipvlan_set_broadcast_mac_filter(ipvlan, true); |
701 | 709 | ||
702 | return 0; | 710 | return 0; |
@@ -706,12 +714,12 @@ static void ipvlan_del_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr) | |||
706 | { | 714 | { |
707 | struct ipvl_addr *addr; | 715 | struct ipvl_addr *addr; |
708 | 716 | ||
709 | addr = ipvlan_ht_addr_lookup(ipvlan->port, ip4_addr, false); | 717 | addr = ipvlan_find_addr(ipvlan, ip4_addr, false); |
710 | if (!addr) | 718 | if (!addr) |
711 | return; | 719 | return; |
712 | 720 | ||
713 | ipvlan_ht_addr_del(addr, true); | 721 | ipvlan_ht_addr_del(addr, true); |
714 | list_del_rcu(&addr->anode); | 722 | list_del(&addr->anode); |
715 | ipvlan->ipv4cnt--; | 723 | ipvlan->ipv4cnt--; |
716 | WARN_ON(ipvlan->ipv4cnt < 0); | 724 | WARN_ON(ipvlan->ipv4cnt < 0); |
717 | if (!ipvlan->ipv4cnt) | 725 | if (!ipvlan->ipv4cnt) |