aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ipvlan/ipvlan_main.c
diff options
context:
space:
mode:
authorMahesh Bandewar <maheshb@google.com>2015-05-04 20:06:11 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-05 19:29:49 -0400
commitf631c44bbe1581d18d0aba628b3802d0eacb6373 (patch)
treead5402d0f33bfdff1e446bdb135ea20a7747c5e4 /drivers/net/ipvlan/ipvlan_main.c
parentba35f8588f474d5bf8988615b04ee722a2684fd2 (diff)
ipvlan: Always set broadcast bit in multicast filter
Earlier tricks of setting broadcast bit only when IPv4 address is added onto interface are not good enough especially when autoconf comes in play. Setting them on always is performance drag but now that multicast / broadcast is not processed in fast-path; enabling broadcast will let autoconf work correctly without affecting performance characteristics of the device. Signed-off-by: Mahesh Bandewar <maheshb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ipvlan/ipvlan_main.c')
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index a16d3017fdc3..1acc283160d9 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -218,17 +218,6 @@ static void ipvlan_change_rx_flags(struct net_device *dev, int change)
218 dev_set_allmulti(phy_dev, dev->flags & IFF_ALLMULTI? 1 : -1); 218 dev_set_allmulti(phy_dev, dev->flags & IFF_ALLMULTI? 1 : -1);
219} 219}
220 220
221static void ipvlan_set_broadcast_mac_filter(struct ipvl_dev *ipvlan, bool set)
222{
223 struct net_device *dev = ipvlan->dev;
224 unsigned int hashbit = ipvlan_mac_hash(dev->broadcast);
225
226 if (set && !test_bit(hashbit, ipvlan->mac_filters))
227 __set_bit(hashbit, ipvlan->mac_filters);
228 else if (!set && test_bit(hashbit, ipvlan->mac_filters))
229 __clear_bit(hashbit, ipvlan->mac_filters);
230}
231
232static void ipvlan_set_multicast_mac_filter(struct net_device *dev) 221static void ipvlan_set_multicast_mac_filter(struct net_device *dev)
233{ 222{
234 struct ipvl_dev *ipvlan = netdev_priv(dev); 223 struct ipvl_dev *ipvlan = netdev_priv(dev);
@@ -243,6 +232,12 @@ static void ipvlan_set_multicast_mac_filter(struct net_device *dev)
243 netdev_for_each_mc_addr(ha, dev) 232 netdev_for_each_mc_addr(ha, dev)
244 __set_bit(ipvlan_mac_hash(ha->addr), mc_filters); 233 __set_bit(ipvlan_mac_hash(ha->addr), mc_filters);
245 234
235 /* Turn-on broadcast bit irrespective of address family,
236 * since broadcast is deferred to a work-queue, hence no
237 * impact on fast-path processing.
238 */
239 __set_bit(ipvlan_mac_hash(dev->broadcast), mc_filters);
240
246 bitmap_copy(ipvlan->mac_filters, mc_filters, 241 bitmap_copy(ipvlan->mac_filters, mc_filters,
247 IPVLAN_MAC_FILTER_SIZE); 242 IPVLAN_MAC_FILTER_SIZE);
248 } 243 }
@@ -710,7 +705,6 @@ static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr)
710 */ 705 */
711 if (netif_running(ipvlan->dev)) 706 if (netif_running(ipvlan->dev))
712 ipvlan_ht_addr_add(ipvlan, addr); 707 ipvlan_ht_addr_add(ipvlan, addr);
713 ipvlan_set_broadcast_mac_filter(ipvlan, true);
714 708
715 return 0; 709 return 0;
716} 710}
@@ -727,8 +721,6 @@ static void ipvlan_del_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr)
727 list_del(&addr->anode); 721 list_del(&addr->anode);
728 ipvlan->ipv4cnt--; 722 ipvlan->ipv4cnt--;
729 WARN_ON(ipvlan->ipv4cnt < 0); 723 WARN_ON(ipvlan->ipv4cnt < 0);
730 if (!ipvlan->ipv4cnt)
731 ipvlan_set_broadcast_mac_filter(ipvlan, false);
732 kfree_rcu(addr, rcu); 724 kfree_rcu(addr, rcu);
733 725
734 return; 726 return;