1/*-
2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
5 * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice unmodified, this list of conditions, and the following
13 *    disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#ifndef	_LINUX_NETDEVICE_H_
30#define	_LINUX_NETDEVICE_H_
31
32#include <linux/types.h>
33
34#include <sys/socket.h>
35
36#include <net/if_types.h>
37#include <net/if.h>
38#include <net/if_var.h>
39#include <net/if_dl.h>
40
41#include <linux/list.h>
42#include <linux/completion.h>
43#include <linux/device.h>
44#include <linux/workqueue.h>
45#include <linux/net.h>
46#include <linux/notifier.h>
47
48#ifdef VIMAGE
49#define	init_net *vnet0
50#else
51#define	init_net *((struct vnet *)0)
52#endif
53
54#define	MAX_ADDR_LEN		20
55
56#define	net_device	ifnet
57
58static inline struct ifnet *
59dev_get_by_index(struct vnet *vnet, int if_index)
60{
61	struct ifnet *retval;
62
63	CURVNET_SET(vnet);
64	retval = ifnet_byindex_ref(if_index);
65	CURVNET_RESTORE();
66
67	return (retval);
68}
69
70#define	dev_hold(d)	if_ref(d)
71#define	dev_put(d)	if_rele(d)
72#define	dev_net(d)	((d)->if_vnet)
73
74#define	net_eq(a,b)	((a) == (b))
75
76#define	netif_running(dev)	!!((dev)->if_drv_flags & IFF_DRV_RUNNING)
77#define	netif_oper_up(dev)	!!((dev)->if_flags & IFF_UP)
78#define	netif_carrier_ok(dev)	netif_running(dev)
79
80static inline void *
81netdev_priv(const struct net_device *dev)
82{
83	return (dev->if_softc);
84}
85
86static inline void
87_handle_ifnet_link_event(void *arg, struct ifnet *ifp, int linkstate)
88{
89	struct notifier_block *nb;
90
91	nb = arg;
92	if (linkstate == LINK_STATE_UP)
93		nb->notifier_call(nb, NETDEV_UP, ifp);
94	else
95		nb->notifier_call(nb, NETDEV_DOWN, ifp);
96}
97
98static inline void
99_handle_ifnet_arrival_event(void *arg, struct ifnet *ifp)
100{
101	struct notifier_block *nb;
102
103	nb = arg;
104	nb->notifier_call(nb, NETDEV_REGISTER, ifp);
105}
106
107static inline void
108_handle_ifnet_departure_event(void *arg, struct ifnet *ifp)
109{
110	struct notifier_block *nb;
111
112	nb = arg;
113	nb->notifier_call(nb, NETDEV_UNREGISTER, ifp);
114}
115
116static inline void
117_handle_iflladdr_event(void *arg, struct ifnet *ifp)
118{
119	struct notifier_block *nb;
120
121	nb = arg;
122	nb->notifier_call(nb, NETDEV_CHANGEADDR, ifp);
123}
124
125static inline void
126_handle_ifaddr_event(void *arg, struct ifnet *ifp)
127{
128	struct notifier_block *nb;
129
130	nb = arg;
131	nb->notifier_call(nb, NETDEV_CHANGEIFADDR, ifp);
132}
133
134static inline int
135register_netdevice_notifier(struct notifier_block *nb)
136{
137
138	nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER(
139	    ifnet_link_event, _handle_ifnet_link_event, nb, 0);
140	nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER(
141	    ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0);
142	nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER(
143	    ifnet_departure_event, _handle_ifnet_departure_event, nb, 0);
144	nb->tags[NETDEV_CHANGEADDR] = EVENTHANDLER_REGISTER(
145	    iflladdr_event, _handle_iflladdr_event, nb, 0);
146
147	return (0);
148}
149
150static inline int
151register_inetaddr_notifier(struct notifier_block *nb)
152{
153
154        nb->tags[NETDEV_CHANGEIFADDR] = EVENTHANDLER_REGISTER(
155            ifaddr_event, _handle_ifaddr_event, nb, 0);
156        return (0);
157}
158
159static inline int
160unregister_netdevice_notifier(struct notifier_block *nb)
161{
162
163        EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]);
164        EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]);
165        EVENTHANDLER_DEREGISTER(ifnet_departure_event,
166	    nb->tags[NETDEV_UNREGISTER]);
167        EVENTHANDLER_DEREGISTER(iflladdr_event,
168            nb->tags[NETDEV_CHANGEADDR]);
169
170	return (0);
171}
172
173static inline int
174unregister_inetaddr_notifier(struct notifier_block *nb)
175{
176
177        EVENTHANDLER_DEREGISTER(ifaddr_event,
178            nb->tags[NETDEV_CHANGEIFADDR]);
179
180        return (0);
181}
182
183
184#define	rtnl_lock()
185#define	rtnl_unlock()
186
187static inline int
188dev_mc_delete(struct net_device *dev, void *addr, int alen, int all)
189{
190	struct sockaddr_dl sdl;
191
192	if (alen > sizeof(sdl.sdl_data))
193		return (-EINVAL);
194	memset(&sdl, 0, sizeof(sdl));
195	sdl.sdl_len = sizeof(sdl);
196	sdl.sdl_family = AF_LINK;
197	sdl.sdl_alen = alen;
198	memcpy(&sdl.sdl_data, addr, alen);
199
200	return -if_delmulti(dev, (struct sockaddr *)&sdl);
201}
202
203static inline int
204dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly)
205{
206	struct sockaddr_dl sdl;
207
208	if (alen > sizeof(sdl.sdl_data))
209		return (-EINVAL);
210	memset(&sdl, 0, sizeof(sdl));
211	sdl.sdl_len = sizeof(sdl);
212	sdl.sdl_family = AF_LINK;
213	sdl.sdl_alen = alen;
214	memcpy(&sdl.sdl_data, addr, alen);
215
216	return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL);
217}
218
219#endif	/* _LINUX_NETDEVICE_H_ */
220