xref: /linux/drivers/infiniband/core/roce_gid_mgmt.c (revision 25f4874662fb0d43fc1d934dd7802b740ed2ab5f)
103db3a2dSMatan Barak /*
203db3a2dSMatan Barak  * Copyright (c) 2015, Mellanox Technologies inc.  All rights reserved.
303db3a2dSMatan Barak  *
403db3a2dSMatan Barak  * This software is available to you under a choice of one of two
503db3a2dSMatan Barak  * licenses.  You may choose to be licensed under the terms of the GNU
603db3a2dSMatan Barak  * General Public License (GPL) Version 2, available from the file
703db3a2dSMatan Barak  * COPYING in the main directory of this source tree, or the
803db3a2dSMatan Barak  * OpenIB.org BSD license below:
903db3a2dSMatan Barak  *
1003db3a2dSMatan Barak  *     Redistribution and use in source and binary forms, with or
1103db3a2dSMatan Barak  *     without modification, are permitted provided that the following
1203db3a2dSMatan Barak  *     conditions are met:
1303db3a2dSMatan Barak  *
1403db3a2dSMatan Barak  *      - Redistributions of source code must retain the above
1503db3a2dSMatan Barak  *        copyright notice, this list of conditions and the following
1603db3a2dSMatan Barak  *        disclaimer.
1703db3a2dSMatan Barak  *
1803db3a2dSMatan Barak  *      - Redistributions in binary form must reproduce the above
1903db3a2dSMatan Barak  *        copyright notice, this list of conditions and the following
2003db3a2dSMatan Barak  *        disclaimer in the documentation and/or other materials
2103db3a2dSMatan Barak  *        provided with the distribution.
2203db3a2dSMatan Barak  *
2303db3a2dSMatan Barak  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2403db3a2dSMatan Barak  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2503db3a2dSMatan Barak  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2603db3a2dSMatan Barak  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2703db3a2dSMatan Barak  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2803db3a2dSMatan Barak  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2903db3a2dSMatan Barak  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3003db3a2dSMatan Barak  * SOFTWARE.
3103db3a2dSMatan Barak  */
3203db3a2dSMatan Barak 
3303db3a2dSMatan Barak #include "core_priv.h"
3403db3a2dSMatan Barak 
3503db3a2dSMatan Barak #include <linux/in.h>
3603db3a2dSMatan Barak #include <linux/in6.h>
3703db3a2dSMatan Barak 
3803db3a2dSMatan Barak /* For in6_dev_get/in6_dev_put */
3903db3a2dSMatan Barak #include <net/addrconf.h>
40238fdf48SMatan Barak #include <net/bonding.h>
4103db3a2dSMatan Barak 
4203db3a2dSMatan Barak #include <rdma/ib_cache.h>
4303db3a2dSMatan Barak #include <rdma/ib_addr.h>
4403db3a2dSMatan Barak 
458fe8bacbSMajd Dibbiny static struct workqueue_struct *gid_cache_wq;
468fe8bacbSMajd Dibbiny 
4703db3a2dSMatan Barak enum gid_op_type {
4803db3a2dSMatan Barak 	GID_DEL = 0,
4903db3a2dSMatan Barak 	GID_ADD
5003db3a2dSMatan Barak };
5103db3a2dSMatan Barak 
5203db3a2dSMatan Barak struct update_gid_event_work {
5303db3a2dSMatan Barak 	struct work_struct work;
5403db3a2dSMatan Barak 	union ib_gid       gid;
5503db3a2dSMatan Barak 	struct ib_gid_attr gid_attr;
5603db3a2dSMatan Barak 	enum gid_op_type gid_op;
5703db3a2dSMatan Barak };
5803db3a2dSMatan Barak 
59238fdf48SMatan Barak #define ROCE_NETDEV_CALLBACK_SZ		3
6003db3a2dSMatan Barak struct netdev_event_work_cmd {
6103db3a2dSMatan Barak 	roce_netdev_callback	cb;
6203db3a2dSMatan Barak 	roce_netdev_filter	filter;
63238fdf48SMatan Barak 	struct net_device	*ndev;
64238fdf48SMatan Barak 	struct net_device	*filter_ndev;
6503db3a2dSMatan Barak };
6603db3a2dSMatan Barak 
6703db3a2dSMatan Barak struct netdev_event_work {
6803db3a2dSMatan Barak 	struct work_struct		work;
6903db3a2dSMatan Barak 	struct netdev_event_work_cmd	cmds[ROCE_NETDEV_CALLBACK_SZ];
7003db3a2dSMatan Barak };
7103db3a2dSMatan Barak 
72b39ffa1dSMatan Barak static const struct {
731fb7f897SMark Bloch 	bool (*is_supported)(const struct ib_device *device, u32 port_num);
74b39ffa1dSMatan Barak 	enum ib_gid_type gid_type;
75b39ffa1dSMatan Barak } PORT_CAP_TO_GID_TYPE[] = {
767766a99fSMatan Barak 	{rdma_protocol_roce_eth_encap, IB_GID_TYPE_ROCE},
777766a99fSMatan Barak 	{rdma_protocol_roce_udp_encap, IB_GID_TYPE_ROCE_UDP_ENCAP},
78b39ffa1dSMatan Barak };
79b39ffa1dSMatan Barak 
80b39ffa1dSMatan Barak #define CAP_TO_GID_TABLE_SIZE	ARRAY_SIZE(PORT_CAP_TO_GID_TYPE)
81b39ffa1dSMatan Barak 
roce_gid_type_mask_support(struct ib_device * ib_dev,u32 port)821fb7f897SMark Bloch unsigned long roce_gid_type_mask_support(struct ib_device *ib_dev, u32 port)
83b39ffa1dSMatan Barak {
84b39ffa1dSMatan Barak 	int i;
85b39ffa1dSMatan Barak 	unsigned int ret_flags = 0;
86b39ffa1dSMatan Barak 
87b39ffa1dSMatan Barak 	if (!rdma_protocol_roce(ib_dev, port))
88b39ffa1dSMatan Barak 		return 1UL << IB_GID_TYPE_IB;
89b39ffa1dSMatan Barak 
90b39ffa1dSMatan Barak 	for (i = 0; i < CAP_TO_GID_TABLE_SIZE; i++)
91b39ffa1dSMatan Barak 		if (PORT_CAP_TO_GID_TYPE[i].is_supported(ib_dev, port))
92b39ffa1dSMatan Barak 			ret_flags |= 1UL << PORT_CAP_TO_GID_TYPE[i].gid_type;
93b39ffa1dSMatan Barak 
94b39ffa1dSMatan Barak 	return ret_flags;
95b39ffa1dSMatan Barak }
96b39ffa1dSMatan Barak EXPORT_SYMBOL(roce_gid_type_mask_support);
97b39ffa1dSMatan Barak 
update_gid(enum gid_op_type gid_op,struct ib_device * ib_dev,u32 port,union ib_gid * gid,struct ib_gid_attr * gid_attr)9803db3a2dSMatan Barak static void update_gid(enum gid_op_type gid_op, struct ib_device *ib_dev,
991fb7f897SMark Bloch 		       u32 port, union ib_gid *gid,
10003db3a2dSMatan Barak 		       struct ib_gid_attr *gid_attr)
10103db3a2dSMatan Barak {
102b39ffa1dSMatan Barak 	int i;
103b39ffa1dSMatan Barak 	unsigned long gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
104b39ffa1dSMatan Barak 
105b39ffa1dSMatan Barak 	for (i = 0; i < IB_GID_TYPE_SIZE; i++) {
106b39ffa1dSMatan Barak 		if ((1UL << i) & gid_type_mask) {
107b39ffa1dSMatan Barak 			gid_attr->gid_type = i;
10803db3a2dSMatan Barak 			switch (gid_op) {
10903db3a2dSMatan Barak 			case GID_ADD:
110b39ffa1dSMatan Barak 				ib_cache_gid_add(ib_dev, port,
111b39ffa1dSMatan Barak 						 gid, gid_attr);
11203db3a2dSMatan Barak 				break;
11303db3a2dSMatan Barak 			case GID_DEL:
114b39ffa1dSMatan Barak 				ib_cache_gid_del(ib_dev, port,
115b39ffa1dSMatan Barak 						 gid, gid_attr);
11603db3a2dSMatan Barak 				break;
11703db3a2dSMatan Barak 			}
11803db3a2dSMatan Barak 		}
119b39ffa1dSMatan Barak 	}
120b39ffa1dSMatan Barak }
12103db3a2dSMatan Barak 
122238fdf48SMatan Barak enum bonding_slave_state {
123238fdf48SMatan Barak 	BONDING_SLAVE_STATE_ACTIVE	= 1UL << 0,
124238fdf48SMatan Barak 	BONDING_SLAVE_STATE_INACTIVE	= 1UL << 1,
125238fdf48SMatan Barak 	/* No primary slave or the device isn't a slave in bonding */
126238fdf48SMatan Barak 	BONDING_SLAVE_STATE_NA		= 1UL << 2,
127238fdf48SMatan Barak };
128238fdf48SMatan Barak 
is_eth_active_slave_of_bonding_rcu(struct net_device * dev,struct net_device * upper)129238fdf48SMatan Barak static enum bonding_slave_state is_eth_active_slave_of_bonding_rcu(struct net_device *dev,
130238fdf48SMatan Barak 								   struct net_device *upper)
131238fdf48SMatan Barak {
132238fdf48SMatan Barak 	if (upper && netif_is_bond_master(upper)) {
133238fdf48SMatan Barak 		struct net_device *pdev =
134238fdf48SMatan Barak 			bond_option_active_slave_get_rcu(netdev_priv(upper));
135238fdf48SMatan Barak 
136238fdf48SMatan Barak 		if (pdev)
137238fdf48SMatan Barak 			return dev == pdev ? BONDING_SLAVE_STATE_ACTIVE :
138238fdf48SMatan Barak 				BONDING_SLAVE_STATE_INACTIVE;
139238fdf48SMatan Barak 	}
140238fdf48SMatan Barak 
141238fdf48SMatan Barak 	return BONDING_SLAVE_STATE_NA;
142238fdf48SMatan Barak }
143238fdf48SMatan Barak 
144238fdf48SMatan Barak #define REQUIRED_BOND_STATES		(BONDING_SLAVE_STATE_ACTIVE |	\
145238fdf48SMatan Barak 					 BONDING_SLAVE_STATE_NA)
146dd81b2c8SParav Pandit static bool
is_eth_port_of_netdev_filter(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)1471fb7f897SMark Bloch is_eth_port_of_netdev_filter(struct ib_device *ib_dev, u32 port,
14803db3a2dSMatan Barak 			     struct net_device *rdma_ndev, void *cookie)
14903db3a2dSMatan Barak {
150238fdf48SMatan Barak 	struct net_device *real_dev;
151dd81b2c8SParav Pandit 	bool res;
152238fdf48SMatan Barak 
153238fdf48SMatan Barak 	if (!rdma_ndev)
154dd81b2c8SParav Pandit 		return false;
155238fdf48SMatan Barak 
156238fdf48SMatan Barak 	rcu_read_lock();
15759039608SParav Pandit 	real_dev = rdma_vlan_dev_real_dev(cookie);
158238fdf48SMatan Barak 	if (!real_dev)
15959039608SParav Pandit 		real_dev = cookie;
160238fdf48SMatan Barak 
16159039608SParav Pandit 	res = ((rdma_is_upper_dev_rcu(rdma_ndev, cookie) &&
162238fdf48SMatan Barak 	       (is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev) &
163238fdf48SMatan Barak 		REQUIRED_BOND_STATES)) ||
164238fdf48SMatan Barak 	       real_dev == rdma_ndev);
165238fdf48SMatan Barak 
166238fdf48SMatan Barak 	rcu_read_unlock();
167238fdf48SMatan Barak 	return res;
168238fdf48SMatan Barak }
169238fdf48SMatan Barak 
170dd81b2c8SParav Pandit static bool
is_eth_port_inactive_slave_filter(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)1711fb7f897SMark Bloch is_eth_port_inactive_slave_filter(struct ib_device *ib_dev, u32 port,
172238fdf48SMatan Barak 				  struct net_device *rdma_ndev, void *cookie)
173238fdf48SMatan Barak {
174238fdf48SMatan Barak 	struct net_device *master_dev;
175dd81b2c8SParav Pandit 	bool res;
17603db3a2dSMatan Barak 
17703db3a2dSMatan Barak 	if (!rdma_ndev)
178dd81b2c8SParav Pandit 		return false;
17903db3a2dSMatan Barak 
18003db3a2dSMatan Barak 	rcu_read_lock();
18103db3a2dSMatan Barak 	master_dev = netdev_master_upper_dev_get_rcu(rdma_ndev);
182238fdf48SMatan Barak 	res = is_eth_active_slave_of_bonding_rcu(rdma_ndev, master_dev) ==
183238fdf48SMatan Barak 		BONDING_SLAVE_STATE_INACTIVE;
18403db3a2dSMatan Barak 	rcu_read_unlock();
18503db3a2dSMatan Barak 
18603db3a2dSMatan Barak 	return res;
18703db3a2dSMatan Barak }
18803db3a2dSMatan Barak 
189bf194997SLeon Romanovsky /**
190bf194997SLeon Romanovsky  * is_ndev_for_default_gid_filter - Check if a given netdevice
191464b79b4SParav Pandit  * can be considered for default GIDs or not.
192464b79b4SParav Pandit  * @ib_dev:		IB device to check
193464b79b4SParav Pandit  * @port:		Port to consider for adding default GID
194464b79b4SParav Pandit  * @rdma_ndev:		rdma netdevice pointer
195bf194997SLeon Romanovsky  * @cookie:             Netdevice to consider to form a default GID
196464b79b4SParav Pandit  *
197dd81b2c8SParav Pandit  * is_ndev_for_default_gid_filter() returns true if a given netdevice can be
198dd81b2c8SParav Pandit  * considered for deriving default RoCE GID, returns false otherwise.
199464b79b4SParav Pandit  */
200dd81b2c8SParav Pandit static bool
is_ndev_for_default_gid_filter(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)2011fb7f897SMark Bloch is_ndev_for_default_gid_filter(struct ib_device *ib_dev, u32 port,
202464b79b4SParav Pandit 			       struct net_device *rdma_ndev, void *cookie)
203464b79b4SParav Pandit {
204464b79b4SParav Pandit 	struct net_device *cookie_ndev = cookie;
205dd81b2c8SParav Pandit 	bool res;
206464b79b4SParav Pandit 
207464b79b4SParav Pandit 	if (!rdma_ndev)
208dd81b2c8SParav Pandit 		return false;
209464b79b4SParav Pandit 
210464b79b4SParav Pandit 	rcu_read_lock();
211464b79b4SParav Pandit 
212464b79b4SParav Pandit 	/*
213464b79b4SParav Pandit 	 * When rdma netdevice is used in bonding, bonding master netdevice
214464b79b4SParav Pandit 	 * should be considered for default GIDs. Therefore, ignore slave rdma
215464b79b4SParav Pandit 	 * netdevices when bonding is considered.
216464b79b4SParav Pandit 	 * Additionally when event(cookie) netdevice is bond master device,
217464b79b4SParav Pandit 	 * make sure that it the upper netdevice of rdma netdevice.
218464b79b4SParav Pandit 	 */
219464b79b4SParav Pandit 	res = ((cookie_ndev == rdma_ndev && !netif_is_bond_slave(rdma_ndev)) ||
220464b79b4SParav Pandit 	       (netif_is_bond_master(cookie_ndev) &&
221464b79b4SParav Pandit 		rdma_is_upper_dev_rcu(rdma_ndev, cookie_ndev)));
222464b79b4SParav Pandit 
223464b79b4SParav Pandit 	rcu_read_unlock();
224464b79b4SParav Pandit 	return res;
225464b79b4SParav Pandit }
226464b79b4SParav Pandit 
pass_all_filter(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)2271fb7f897SMark Bloch static bool pass_all_filter(struct ib_device *ib_dev, u32 port,
22803db3a2dSMatan Barak 			    struct net_device *rdma_ndev, void *cookie)
22903db3a2dSMatan Barak {
230dd81b2c8SParav Pandit 	return true;
23103db3a2dSMatan Barak }
23203db3a2dSMatan Barak 
upper_device_filter(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)2331fb7f897SMark Bloch static bool upper_device_filter(struct ib_device *ib_dev, u32 port,
234238fdf48SMatan Barak 				struct net_device *rdma_ndev, void *cookie)
235238fdf48SMatan Barak {
236dd81b2c8SParav Pandit 	bool res;
237238fdf48SMatan Barak 
238238fdf48SMatan Barak 	if (!rdma_ndev)
239dd81b2c8SParav Pandit 		return false;
240238fdf48SMatan Barak 
24159039608SParav Pandit 	if (rdma_ndev == cookie)
242dd81b2c8SParav Pandit 		return true;
243238fdf48SMatan Barak 
244238fdf48SMatan Barak 	rcu_read_lock();
24559039608SParav Pandit 	res = rdma_is_upper_dev_rcu(rdma_ndev, cookie);
246238fdf48SMatan Barak 	rcu_read_unlock();
247238fdf48SMatan Barak 
248238fdf48SMatan Barak 	return res;
249238fdf48SMatan Barak }
250238fdf48SMatan Barak 
251408f1242SParav Pandit /**
252408f1242SParav Pandit  * is_upper_ndev_bond_master_filter - Check if a given netdevice
253*ca325edbSSlark Xiao  * is bond master device of netdevice of the RDMA device of port.
254408f1242SParav Pandit  * @ib_dev:		IB device to check
255408f1242SParav Pandit  * @port:		Port to consider for adding default GID
256408f1242SParav Pandit  * @rdma_ndev:		Pointer to rdma netdevice
257408f1242SParav Pandit  * @cookie:	        Netdevice to consider to form a default GID
258408f1242SParav Pandit  *
259408f1242SParav Pandit  * is_upper_ndev_bond_master_filter() returns true if a cookie_netdev
260408f1242SParav Pandit  * is bond master device and rdma_ndev is its lower netdevice. It might
261408f1242SParav Pandit  * not have been established as slave device yet.
262408f1242SParav Pandit  */
263dd81b2c8SParav Pandit static bool
is_upper_ndev_bond_master_filter(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)2641fb7f897SMark Bloch is_upper_ndev_bond_master_filter(struct ib_device *ib_dev, u32 port,
265408f1242SParav Pandit 				 struct net_device *rdma_ndev,
266408f1242SParav Pandit 				 void *cookie)
267408f1242SParav Pandit {
268408f1242SParav Pandit 	struct net_device *cookie_ndev = cookie;
269408f1242SParav Pandit 	bool match = false;
270408f1242SParav Pandit 
27137fbd834SMark Zhang 	if (!rdma_ndev)
27237fbd834SMark Zhang 		return false;
27337fbd834SMark Zhang 
274408f1242SParav Pandit 	rcu_read_lock();
275408f1242SParav Pandit 	if (netif_is_bond_master(cookie_ndev) &&
276408f1242SParav Pandit 	    rdma_is_upper_dev_rcu(rdma_ndev, cookie_ndev))
277408f1242SParav Pandit 		match = true;
278408f1242SParav Pandit 	rcu_read_unlock();
279408f1242SParav Pandit 	return match;
280408f1242SParav Pandit }
281408f1242SParav Pandit 
update_gid_ip(enum gid_op_type gid_op,struct ib_device * ib_dev,u32 port,struct net_device * ndev,struct sockaddr * addr)28203db3a2dSMatan Barak static void update_gid_ip(enum gid_op_type gid_op,
28303db3a2dSMatan Barak 			  struct ib_device *ib_dev,
2841fb7f897SMark Bloch 			  u32 port, struct net_device *ndev,
28503db3a2dSMatan Barak 			  struct sockaddr *addr)
28603db3a2dSMatan Barak {
28703db3a2dSMatan Barak 	union ib_gid gid;
28803db3a2dSMatan Barak 	struct ib_gid_attr gid_attr;
28903db3a2dSMatan Barak 
29003db3a2dSMatan Barak 	rdma_ip2gid(addr, &gid);
29103db3a2dSMatan Barak 	memset(&gid_attr, 0, sizeof(gid_attr));
29203db3a2dSMatan Barak 	gid_attr.ndev = ndev;
29303db3a2dSMatan Barak 
29403db3a2dSMatan Barak 	update_gid(gid_op, ib_dev, port, &gid, &gid_attr);
29503db3a2dSMatan Barak }
29603db3a2dSMatan Barak 
bond_delete_netdev_default_gids(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,struct net_device * event_ndev)297238fdf48SMatan Barak static void bond_delete_netdev_default_gids(struct ib_device *ib_dev,
2981fb7f897SMark Bloch 					    u32 port,
299b9f09866SParav Pandit 					    struct net_device *rdma_ndev,
300d12e2eedSParav Pandit 					    struct net_device *event_ndev)
301238fdf48SMatan Barak {
302238fdf48SMatan Barak 	struct net_device *real_dev = rdma_vlan_dev_real_dev(event_ndev);
303dc5640f2SParav Pandit 	unsigned long gid_type_mask;
304238fdf48SMatan Barak 
305238fdf48SMatan Barak 	if (!rdma_ndev)
306238fdf48SMatan Barak 		return;
307238fdf48SMatan Barak 
308238fdf48SMatan Barak 	if (!real_dev)
309238fdf48SMatan Barak 		real_dev = event_ndev;
310238fdf48SMatan Barak 
311238fdf48SMatan Barak 	rcu_read_lock();
312238fdf48SMatan Barak 
313dc5640f2SParav Pandit 	if (((rdma_ndev != event_ndev &&
314dc5640f2SParav Pandit 	      !rdma_is_upper_dev_rcu(rdma_ndev, event_ndev)) ||
315dc5640f2SParav Pandit 	     is_eth_active_slave_of_bonding_rcu(rdma_ndev, real_dev)
316dc5640f2SParav Pandit 						 ==
317dc5640f2SParav Pandit 	     BONDING_SLAVE_STATE_INACTIVE)) {
318dc5640f2SParav Pandit 		rcu_read_unlock();
319dc5640f2SParav Pandit 		return;
320dc5640f2SParav Pandit 	}
321b39ffa1dSMatan Barak 
322238fdf48SMatan Barak 	rcu_read_unlock();
323238fdf48SMatan Barak 
324b39ffa1dSMatan Barak 	gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
325b39ffa1dSMatan Barak 
326238fdf48SMatan Barak 	ib_cache_gid_set_default_gid(ib_dev, port, rdma_ndev,
327b39ffa1dSMatan Barak 				     gid_type_mask,
328238fdf48SMatan Barak 				     IB_CACHE_GID_DEFAULT_MODE_DELETE);
329238fdf48SMatan Barak }
330238fdf48SMatan Barak 
enum_netdev_ipv4_ips(struct ib_device * ib_dev,u32 port,struct net_device * ndev)33103db3a2dSMatan Barak static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
3321fb7f897SMark Bloch 				 u32 port, struct net_device *ndev)
33303db3a2dSMatan Barak {
334cb8f1478SFlorian Westphal 	const struct in_ifaddr *ifa;
33503db3a2dSMatan Barak 	struct in_device *in_dev;
33639096420SMatan Barak 	struct sin_list {
33739096420SMatan Barak 		struct list_head	list;
33839096420SMatan Barak 		struct sockaddr_in	ip;
33939096420SMatan Barak 	};
34039096420SMatan Barak 	struct sin_list *sin_iter;
34139096420SMatan Barak 	struct sin_list *sin_temp;
34203db3a2dSMatan Barak 
34339096420SMatan Barak 	LIST_HEAD(sin_list);
34403db3a2dSMatan Barak 	if (ndev->reg_state >= NETREG_UNREGISTERING)
34503db3a2dSMatan Barak 		return;
34603db3a2dSMatan Barak 
34739096420SMatan Barak 	rcu_read_lock();
34839096420SMatan Barak 	in_dev = __in_dev_get_rcu(ndev);
34939096420SMatan Barak 	if (!in_dev) {
35039096420SMatan Barak 		rcu_read_unlock();
35103db3a2dSMatan Barak 		return;
35239096420SMatan Barak 	}
35303db3a2dSMatan Barak 
354cb8f1478SFlorian Westphal 	in_dev_for_each_ifa_rcu(ifa, in_dev) {
35539096420SMatan Barak 		struct sin_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
35603db3a2dSMatan Barak 
357a0b3455fSLeon Romanovsky 		if (!entry)
35839096420SMatan Barak 			continue;
359a0b3455fSLeon Romanovsky 
36039096420SMatan Barak 		entry->ip.sin_family = AF_INET;
36139096420SMatan Barak 		entry->ip.sin_addr.s_addr = ifa->ifa_address;
36239096420SMatan Barak 		list_add_tail(&entry->list, &sin_list);
36303db3a2dSMatan Barak 	}
364cb8f1478SFlorian Westphal 
36539096420SMatan Barak 	rcu_read_unlock();
36603db3a2dSMatan Barak 
36739096420SMatan Barak 	list_for_each_entry_safe(sin_iter, sin_temp, &sin_list, list) {
36839096420SMatan Barak 		update_gid_ip(GID_ADD, ib_dev, port, ndev,
36939096420SMatan Barak 			      (struct sockaddr *)&sin_iter->ip);
37039096420SMatan Barak 		list_del(&sin_iter->list);
37139096420SMatan Barak 		kfree(sin_iter);
37239096420SMatan Barak 	}
37303db3a2dSMatan Barak }
37403db3a2dSMatan Barak 
enum_netdev_ipv6_ips(struct ib_device * ib_dev,u32 port,struct net_device * ndev)37503db3a2dSMatan Barak static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
3761fb7f897SMark Bloch 				 u32 port, struct net_device *ndev)
37703db3a2dSMatan Barak {
37803db3a2dSMatan Barak 	struct inet6_ifaddr *ifp;
37903db3a2dSMatan Barak 	struct inet6_dev *in6_dev;
38003db3a2dSMatan Barak 	struct sin6_list {
38103db3a2dSMatan Barak 		struct list_head	list;
38203db3a2dSMatan Barak 		struct sockaddr_in6	sin6;
38303db3a2dSMatan Barak 	};
38403db3a2dSMatan Barak 	struct sin6_list *sin6_iter;
38503db3a2dSMatan Barak 	struct sin6_list *sin6_temp;
38603db3a2dSMatan Barak 	struct ib_gid_attr gid_attr = {.ndev = ndev};
38703db3a2dSMatan Barak 	LIST_HEAD(sin6_list);
38803db3a2dSMatan Barak 
38903db3a2dSMatan Barak 	if (ndev->reg_state >= NETREG_UNREGISTERING)
39003db3a2dSMatan Barak 		return;
39103db3a2dSMatan Barak 
39203db3a2dSMatan Barak 	in6_dev = in6_dev_get(ndev);
39303db3a2dSMatan Barak 	if (!in6_dev)
39403db3a2dSMatan Barak 		return;
39503db3a2dSMatan Barak 
39603db3a2dSMatan Barak 	read_lock_bh(&in6_dev->lock);
39703db3a2dSMatan Barak 	list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
39803db3a2dSMatan Barak 		struct sin6_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
39903db3a2dSMatan Barak 
400a0b3455fSLeon Romanovsky 		if (!entry)
40103db3a2dSMatan Barak 			continue;
40203db3a2dSMatan Barak 
40303db3a2dSMatan Barak 		entry->sin6.sin6_family = AF_INET6;
40403db3a2dSMatan Barak 		entry->sin6.sin6_addr = ifp->addr;
40503db3a2dSMatan Barak 		list_add_tail(&entry->list, &sin6_list);
40603db3a2dSMatan Barak 	}
40703db3a2dSMatan Barak 	read_unlock_bh(&in6_dev->lock);
40803db3a2dSMatan Barak 
40903db3a2dSMatan Barak 	in6_dev_put(in6_dev);
41003db3a2dSMatan Barak 
41103db3a2dSMatan Barak 	list_for_each_entry_safe(sin6_iter, sin6_temp, &sin6_list, list) {
41203db3a2dSMatan Barak 		union ib_gid	gid;
41303db3a2dSMatan Barak 
41403db3a2dSMatan Barak 		rdma_ip2gid((struct sockaddr *)&sin6_iter->sin6, &gid);
41503db3a2dSMatan Barak 		update_gid(GID_ADD, ib_dev, port, &gid, &gid_attr);
41603db3a2dSMatan Barak 		list_del(&sin6_iter->list);
41703db3a2dSMatan Barak 		kfree(sin6_iter);
41803db3a2dSMatan Barak 	}
41903db3a2dSMatan Barak }
42003db3a2dSMatan Barak 
_add_netdev_ips(struct ib_device * ib_dev,u32 port,struct net_device * ndev)4211fb7f897SMark Bloch static void _add_netdev_ips(struct ib_device *ib_dev, u32 port,
422238fdf48SMatan Barak 			    struct net_device *ndev)
423238fdf48SMatan Barak {
424238fdf48SMatan Barak 	enum_netdev_ipv4_ips(ib_dev, port, ndev);
425238fdf48SMatan Barak 	if (IS_ENABLED(CONFIG_IPV6))
426238fdf48SMatan Barak 		enum_netdev_ipv6_ips(ib_dev, port, ndev);
427238fdf48SMatan Barak }
428238fdf48SMatan Barak 
add_netdev_ips(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)4291fb7f897SMark Bloch static void add_netdev_ips(struct ib_device *ib_dev, u32 port,
43003db3a2dSMatan Barak 			   struct net_device *rdma_ndev, void *cookie)
43103db3a2dSMatan Barak {
43259039608SParav Pandit 	_add_netdev_ips(ib_dev, port, cookie);
43303db3a2dSMatan Barak }
43403db3a2dSMatan Barak 
del_netdev_ips(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)4351fb7f897SMark Bloch static void del_netdev_ips(struct ib_device *ib_dev, u32 port,
43603db3a2dSMatan Barak 			   struct net_device *rdma_ndev, void *cookie)
43703db3a2dSMatan Barak {
43859039608SParav Pandit 	ib_cache_gid_del_all_netdev_gids(ib_dev, port, cookie);
43903db3a2dSMatan Barak }
44003db3a2dSMatan Barak 
441408f1242SParav Pandit /**
442408f1242SParav Pandit  * del_default_gids - Delete default GIDs of the event/cookie netdevice
443408f1242SParav Pandit  * @ib_dev:	RDMA device pointer
444408f1242SParav Pandit  * @port:	Port of the RDMA device whose GID table to consider
445408f1242SParav Pandit  * @rdma_ndev:	Unused rdma netdevice
446408f1242SParav Pandit  * @cookie:	Pointer to event netdevice
447408f1242SParav Pandit  *
448408f1242SParav Pandit  * del_default_gids() deletes the default GIDs of the event/cookie netdevice.
449408f1242SParav Pandit  */
del_default_gids(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)4501fb7f897SMark Bloch static void del_default_gids(struct ib_device *ib_dev, u32 port,
451408f1242SParav Pandit 			     struct net_device *rdma_ndev, void *cookie)
452408f1242SParav Pandit {
453408f1242SParav Pandit 	struct net_device *cookie_ndev = cookie;
454408f1242SParav Pandit 	unsigned long gid_type_mask;
455408f1242SParav Pandit 
456408f1242SParav Pandit 	gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
457408f1242SParav Pandit 
458408f1242SParav Pandit 	ib_cache_gid_set_default_gid(ib_dev, port, cookie_ndev, gid_type_mask,
459408f1242SParav Pandit 				     IB_CACHE_GID_DEFAULT_MODE_DELETE);
460408f1242SParav Pandit }
461408f1242SParav Pandit 
add_default_gids(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)4621fb7f897SMark Bloch static void add_default_gids(struct ib_device *ib_dev, u32 port,
463a03d4d27SParav Pandit 			     struct net_device *rdma_ndev, void *cookie)
464a03d4d27SParav Pandit {
465a03d4d27SParav Pandit 	struct net_device *event_ndev = cookie;
466a03d4d27SParav Pandit 	unsigned long gid_type_mask;
467a03d4d27SParav Pandit 
468a03d4d27SParav Pandit 	gid_type_mask = roce_gid_type_mask_support(ib_dev, port);
469a03d4d27SParav Pandit 	ib_cache_gid_set_default_gid(ib_dev, port, event_ndev, gid_type_mask,
470a03d4d27SParav Pandit 				     IB_CACHE_GID_DEFAULT_MODE_SET);
471a03d4d27SParav Pandit }
472a03d4d27SParav Pandit 
enum_all_gids_of_dev_cb(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)47303db3a2dSMatan Barak static void enum_all_gids_of_dev_cb(struct ib_device *ib_dev,
4741fb7f897SMark Bloch 				    u32 port,
47503db3a2dSMatan Barak 				    struct net_device *rdma_ndev,
47603db3a2dSMatan Barak 				    void *cookie)
47703db3a2dSMatan Barak {
47803db3a2dSMatan Barak 	struct net *net;
47903db3a2dSMatan Barak 	struct net_device *ndev;
48003db3a2dSMatan Barak 
48103db3a2dSMatan Barak 	/* Lock the rtnl to make sure the netdevs does not move under
48203db3a2dSMatan Barak 	 * our feet
48303db3a2dSMatan Barak 	 */
48403db3a2dSMatan Barak 	rtnl_lock();
485f0b07bb1SKirill Tkhai 	down_read(&net_rwsem);
48603db3a2dSMatan Barak 	for_each_net(net)
487464b79b4SParav Pandit 		for_each_netdev(net, ndev) {
488464b79b4SParav Pandit 			/*
489464b79b4SParav Pandit 			 * Filter and add default GIDs of the primary netdevice
490464b79b4SParav Pandit 			 * when not in bonding mode, or add default GIDs
491464b79b4SParav Pandit 			 * of bond master device, when in bonding mode.
492464b79b4SParav Pandit 			 */
493464b79b4SParav Pandit 			if (is_ndev_for_default_gid_filter(ib_dev, port,
494464b79b4SParav Pandit 							   rdma_ndev, ndev))
495464b79b4SParav Pandit 				add_default_gids(ib_dev, port, rdma_ndev, ndev);
496464b79b4SParav Pandit 
497dd81b2c8SParav Pandit 			if (is_eth_port_of_netdev_filter(ib_dev, port,
498dd81b2c8SParav Pandit 							 rdma_ndev, ndev))
499464b79b4SParav Pandit 				_add_netdev_ips(ib_dev, port, ndev);
500464b79b4SParav Pandit 		}
501f0b07bb1SKirill Tkhai 	up_read(&net_rwsem);
50203db3a2dSMatan Barak 	rtnl_unlock();
50303db3a2dSMatan Barak }
50403db3a2dSMatan Barak 
50532f69e4bSDaniel Jurgens /**
50632f69e4bSDaniel Jurgens  * rdma_roce_rescan_device - Rescan all of the network devices in the system
50732f69e4bSDaniel Jurgens  * and add their gids, as needed, to the relevant RoCE devices.
50832f69e4bSDaniel Jurgens  *
509d71f5fa2SLee Jones  * @ib_dev:         the rdma device
51032f69e4bSDaniel Jurgens  */
rdma_roce_rescan_device(struct ib_device * ib_dev)51132f69e4bSDaniel Jurgens void rdma_roce_rescan_device(struct ib_device *ib_dev)
51203db3a2dSMatan Barak {
51303db3a2dSMatan Barak 	ib_enum_roce_netdev(ib_dev, pass_all_filter, NULL,
51403db3a2dSMatan Barak 			    enum_all_gids_of_dev_cb, NULL);
51503db3a2dSMatan Barak }
51632f69e4bSDaniel Jurgens EXPORT_SYMBOL(rdma_roce_rescan_device);
51703db3a2dSMatan Barak 
callback_for_addr_gid_device_scan(struct ib_device * device,u32 port,struct net_device * rdma_ndev,void * cookie)51803db3a2dSMatan Barak static void callback_for_addr_gid_device_scan(struct ib_device *device,
5191fb7f897SMark Bloch 					      u32 port,
52003db3a2dSMatan Barak 					      struct net_device *rdma_ndev,
52103db3a2dSMatan Barak 					      void *cookie)
52203db3a2dSMatan Barak {
52303db3a2dSMatan Barak 	struct update_gid_event_work *parsed = cookie;
52403db3a2dSMatan Barak 
52503db3a2dSMatan Barak 	return update_gid(parsed->gid_op, device,
52603db3a2dSMatan Barak 			  port, &parsed->gid,
52703db3a2dSMatan Barak 			  &parsed->gid_attr);
52803db3a2dSMatan Barak }
52903db3a2dSMatan Barak 
530453d3932SDavid Ahern struct upper_list {
531453d3932SDavid Ahern 	struct list_head list;
532453d3932SDavid Ahern 	struct net_device *upper;
533453d3932SDavid Ahern };
534453d3932SDavid Ahern 
netdev_upper_walk(struct net_device * upper,struct netdev_nested_priv * priv)535eff74233STaehee Yoo static int netdev_upper_walk(struct net_device *upper,
536eff74233STaehee Yoo 			     struct netdev_nested_priv *priv)
537453d3932SDavid Ahern {
538453d3932SDavid Ahern 	struct upper_list *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
539eff74233STaehee Yoo 	struct list_head *upper_list = (struct list_head *)priv->data;
540453d3932SDavid Ahern 
5414d5b57e0SLinus Torvalds 	if (!entry)
542453d3932SDavid Ahern 		return 0;
543453d3932SDavid Ahern 
544453d3932SDavid Ahern 	list_add_tail(&entry->list, upper_list);
545453d3932SDavid Ahern 	dev_hold(upper);
546453d3932SDavid Ahern 	entry->upper = upper;
547453d3932SDavid Ahern 
548453d3932SDavid Ahern 	return 0;
549453d3932SDavid Ahern }
550453d3932SDavid Ahern 
handle_netdev_upper(struct ib_device * ib_dev,u32 port,void * cookie,void (* handle_netdev)(struct ib_device * ib_dev,u32 port,struct net_device * ndev))5511fb7f897SMark Bloch static void handle_netdev_upper(struct ib_device *ib_dev, u32 port,
552238fdf48SMatan Barak 				void *cookie,
553238fdf48SMatan Barak 				void (*handle_netdev)(struct ib_device *ib_dev,
5541fb7f897SMark Bloch 						      u32 port,
555238fdf48SMatan Barak 						      struct net_device *ndev))
556238fdf48SMatan Barak {
55759039608SParav Pandit 	struct net_device *ndev = cookie;
558eff74233STaehee Yoo 	struct netdev_nested_priv priv;
559238fdf48SMatan Barak 	struct upper_list *upper_iter;
560238fdf48SMatan Barak 	struct upper_list *upper_temp;
561238fdf48SMatan Barak 	LIST_HEAD(upper_list);
562238fdf48SMatan Barak 
563eff74233STaehee Yoo 	priv.data = &upper_list;
564238fdf48SMatan Barak 	rcu_read_lock();
565eff74233STaehee Yoo 	netdev_walk_all_upper_dev_rcu(ndev, netdev_upper_walk, &priv);
566238fdf48SMatan Barak 	rcu_read_unlock();
567238fdf48SMatan Barak 
568238fdf48SMatan Barak 	handle_netdev(ib_dev, port, ndev);
569238fdf48SMatan Barak 	list_for_each_entry_safe(upper_iter, upper_temp, &upper_list,
570238fdf48SMatan Barak 				 list) {
571238fdf48SMatan Barak 		handle_netdev(ib_dev, port, upper_iter->upper);
572238fdf48SMatan Barak 		dev_put(upper_iter->upper);
573238fdf48SMatan Barak 		list_del(&upper_iter->list);
574238fdf48SMatan Barak 		kfree(upper_iter);
575238fdf48SMatan Barak 	}
576238fdf48SMatan Barak }
577238fdf48SMatan Barak 
_roce_del_all_netdev_gids(struct ib_device * ib_dev,u32 port,struct net_device * event_ndev)5781fb7f897SMark Bloch static void _roce_del_all_netdev_gids(struct ib_device *ib_dev, u32 port,
579238fdf48SMatan Barak 				      struct net_device *event_ndev)
580238fdf48SMatan Barak {
581238fdf48SMatan Barak 	ib_cache_gid_del_all_netdev_gids(ib_dev, port, event_ndev);
582238fdf48SMatan Barak }
583238fdf48SMatan Barak 
del_netdev_upper_ips(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)5841fb7f897SMark Bloch static void del_netdev_upper_ips(struct ib_device *ib_dev, u32 port,
585238fdf48SMatan Barak 				 struct net_device *rdma_ndev, void *cookie)
586238fdf48SMatan Barak {
587238fdf48SMatan Barak 	handle_netdev_upper(ib_dev, port, cookie, _roce_del_all_netdev_gids);
588238fdf48SMatan Barak }
589238fdf48SMatan Barak 
add_netdev_upper_ips(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)5901fb7f897SMark Bloch static void add_netdev_upper_ips(struct ib_device *ib_dev, u32 port,
591238fdf48SMatan Barak 				 struct net_device *rdma_ndev, void *cookie)
592238fdf48SMatan Barak {
593238fdf48SMatan Barak 	handle_netdev_upper(ib_dev, port, cookie, _add_netdev_ips);
594238fdf48SMatan Barak }
595238fdf48SMatan Barak 
del_netdev_default_ips_join(struct ib_device * ib_dev,u32 port,struct net_device * rdma_ndev,void * cookie)5961fb7f897SMark Bloch static void del_netdev_default_ips_join(struct ib_device *ib_dev, u32 port,
597238fdf48SMatan Barak 					struct net_device *rdma_ndev,
598238fdf48SMatan Barak 					void *cookie)
599238fdf48SMatan Barak {
600238fdf48SMatan Barak 	struct net_device *master_ndev;
601238fdf48SMatan Barak 
602238fdf48SMatan Barak 	rcu_read_lock();
603238fdf48SMatan Barak 	master_ndev = netdev_master_upper_dev_get_rcu(rdma_ndev);
604238fdf48SMatan Barak 	dev_hold(master_ndev);
605238fdf48SMatan Barak 	rcu_read_unlock();
606238fdf48SMatan Barak 
607238fdf48SMatan Barak 	if (master_ndev) {
608b9f09866SParav Pandit 		bond_delete_netdev_default_gids(ib_dev, port, rdma_ndev,
609b9f09866SParav Pandit 						master_ndev);
610238fdf48SMatan Barak 		dev_put(master_ndev);
611238fdf48SMatan Barak 	}
612238fdf48SMatan Barak }
613238fdf48SMatan Barak 
61403db3a2dSMatan Barak /* The following functions operate on all IB devices. netdevice_event and
61503db3a2dSMatan Barak  * addr_event execute ib_enum_all_roce_netdevs through a work.
61603db3a2dSMatan Barak  * ib_enum_all_roce_netdevs iterates through all IB devices.
61703db3a2dSMatan Barak  */
61803db3a2dSMatan Barak 
netdevice_event_work_handler(struct work_struct * _work)61903db3a2dSMatan Barak static void netdevice_event_work_handler(struct work_struct *_work)
62003db3a2dSMatan Barak {
62103db3a2dSMatan Barak 	struct netdev_event_work *work =
62203db3a2dSMatan Barak 		container_of(_work, struct netdev_event_work, work);
62303db3a2dSMatan Barak 	unsigned int i;
62403db3a2dSMatan Barak 
625238fdf48SMatan Barak 	for (i = 0; i < ARRAY_SIZE(work->cmds) && work->cmds[i].cb; i++) {
626238fdf48SMatan Barak 		ib_enum_all_roce_netdevs(work->cmds[i].filter,
627238fdf48SMatan Barak 					 work->cmds[i].filter_ndev,
628238fdf48SMatan Barak 					 work->cmds[i].cb,
629238fdf48SMatan Barak 					 work->cmds[i].ndev);
630238fdf48SMatan Barak 		dev_put(work->cmds[i].ndev);
631238fdf48SMatan Barak 		dev_put(work->cmds[i].filter_ndev);
632238fdf48SMatan Barak 	}
63303db3a2dSMatan Barak 
63403db3a2dSMatan Barak 	kfree(work);
63503db3a2dSMatan Barak }
63603db3a2dSMatan Barak 
netdevice_queue_work(struct netdev_event_work_cmd * cmds,struct net_device * ndev)63703db3a2dSMatan Barak static int netdevice_queue_work(struct netdev_event_work_cmd *cmds,
63803db3a2dSMatan Barak 				struct net_device *ndev)
63903db3a2dSMatan Barak {
640238fdf48SMatan Barak 	unsigned int i;
64103db3a2dSMatan Barak 	struct netdev_event_work *ndev_work =
64203db3a2dSMatan Barak 		kmalloc(sizeof(*ndev_work), GFP_KERNEL);
64303db3a2dSMatan Barak 
644a0b3455fSLeon Romanovsky 	if (!ndev_work)
64503db3a2dSMatan Barak 		return NOTIFY_DONE;
64603db3a2dSMatan Barak 
64703db3a2dSMatan Barak 	memcpy(ndev_work->cmds, cmds, sizeof(ndev_work->cmds));
648238fdf48SMatan Barak 	for (i = 0; i < ARRAY_SIZE(ndev_work->cmds) && ndev_work->cmds[i].cb; i++) {
649238fdf48SMatan Barak 		if (!ndev_work->cmds[i].ndev)
650238fdf48SMatan Barak 			ndev_work->cmds[i].ndev = ndev;
651238fdf48SMatan Barak 		if (!ndev_work->cmds[i].filter_ndev)
652238fdf48SMatan Barak 			ndev_work->cmds[i].filter_ndev = ndev;
653238fdf48SMatan Barak 		dev_hold(ndev_work->cmds[i].ndev);
654238fdf48SMatan Barak 		dev_hold(ndev_work->cmds[i].filter_ndev);
655238fdf48SMatan Barak 	}
65603db3a2dSMatan Barak 	INIT_WORK(&ndev_work->work, netdevice_event_work_handler);
65703db3a2dSMatan Barak 
6588fe8bacbSMajd Dibbiny 	queue_work(gid_cache_wq, &ndev_work->work);
65903db3a2dSMatan Barak 
66003db3a2dSMatan Barak 	return NOTIFY_DONE;
66103db3a2dSMatan Barak }
66203db3a2dSMatan Barak 
663238fdf48SMatan Barak static const struct netdev_event_work_cmd add_cmd = {
664dd81b2c8SParav Pandit 	.cb	= add_netdev_ips,
665dd81b2c8SParav Pandit 	.filter	= is_eth_port_of_netdev_filter
666dd81b2c8SParav Pandit };
667dd81b2c8SParav Pandit 
668238fdf48SMatan Barak static const struct netdev_event_work_cmd add_cmd_upper_ips = {
669dd81b2c8SParav Pandit 	.cb	= add_netdev_upper_ips,
670dd81b2c8SParav Pandit 	.filter = is_eth_port_of_netdev_filter
671dd81b2c8SParav Pandit };
672238fdf48SMatan Barak 
673666e7099SParav Pandit static void
ndev_event_unlink(struct netdev_notifier_changeupper_info * changeupper_info,struct netdev_event_work_cmd * cmds)674666e7099SParav Pandit ndev_event_unlink(struct netdev_notifier_changeupper_info *changeupper_info,
675238fdf48SMatan Barak 		  struct netdev_event_work_cmd *cmds)
676238fdf48SMatan Barak {
677666e7099SParav Pandit 	static const struct netdev_event_work_cmd
678666e7099SParav Pandit 			upper_ips_del_cmd = {
679666e7099SParav Pandit 				.cb	= del_netdev_upper_ips,
680666e7099SParav Pandit 				.filter	= upper_device_filter
681666e7099SParav Pandit 	};
682238fdf48SMatan Barak 
683238fdf48SMatan Barak 	cmds[0] = upper_ips_del_cmd;
68426d2177eSLinus Torvalds 	cmds[0].ndev = changeupper_info->upper_dev;
685238fdf48SMatan Barak 	cmds[1] = add_cmd;
686666e7099SParav Pandit }
687666e7099SParav Pandit 
688a03d4d27SParav Pandit static const struct netdev_event_work_cmd bonding_default_add_cmd = {
689a03d4d27SParav Pandit 	.cb	= add_default_gids,
690a03d4d27SParav Pandit 	.filter	= is_upper_ndev_bond_master_filter
691a03d4d27SParav Pandit };
692a03d4d27SParav Pandit 
693666e7099SParav Pandit static void
ndev_event_link(struct net_device * event_ndev,struct netdev_notifier_changeupper_info * changeupper_info,struct netdev_event_work_cmd * cmds)694408f1242SParav Pandit ndev_event_link(struct net_device *event_ndev,
695408f1242SParav Pandit 		struct netdev_notifier_changeupper_info *changeupper_info,
696666e7099SParav Pandit 		struct netdev_event_work_cmd *cmds)
697666e7099SParav Pandit {
698666e7099SParav Pandit 	static const struct netdev_event_work_cmd
699666e7099SParav Pandit 			bonding_default_del_cmd = {
700408f1242SParav Pandit 				.cb	= del_default_gids,
701408f1242SParav Pandit 				.filter	= is_upper_ndev_bond_master_filter
702666e7099SParav Pandit 			};
703666e7099SParav Pandit 	/*
704666e7099SParav Pandit 	 * When a lower netdev is linked to its upper bonding
705408f1242SParav Pandit 	 * netdev, delete lower slave netdev's default GIDs.
706666e7099SParav Pandit 	 */
707238fdf48SMatan Barak 	cmds[0] = bonding_default_del_cmd;
708408f1242SParav Pandit 	cmds[0].ndev = event_ndev;
709408f1242SParav Pandit 	cmds[0].filter_ndev = changeupper_info->upper_dev;
710408f1242SParav Pandit 
711a03d4d27SParav Pandit 	/* Now add bonding upper device default GIDs */
712a03d4d27SParav Pandit 	cmds[1] = bonding_default_add_cmd;
71326d2177eSLinus Torvalds 	cmds[1].ndev = changeupper_info->upper_dev;
71426d2177eSLinus Torvalds 	cmds[1].filter_ndev = changeupper_info->upper_dev;
715a03d4d27SParav Pandit 
716a03d4d27SParav Pandit 	/* Now add bonding upper device IP based GIDs */
717a03d4d27SParav Pandit 	cmds[2] = add_cmd_upper_ips;
718a03d4d27SParav Pandit 	cmds[2].ndev = changeupper_info->upper_dev;
719a03d4d27SParav Pandit 	cmds[2].filter_ndev = changeupper_info->upper_dev;
720238fdf48SMatan Barak }
721666e7099SParav Pandit 
netdevice_event_changeupper(struct net_device * event_ndev,struct netdev_notifier_changeupper_info * changeupper_info,struct netdev_event_work_cmd * cmds)722408f1242SParav Pandit static void netdevice_event_changeupper(struct net_device *event_ndev,
723408f1242SParav Pandit 		struct netdev_notifier_changeupper_info *changeupper_info,
724666e7099SParav Pandit 		struct netdev_event_work_cmd *cmds)
725666e7099SParav Pandit {
726666e7099SParav Pandit 	if (changeupper_info->linking)
727408f1242SParav Pandit 		ndev_event_link(event_ndev, changeupper_info, cmds);
728666e7099SParav Pandit 	else
729666e7099SParav Pandit 		ndev_event_unlink(changeupper_info, cmds);
730238fdf48SMatan Barak }
731238fdf48SMatan Barak 
732464b79b4SParav Pandit static const struct netdev_event_work_cmd add_default_gid_cmd = {
733464b79b4SParav Pandit 	.cb	= add_default_gids,
734464b79b4SParav Pandit 	.filter	= is_ndev_for_default_gid_filter,
735464b79b4SParav Pandit };
736464b79b4SParav Pandit 
netdevice_event(struct notifier_block * this,unsigned long event,void * ptr)73703db3a2dSMatan Barak static int netdevice_event(struct notifier_block *this, unsigned long event,
73803db3a2dSMatan Barak 			   void *ptr)
73903db3a2dSMatan Barak {
74003db3a2dSMatan Barak 	static const struct netdev_event_work_cmd del_cmd = {
74103db3a2dSMatan Barak 		.cb = del_netdev_ips, .filter = pass_all_filter};
742dd81b2c8SParav Pandit 	static const struct netdev_event_work_cmd
743dd81b2c8SParav Pandit 			bonding_default_del_cmd_join = {
744dd81b2c8SParav Pandit 				.cb	= del_netdev_default_ips_join,
745dd81b2c8SParav Pandit 				.filter	= is_eth_port_inactive_slave_filter
746dd81b2c8SParav Pandit 			};
747b9f09866SParav Pandit 	static const struct netdev_event_work_cmd
748d12e2eedSParav Pandit 			netdev_del_cmd = {
749d12e2eedSParav Pandit 				.cb	= del_netdev_ips,
750dd81b2c8SParav Pandit 				.filter = is_eth_port_of_netdev_filter
751b9f09866SParav Pandit 			};
752238fdf48SMatan Barak 	static const struct netdev_event_work_cmd bonding_event_ips_del_cmd = {
753238fdf48SMatan Barak 		.cb = del_netdev_upper_ips, .filter = upper_device_filter};
75403db3a2dSMatan Barak 	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
75503db3a2dSMatan Barak 	struct netdev_event_work_cmd cmds[ROCE_NETDEV_CALLBACK_SZ] = { {NULL} };
75603db3a2dSMatan Barak 
75703db3a2dSMatan Barak 	if (ndev->type != ARPHRD_ETHER)
75803db3a2dSMatan Barak 		return NOTIFY_DONE;
75903db3a2dSMatan Barak 
76003db3a2dSMatan Barak 	switch (event) {
76103db3a2dSMatan Barak 	case NETDEV_REGISTER:
76203db3a2dSMatan Barak 	case NETDEV_UP:
763238fdf48SMatan Barak 		cmds[0] = bonding_default_del_cmd_join;
764464b79b4SParav Pandit 		cmds[1] = add_default_gid_cmd;
765464b79b4SParav Pandit 		cmds[2] = add_cmd;
76603db3a2dSMatan Barak 		break;
76703db3a2dSMatan Barak 
76803db3a2dSMatan Barak 	case NETDEV_UNREGISTER:
76903db3a2dSMatan Barak 		if (ndev->reg_state < NETREG_UNREGISTERED)
77003db3a2dSMatan Barak 			cmds[0] = del_cmd;
77103db3a2dSMatan Barak 		else
77203db3a2dSMatan Barak 			return NOTIFY_DONE;
77303db3a2dSMatan Barak 		break;
77403db3a2dSMatan Barak 
77503db3a2dSMatan Barak 	case NETDEV_CHANGEADDR:
776d12e2eedSParav Pandit 		cmds[0] = netdev_del_cmd;
777d52ef88aSParav Pandit 		if (ndev->reg_state == NETREG_REGISTERED) {
778d12e2eedSParav Pandit 			cmds[1] = add_default_gid_cmd;
779d12e2eedSParav Pandit 			cmds[2] = add_cmd;
780d52ef88aSParav Pandit 		}
78103db3a2dSMatan Barak 		break;
782238fdf48SMatan Barak 
783238fdf48SMatan Barak 	case NETDEV_CHANGEUPPER:
784408f1242SParav Pandit 		netdevice_event_changeupper(ndev,
78526d2177eSLinus Torvalds 			container_of(ptr, struct netdev_notifier_changeupper_info, info),
786238fdf48SMatan Barak 			cmds);
787238fdf48SMatan Barak 		break;
788238fdf48SMatan Barak 
789238fdf48SMatan Barak 	case NETDEV_BONDING_FAILOVER:
790238fdf48SMatan Barak 		cmds[0] = bonding_event_ips_del_cmd;
791464b79b4SParav Pandit 		/* Add default GIDs of the bond device */
792464b79b4SParav Pandit 		cmds[1] = bonding_default_add_cmd;
793464b79b4SParav Pandit 		/* Add IP based GIDs of the bond device */
794238fdf48SMatan Barak 		cmds[2] = add_cmd_upper_ips;
795238fdf48SMatan Barak 		break;
796238fdf48SMatan Barak 
79703db3a2dSMatan Barak 	default:
79803db3a2dSMatan Barak 		return NOTIFY_DONE;
79903db3a2dSMatan Barak 	}
80003db3a2dSMatan Barak 
80103db3a2dSMatan Barak 	return netdevice_queue_work(cmds, ndev);
80203db3a2dSMatan Barak }
80303db3a2dSMatan Barak 
update_gid_event_work_handler(struct work_struct * _work)80403db3a2dSMatan Barak static void update_gid_event_work_handler(struct work_struct *_work)
80503db3a2dSMatan Barak {
80603db3a2dSMatan Barak 	struct update_gid_event_work *work =
80703db3a2dSMatan Barak 		container_of(_work, struct update_gid_event_work, work);
80803db3a2dSMatan Barak 
809dd81b2c8SParav Pandit 	ib_enum_all_roce_netdevs(is_eth_port_of_netdev_filter,
810dd81b2c8SParav Pandit 				 work->gid_attr.ndev,
81103db3a2dSMatan Barak 				 callback_for_addr_gid_device_scan, work);
81203db3a2dSMatan Barak 
81303db3a2dSMatan Barak 	dev_put(work->gid_attr.ndev);
81403db3a2dSMatan Barak 	kfree(work);
81503db3a2dSMatan Barak }
81603db3a2dSMatan Barak 
addr_event(struct notifier_block * this,unsigned long event,struct sockaddr * sa,struct net_device * ndev)81703db3a2dSMatan Barak static int addr_event(struct notifier_block *this, unsigned long event,
81803db3a2dSMatan Barak 		      struct sockaddr *sa, struct net_device *ndev)
81903db3a2dSMatan Barak {
82003db3a2dSMatan Barak 	struct update_gid_event_work *work;
82103db3a2dSMatan Barak 	enum gid_op_type gid_op;
82203db3a2dSMatan Barak 
82303db3a2dSMatan Barak 	if (ndev->type != ARPHRD_ETHER)
82403db3a2dSMatan Barak 		return NOTIFY_DONE;
82503db3a2dSMatan Barak 
82603db3a2dSMatan Barak 	switch (event) {
82703db3a2dSMatan Barak 	case NETDEV_UP:
82803db3a2dSMatan Barak 		gid_op = GID_ADD;
82903db3a2dSMatan Barak 		break;
83003db3a2dSMatan Barak 
83103db3a2dSMatan Barak 	case NETDEV_DOWN:
83203db3a2dSMatan Barak 		gid_op = GID_DEL;
83303db3a2dSMatan Barak 		break;
83403db3a2dSMatan Barak 
83503db3a2dSMatan Barak 	default:
83603db3a2dSMatan Barak 		return NOTIFY_DONE;
83703db3a2dSMatan Barak 	}
83803db3a2dSMatan Barak 
83903db3a2dSMatan Barak 	work = kmalloc(sizeof(*work), GFP_ATOMIC);
840a0b3455fSLeon Romanovsky 	if (!work)
84103db3a2dSMatan Barak 		return NOTIFY_DONE;
84203db3a2dSMatan Barak 
84303db3a2dSMatan Barak 	INIT_WORK(&work->work, update_gid_event_work_handler);
84403db3a2dSMatan Barak 
84503db3a2dSMatan Barak 	rdma_ip2gid(sa, &work->gid);
84603db3a2dSMatan Barak 	work->gid_op = gid_op;
84703db3a2dSMatan Barak 
84803db3a2dSMatan Barak 	memset(&work->gid_attr, 0, sizeof(work->gid_attr));
84903db3a2dSMatan Barak 	dev_hold(ndev);
85003db3a2dSMatan Barak 	work->gid_attr.ndev   = ndev;
85103db3a2dSMatan Barak 
8528fe8bacbSMajd Dibbiny 	queue_work(gid_cache_wq, &work->work);
85303db3a2dSMatan Barak 
85403db3a2dSMatan Barak 	return NOTIFY_DONE;
85503db3a2dSMatan Barak }
85603db3a2dSMatan Barak 
inetaddr_event(struct notifier_block * this,unsigned long event,void * ptr)85703db3a2dSMatan Barak static int inetaddr_event(struct notifier_block *this, unsigned long event,
85803db3a2dSMatan Barak 			  void *ptr)
85903db3a2dSMatan Barak {
86003db3a2dSMatan Barak 	struct sockaddr_in	in;
86103db3a2dSMatan Barak 	struct net_device	*ndev;
86203db3a2dSMatan Barak 	struct in_ifaddr	*ifa = ptr;
86303db3a2dSMatan Barak 
86403db3a2dSMatan Barak 	in.sin_family = AF_INET;
86503db3a2dSMatan Barak 	in.sin_addr.s_addr = ifa->ifa_address;
86603db3a2dSMatan Barak 	ndev = ifa->ifa_dev->dev;
86703db3a2dSMatan Barak 
86803db3a2dSMatan Barak 	return addr_event(this, event, (struct sockaddr *)&in, ndev);
86903db3a2dSMatan Barak }
87003db3a2dSMatan Barak 
inet6addr_event(struct notifier_block * this,unsigned long event,void * ptr)87103db3a2dSMatan Barak static int inet6addr_event(struct notifier_block *this, unsigned long event,
87203db3a2dSMatan Barak 			   void *ptr)
87303db3a2dSMatan Barak {
87403db3a2dSMatan Barak 	struct sockaddr_in6	in6;
87503db3a2dSMatan Barak 	struct net_device	*ndev;
87603db3a2dSMatan Barak 	struct inet6_ifaddr	*ifa6 = ptr;
87703db3a2dSMatan Barak 
87803db3a2dSMatan Barak 	in6.sin6_family = AF_INET6;
87903db3a2dSMatan Barak 	in6.sin6_addr = ifa6->addr;
88003db3a2dSMatan Barak 	ndev = ifa6->idev->dev;
88103db3a2dSMatan Barak 
88203db3a2dSMatan Barak 	return addr_event(this, event, (struct sockaddr *)&in6, ndev);
88303db3a2dSMatan Barak }
88403db3a2dSMatan Barak 
88503db3a2dSMatan Barak static struct notifier_block nb_netdevice = {
88603db3a2dSMatan Barak 	.notifier_call = netdevice_event
88703db3a2dSMatan Barak };
88803db3a2dSMatan Barak 
88903db3a2dSMatan Barak static struct notifier_block nb_inetaddr = {
89003db3a2dSMatan Barak 	.notifier_call = inetaddr_event
89103db3a2dSMatan Barak };
89203db3a2dSMatan Barak 
89303db3a2dSMatan Barak static struct notifier_block nb_inet6addr = {
89403db3a2dSMatan Barak 	.notifier_call = inet6addr_event
89503db3a2dSMatan Barak };
89603db3a2dSMatan Barak 
roce_gid_mgmt_init(void)89703db3a2dSMatan Barak int __init roce_gid_mgmt_init(void)
89803db3a2dSMatan Barak {
8998fe8bacbSMajd Dibbiny 	gid_cache_wq = alloc_ordered_workqueue("gid-cache-wq", 0);
9008fe8bacbSMajd Dibbiny 	if (!gid_cache_wq)
9018fe8bacbSMajd Dibbiny 		return -ENOMEM;
9028fe8bacbSMajd Dibbiny 
90303db3a2dSMatan Barak 	register_inetaddr_notifier(&nb_inetaddr);
90403db3a2dSMatan Barak 	if (IS_ENABLED(CONFIG_IPV6))
90503db3a2dSMatan Barak 		register_inet6addr_notifier(&nb_inet6addr);
90603db3a2dSMatan Barak 	/* We relay on the netdevice notifier to enumerate all
90703db3a2dSMatan Barak 	 * existing devices in the system. Register to this notifier
90803db3a2dSMatan Barak 	 * last to make sure we will not miss any IP add/del
90903db3a2dSMatan Barak 	 * callbacks.
91003db3a2dSMatan Barak 	 */
91103db3a2dSMatan Barak 	register_netdevice_notifier(&nb_netdevice);
91203db3a2dSMatan Barak 
91303db3a2dSMatan Barak 	return 0;
91403db3a2dSMatan Barak }
91503db3a2dSMatan Barak 
roce_gid_mgmt_cleanup(void)91603db3a2dSMatan Barak void __exit roce_gid_mgmt_cleanup(void)
91703db3a2dSMatan Barak {
91803db3a2dSMatan Barak 	if (IS_ENABLED(CONFIG_IPV6))
91903db3a2dSMatan Barak 		unregister_inet6addr_notifier(&nb_inet6addr);
92003db3a2dSMatan Barak 	unregister_inetaddr_notifier(&nb_inetaddr);
92103db3a2dSMatan Barak 	unregister_netdevice_notifier(&nb_netdevice);
92203db3a2dSMatan Barak 	/* Ensure all gid deletion tasks complete before we go down,
92303db3a2dSMatan Barak 	 * to avoid any reference to free'd memory. By the time
92403db3a2dSMatan Barak 	 * ib-core is removed, all physical devices have been removed,
92503db3a2dSMatan Barak 	 * so no issue with remaining hardware contexts.
92603db3a2dSMatan Barak 	 */
9278fe8bacbSMajd Dibbiny 	destroy_workqueue(gid_cache_wq);
92803db3a2dSMatan Barak }
929