Esempio n. 1
0
/**
 * i40iw_inetaddr_event - system notifier for ipv4 addr events
 * @notfier: not used
 * @event: event for notifier
 * @ptr: if address
 */
int i40iw_inetaddr_event(struct notifier_block *notifier,
			 unsigned long event,
			 void *ptr)
{
	struct in_ifaddr *ifa = ptr;
	struct net_device *event_netdev = ifa->ifa_dev->dev;
	struct net_device *netdev;
	struct net_device *upper_dev;
	struct i40iw_device *iwdev;
	struct i40iw_handler *hdl;
	u32 local_ipaddr;
	u32 action = I40IW_ARP_ADD;

	hdl = i40iw_find_netdev(event_netdev);
	if (!hdl)
		return NOTIFY_DONE;

	iwdev = &hdl->device;
	if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing)
		return NOTIFY_DONE;

	netdev = iwdev->ldev->netdev;
	upper_dev = netdev_master_upper_dev_get(netdev);
	if (netdev != event_netdev)
		return NOTIFY_DONE;

	if (upper_dev) {
		struct in_device *in;

		rcu_read_lock();
		in = __in_dev_get_rcu(upper_dev);
		local_ipaddr = ntohl(in->ifa_list->ifa_address);
		rcu_read_unlock();
	} else {
		local_ipaddr = ntohl(ifa->ifa_address);
	}
	switch (event) {
	case NETDEV_DOWN:
		action = I40IW_ARP_DELETE;
		/* Fall through */
	case NETDEV_UP:
		/* Fall through */
	case NETDEV_CHANGEADDR:
		i40iw_manage_arp_cache(iwdev,
				       netdev->dev_addr,
				       &local_ipaddr,
				       true,
				       action);
		i40iw_if_notify(iwdev, netdev, &local_ipaddr, true,
				(action == I40IW_ARP_ADD) ? true : false);
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}
Esempio n. 2
0
/**
 * i40iw_inet6addr_event - system notifier for ipv6 addr events
 * @notfier: not used
 * @event: event for notifier
 * @ptr: if address
 */
int i40iw_inet6addr_event(struct notifier_block *notifier,
			  unsigned long event,
			  void *ptr)
{
	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
	struct net_device *event_netdev = ifa->idev->dev;
	struct net_device *netdev;
	struct i40iw_device *iwdev;
	struct i40iw_handler *hdl;
	u32 local_ipaddr6[4];
	u32 action = I40IW_ARP_ADD;

	hdl = i40iw_find_netdev(event_netdev);
	if (!hdl)
		return NOTIFY_DONE;

	iwdev = &hdl->device;
	if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing)
		return NOTIFY_DONE;

	netdev = iwdev->ldev->netdev;
	if (netdev != event_netdev)
		return NOTIFY_DONE;

	i40iw_copy_ip_ntohl(local_ipaddr6, ifa->addr.in6_u.u6_addr32);
	switch (event) {
	case NETDEV_DOWN:
		action = I40IW_ARP_DELETE;
		/* Fall through */
	case NETDEV_UP:
		/* Fall through */
	case NETDEV_CHANGEADDR:
		i40iw_manage_arp_cache(iwdev,
				       netdev->dev_addr,
				       local_ipaddr6,
				       false,
				       action);
		i40iw_if_notify(iwdev, netdev, local_ipaddr6, false,
				(action == I40IW_ARP_ADD) ? true : false);
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}
Esempio n. 3
0
/**
 * i40iw_net_event - system notifier for netevents
 * @notfier: not used
 * @event: event for notifier
 * @ptr: neighbor
 */
int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void *ptr)
{
	struct neighbour *neigh = ptr;
	struct i40iw_device *iwdev;
	struct i40iw_handler *iwhdl;
	__be32 *p;
	u32 local_ipaddr[4];

	switch (event) {
	case NETEVENT_NEIGH_UPDATE:
		iwhdl = i40iw_find_netdev((struct net_device *)neigh->dev);
		if (!iwhdl)
			return NOTIFY_DONE;
		iwdev = &iwhdl->device;
		if (iwdev->init_state < IP_ADDR_REGISTERED || iwdev->closing)
			return NOTIFY_DONE;
		p = (__be32 *)neigh->primary_key;
		i40iw_copy_ip_ntohl(local_ipaddr, p);
		if (neigh->nud_state & NUD_VALID) {
			i40iw_manage_arp_cache(iwdev,
					       neigh->ha,
					       local_ipaddr,
					       false,
					       I40IW_ARP_ADD);

		} else {
			i40iw_manage_arp_cache(iwdev,
					       neigh->ha,
					       local_ipaddr,
					       false,
					       I40IW_ARP_DELETE);
		}
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}
Esempio n. 4
0
/**
 * i40iw_netdevice_event - system notifier for netdev events
 * @notfier: not used
 * @event: event for notifier
 * @ptr: netdev
 */
int i40iw_netdevice_event(struct notifier_block *notifier,
			  unsigned long event,
			  void *ptr)
{
	struct net_device *event_netdev;
	struct net_device *netdev;
	struct i40iw_device *iwdev;
	struct i40iw_handler *hdl;

	event_netdev = netdev_notifier_info_to_dev(ptr);

	hdl = i40iw_find_netdev(event_netdev);
	if (!hdl)
		return NOTIFY_DONE;

	iwdev = &hdl->device;
	if (iwdev->init_state < RDMA_DEV_REGISTERED || iwdev->closing)
		return NOTIFY_DONE;

	netdev = iwdev->ldev->netdev;
	if (netdev != event_netdev)
		return NOTIFY_DONE;

	iwdev->iw_status = 1;

	switch (event) {
	case NETDEV_DOWN:
		iwdev->iw_status = 0;
		/* Fall through */
	case NETDEV_UP:
		i40iw_port_ibevent(iwdev);
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}