Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

macvlan: Add netlink attribute for broadcast cutoff

Make the broadcast cutoff configurable through netlink. Note
that macvlan is weird because there is no central device for
us to configure (the lowerdev could be anything). So all the
options are duplicated over what could be thousands of child
devices.

IFLA_MACVLAN_BC_QUEUE_LEN took the approach of taking the maximum
of all child device settings. This is unnecessary as we could
simply store the option in the port device and take the last
child device that gets updated as the value to use.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Herbert Xu and committed by
David S. Miller
954d1fa1 d45276e7

+31 -2
+29 -2
drivers/net/macvlan.c
··· 47 47 struct sk_buff_head bc_queue; 48 48 struct work_struct bc_work; 49 49 u32 bc_queue_len_used; 50 + int bc_cutoff; 50 51 u32 flags; 51 52 int count; 52 53 struct hlist_head vlan_source_hash[MACVLAN_HASH_SIZE]; ··· 815 814 } 816 815 } 817 816 817 + static void macvlan_recompute_bc_filter(struct macvlan_dev *vlan) 818 + { 819 + macvlan_compute_filter(vlan->port->bc_filter, vlan->lowerdev, NULL, 820 + vlan->port->bc_cutoff); 821 + } 822 + 818 823 static void macvlan_set_mac_lists(struct net_device *dev) 819 824 { 820 825 struct macvlan_dev *vlan = netdev_priv(dev); ··· 845 838 */ 846 839 macvlan_compute_filter(vlan->port->mc_filter, vlan->lowerdev, NULL, 847 840 0); 848 - macvlan_compute_filter(vlan->port->bc_filter, vlan->lowerdev, NULL, 849 - 1); 841 + macvlan_recompute_bc_filter(vlan); 842 + } 843 + 844 + static void update_port_bc_cutoff(struct macvlan_dev *vlan, int cutoff) 845 + { 846 + if (vlan->port->bc_cutoff == cutoff) 847 + return; 848 + 849 + vlan->port->bc_cutoff = cutoff; 850 + macvlan_recompute_bc_filter(vlan); 850 851 } 851 852 852 853 static int macvlan_change_mtu(struct net_device *dev, int new_mtu) ··· 1269 1254 INIT_HLIST_HEAD(&port->vlan_source_hash[i]); 1270 1255 1271 1256 port->bc_queue_len_used = 0; 1257 + port->bc_cutoff = 1; 1272 1258 skb_queue_head_init(&port->bc_queue); 1273 1259 INIT_WORK(&port->bc_work, macvlan_process_broadcast); 1274 1260 ··· 1543 1527 if (data && data[IFLA_MACVLAN_BC_QUEUE_LEN]) 1544 1528 vlan->bc_queue_len_req = nla_get_u32(data[IFLA_MACVLAN_BC_QUEUE_LEN]); 1545 1529 1530 + if (data && data[IFLA_MACVLAN_BC_CUTOFF]) 1531 + update_port_bc_cutoff( 1532 + vlan, nla_get_s32(data[IFLA_MACVLAN_BC_CUTOFF])); 1533 + 1546 1534 err = register_netdevice(dev); 1547 1535 if (err < 0) 1548 1536 goto destroy_macvlan_port; ··· 1643 1623 update_port_bc_queue_len(vlan->port); 1644 1624 } 1645 1625 1626 + if (data && data[IFLA_MACVLAN_BC_CUTOFF]) 1627 + update_port_bc_cutoff( 1628 + vlan, nla_get_s32(data[IFLA_MACVLAN_BC_CUTOFF])); 1629 + 1646 1630 if (set_mode) 1647 1631 vlan->mode = mode; 1648 1632 if (data && data[IFLA_MACVLAN_MACADDR_MODE]) { ··· 1726 1702 if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN, vlan->bc_queue_len_req)) 1727 1703 goto nla_put_failure; 1728 1704 if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN_USED, port->bc_queue_len_used)) 1705 + goto nla_put_failure; 1706 + if (port->bc_cutoff != 1 && 1707 + nla_put_s32(skb, IFLA_MACVLAN_BC_CUTOFF, port->bc_cutoff)) 1729 1708 goto nla_put_failure; 1730 1709 return 0; 1731 1710
+1
include/uapi/linux/if_link.h
··· 635 635 IFLA_MACVLAN_MACADDR_COUNT, 636 636 IFLA_MACVLAN_BC_QUEUE_LEN, 637 637 IFLA_MACVLAN_BC_QUEUE_LEN_USED, 638 + IFLA_MACVLAN_BC_CUTOFF, 638 639 __IFLA_MACVLAN_MAX, 639 640 }; 640 641
+1
tools/include/uapi/linux/if_link.h
··· 605 605 IFLA_MACVLAN_MACADDR_COUNT, 606 606 IFLA_MACVLAN_BC_QUEUE_LEN, 607 607 IFLA_MACVLAN_BC_QUEUE_LEN_USED, 608 + IFLA_MACVLAN_BC_CUTOFF, 608 609 __IFLA_MACVLAN_MAX, 609 610 }; 610 611