mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									d45276e75e
								
							
						
					
					
						commit
						954d1fa1ac
					
				
					 3 changed files with 31 additions and 2 deletions
				
			
		| 
						 | 
					@ -47,6 +47,7 @@ struct macvlan_port {
 | 
				
			||||||
	struct sk_buff_head	bc_queue;
 | 
						struct sk_buff_head	bc_queue;
 | 
				
			||||||
	struct work_struct	bc_work;
 | 
						struct work_struct	bc_work;
 | 
				
			||||||
	u32			bc_queue_len_used;
 | 
						u32			bc_queue_len_used;
 | 
				
			||||||
 | 
						int			bc_cutoff;
 | 
				
			||||||
	u32			flags;
 | 
						u32			flags;
 | 
				
			||||||
	int			count;
 | 
						int			count;
 | 
				
			||||||
	struct hlist_head	vlan_source_hash[MACVLAN_HASH_SIZE];
 | 
						struct hlist_head	vlan_source_hash[MACVLAN_HASH_SIZE];
 | 
				
			||||||
| 
						 | 
					@ -814,6 +815,12 @@ static void macvlan_compute_filter(unsigned long *mc_filter,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void macvlan_recompute_bc_filter(struct macvlan_dev *vlan)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						macvlan_compute_filter(vlan->port->bc_filter, vlan->lowerdev, NULL,
 | 
				
			||||||
 | 
								       vlan->port->bc_cutoff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void macvlan_set_mac_lists(struct net_device *dev)
 | 
					static void macvlan_set_mac_lists(struct net_device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct macvlan_dev *vlan = netdev_priv(dev);
 | 
						struct macvlan_dev *vlan = netdev_priv(dev);
 | 
				
			||||||
| 
						 | 
					@ -838,8 +845,16 @@ static void macvlan_set_mac_lists(struct net_device *dev)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	macvlan_compute_filter(vlan->port->mc_filter, vlan->lowerdev, NULL,
 | 
						macvlan_compute_filter(vlan->port->mc_filter, vlan->lowerdev, NULL,
 | 
				
			||||||
			       0);
 | 
								       0);
 | 
				
			||||||
	macvlan_compute_filter(vlan->port->bc_filter, vlan->lowerdev, NULL,
 | 
						macvlan_recompute_bc_filter(vlan);
 | 
				
			||||||
			       1);
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void update_port_bc_cutoff(struct macvlan_dev *vlan, int cutoff)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (vlan->port->bc_cutoff == cutoff)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vlan->port->bc_cutoff = cutoff;
 | 
				
			||||||
 | 
						macvlan_recompute_bc_filter(vlan);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
 | 
					static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
 | 
				
			||||||
| 
						 | 
					@ -1254,6 +1269,7 @@ static int macvlan_port_create(struct net_device *dev)
 | 
				
			||||||
		INIT_HLIST_HEAD(&port->vlan_source_hash[i]);
 | 
							INIT_HLIST_HEAD(&port->vlan_source_hash[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	port->bc_queue_len_used = 0;
 | 
						port->bc_queue_len_used = 0;
 | 
				
			||||||
 | 
						port->bc_cutoff = 1;
 | 
				
			||||||
	skb_queue_head_init(&port->bc_queue);
 | 
						skb_queue_head_init(&port->bc_queue);
 | 
				
			||||||
	INIT_WORK(&port->bc_work, macvlan_process_broadcast);
 | 
						INIT_WORK(&port->bc_work, macvlan_process_broadcast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1527,6 +1543,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
 | 
				
			||||||
	if (data && data[IFLA_MACVLAN_BC_QUEUE_LEN])
 | 
						if (data && data[IFLA_MACVLAN_BC_QUEUE_LEN])
 | 
				
			||||||
		vlan->bc_queue_len_req = nla_get_u32(data[IFLA_MACVLAN_BC_QUEUE_LEN]);
 | 
							vlan->bc_queue_len_req = nla_get_u32(data[IFLA_MACVLAN_BC_QUEUE_LEN]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data && data[IFLA_MACVLAN_BC_CUTOFF])
 | 
				
			||||||
 | 
							update_port_bc_cutoff(
 | 
				
			||||||
 | 
								vlan, nla_get_s32(data[IFLA_MACVLAN_BC_CUTOFF]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = register_netdevice(dev);
 | 
						err = register_netdevice(dev);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		goto destroy_macvlan_port;
 | 
							goto destroy_macvlan_port;
 | 
				
			||||||
| 
						 | 
					@ -1623,6 +1643,10 @@ static int macvlan_changelink(struct net_device *dev,
 | 
				
			||||||
		update_port_bc_queue_len(vlan->port);
 | 
							update_port_bc_queue_len(vlan->port);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data && data[IFLA_MACVLAN_BC_CUTOFF])
 | 
				
			||||||
 | 
							update_port_bc_cutoff(
 | 
				
			||||||
 | 
								vlan, nla_get_s32(data[IFLA_MACVLAN_BC_CUTOFF]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (set_mode)
 | 
						if (set_mode)
 | 
				
			||||||
		vlan->mode = mode;
 | 
							vlan->mode = mode;
 | 
				
			||||||
	if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
 | 
						if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
 | 
				
			||||||
| 
						 | 
					@ -1703,6 +1727,9 @@ static int macvlan_fill_info(struct sk_buff *skb,
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
	if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN_USED, port->bc_queue_len_used))
 | 
						if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN_USED, port->bc_queue_len_used))
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
						if (port->bc_cutoff != 1 &&
 | 
				
			||||||
 | 
						    nla_put_s32(skb, IFLA_MACVLAN_BC_CUTOFF, port->bc_cutoff))
 | 
				
			||||||
 | 
							goto nla_put_failure;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nla_put_failure:
 | 
					nla_put_failure:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -635,6 +635,7 @@ enum {
 | 
				
			||||||
	IFLA_MACVLAN_MACADDR_COUNT,
 | 
						IFLA_MACVLAN_MACADDR_COUNT,
 | 
				
			||||||
	IFLA_MACVLAN_BC_QUEUE_LEN,
 | 
						IFLA_MACVLAN_BC_QUEUE_LEN,
 | 
				
			||||||
	IFLA_MACVLAN_BC_QUEUE_LEN_USED,
 | 
						IFLA_MACVLAN_BC_QUEUE_LEN_USED,
 | 
				
			||||||
 | 
						IFLA_MACVLAN_BC_CUTOFF,
 | 
				
			||||||
	__IFLA_MACVLAN_MAX,
 | 
						__IFLA_MACVLAN_MAX,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -605,6 +605,7 @@ enum {
 | 
				
			||||||
	IFLA_MACVLAN_MACADDR_COUNT,
 | 
						IFLA_MACVLAN_MACADDR_COUNT,
 | 
				
			||||||
	IFLA_MACVLAN_BC_QUEUE_LEN,
 | 
						IFLA_MACVLAN_BC_QUEUE_LEN,
 | 
				
			||||||
	IFLA_MACVLAN_BC_QUEUE_LEN_USED,
 | 
						IFLA_MACVLAN_BC_QUEUE_LEN_USED,
 | 
				
			||||||
 | 
						IFLA_MACVLAN_BC_CUTOFF,
 | 
				
			||||||
	__IFLA_MACVLAN_MAX,
 | 
						__IFLA_MACVLAN_MAX,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue