aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ipvlan/ipvlan_core.c
diff options
context:
space:
mode:
authorJiri Benc <jbenc@redhat.com>2015-03-28 14:13:25 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-31 13:28:33 -0400
commite9997c2938b23d792528da1597b3aea9b0f2a324 (patch)
treec2e767997eb357c7b48e4711c336a89ddcc730ce /drivers/net/ipvlan/ipvlan_core.c
parent40891e8ad630558caae26788d37bf50137b6d5d2 (diff)
ipvlan: fix check for IP addresses in control path
When an ipvlan interface is down, its addresses are not on the hash list. Fix checks for existence of addresses not to depend on the hash list, walk through all interface addresses instead. Signed-off-by: Jiri Benc <jbenc@redhat.com> Acked-by: Mahesh Bandewar <maheshb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ipvlan/ipvlan_core.c')
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 568628f95aa2..b7877a194cfe 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -92,9 +92,9 @@ void ipvlan_ht_addr_del(struct ipvl_addr *addr, bool sync)
92 synchronize_rcu(); 92 synchronize_rcu();
93} 93}
94 94
95bool ipvlan_addr_busy(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6) 95struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan,
96 const void *iaddr, bool is_v6)
96{ 97{
97 struct ipvl_port *port = ipvlan->port;
98 struct ipvl_addr *addr; 98 struct ipvl_addr *addr;
99 99
100 list_for_each_entry(addr, &ipvlan->addrs, anode) { 100 list_for_each_entry(addr, &ipvlan->addrs, anode) {
@@ -102,12 +102,21 @@ bool ipvlan_addr_busy(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
102 ipv6_addr_equal(&addr->ip6addr, iaddr)) || 102 ipv6_addr_equal(&addr->ip6addr, iaddr)) ||
103 (!is_v6 && addr->atype == IPVL_IPV4 && 103 (!is_v6 && addr->atype == IPVL_IPV4 &&
104 addr->ip4addr.s_addr == ((struct in_addr *)iaddr)->s_addr)) 104 addr->ip4addr.s_addr == ((struct in_addr *)iaddr)->s_addr))
105 return true; 105 return addr;
106 } 106 }
107 return NULL;
108}
107 109
108 if (ipvlan_ht_addr_lookup(port, iaddr, is_v6)) 110bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
109 return true; 111{
112 struct ipvl_dev *ipvlan;
113
114 ASSERT_RTNL();
110 115
116 list_for_each_entry(ipvlan, &port->ipvlans, pnode) {
117 if (ipvlan_find_addr(ipvlan, iaddr, is_v6))
118 return true;
119 }
111 return false; 120 return false;
112} 121}
113 122