if: Multiple TX queue support step 3 of 3; map CPUID to subqueue
[dragonfly.git] / sys / net / if_var.h
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1982, 1986, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * From: @(#)if.h 8.1 (Berkeley) 6/10/93
34 * $FreeBSD: src/sys/net/if_var.h,v 1.18.2.16 2003/04/15 18:11:19 fjoe Exp $
35 */
36
37#ifndef _NET_IF_VAR_H_
38#define _NET_IF_VAR_H_
39
78195a76
MD
40#ifndef _SYS_SERIALIZE_H_
41#include <sys/serialize.h>
42#endif
1bd40720
MD
43#ifndef _NET_IF_H_
44#include <net/if.h>
45#endif
9683f229
MD
46#ifndef _SYS_MUTEX_H_
47#include <sys/mutex.h>
48#endif
78195a76 49
984263bc
MD
50/*
51 * Structures defining a network interface, providing a packet
52 * transport mechanism (ala level 0 of the PUP protocols).
53 *
54 * Each interface accepts output datagrams of a specified maximum
55 * length, and provides higher level routines with input datagrams
56 * received from its medium.
57 *
78195a76
MD
58 * Output occurs when the routine if_output is called, with four parameters:
59 * ifp->if_output(ifp, m, dst, rt)
984263bc
MD
60 * Here m is the mbuf chain to be sent and dst is the destination address.
61 * The output routine encapsulates the supplied datagram if necessary,
62 * and then transmits it on its medium.
63 *
64 * On input, each interface unwraps the data received by it, and either
65 * places it on the input queue of a internetwork datagram routine
3013ac0e
JS
66 * and posts the associated software interrupt, or passes the datagram to
67 * the routine if_input. It is called with the mbuf chain as parameter:
78195a76 68 * ifp->if_input(ifp, m)
3013ac0e 69 * The input routine removes the protocol dependent header if necessary.
984263bc
MD
70 *
71 * Routines exist for locating interfaces by their addresses
72 * or for locating a interface on a certain network, as well as more general
73 * routing and gateway routines maintaining information used to locate
74 * interfaces. These routines live in the files if.c and route.c
75 */
76
984263bc
MD
77/*
78 * Forward structure declarations for function prototypes [sic].
79 */
80struct mbuf;
81struct proc;
82struct rtentry;
83struct rt_addrinfo;
84struct socket;
85struct ether_header;
bd4539cc 86struct ucred;
78195a76 87struct lwkt_serialize;
b2632176
SZ
88struct ifaddr_container;
89struct ifaddr;
90struct lwkt_port;
fb908635 91struct lwkt_msg;
002c1265 92union netmsg;
2eb0d069 93struct pktinfo;
b3a7093f 94struct ifpoll_info;
984263bc
MD
95
96#include <sys/queue.h> /* get TAILQ macros */
97
4d723e5a
JS
98#include <net/altq/if_altq.h>
99
984263bc 100#ifdef _KERNEL
f2bd8b67 101#include <sys/eventhandler.h>
984263bc
MD
102#include <sys/mbuf.h>
103#include <sys/systm.h> /* XXX */
4986965b 104#include <sys/thread2.h>
984263bc
MD
105#endif /* _KERNEL */
106
1550dfd9
MD
107#define IF_DUNIT_NONE -1
108
984263bc 109TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */
b2632176 110TAILQ_HEAD(ifaddrhead, ifaddr_container); /* instantiation is preserved in the list */
984263bc 111TAILQ_HEAD(ifprefixhead, ifprefix);
441d34b2 112TAILQ_HEAD(ifmultihead, ifmultiaddr);
984263bc
MD
113
114/*
115 * Structure defining a queue for a network interface.
116 */
117struct ifqueue {
118 struct mbuf *ifq_head;
119 struct mbuf *ifq_tail;
120 int ifq_len;
121 int ifq_maxlen;
122 int ifq_drops;
123};
124
2b71c8f1 125/*
9b4bf5e3
SZ
126 * Note of IFPOLL_ENABLE
127 * 1) Any file(*.c) that depends on IFPOLL_ENABLE supports in this
128 * file should include opt_ifpoll.h at its beginning.
129 * 2) When struct changes, which are conditioned by IFPOLL_ENABLE,
2b71c8f1 130 * are to be introduced, please keep the struct's size and layout
9b4bf5e3
SZ
131 * same, no matter whether IFPOLL_ENABLE is defined or not.
132 * See ifnet.if_npoll and ifnet.if_npoll_unused for example.
2b71c8f1
SZ
133 */
134
a3dd34d2
SZ
135enum ifnet_serialize {
136 IFNET_SERIALIZE_ALL,
aabfe6fb 137 IFNET_SERIALIZE_MAIN,
a3dd34d2
SZ
138 IFNET_SERIALIZE_TX_BASE = 0x10000000,
139 IFNET_SERIALIZE_RX_BASE = 0x20000000
140};
3c4cd924 141#define IFNET_SERIALIZE_TX(i) (IFNET_SERIALIZE_TX_BASE + (i))
067b3d6b 142#define IFNET_SERIALIZE_RX(i) (IFNET_SERIALIZE_RX_BASE + (i))
a3dd34d2 143
1afbcbac
MD
144#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
145
984263bc
MD
146/*
147 * Structure defining a network interface.
148 *
149 * (Would like to call this struct ``if'', but C isn't PL/1.)
150 */
151
152/*
153 * NB: For FreeBSD, it is assumed that each NIC driver's softc starts with
154 * one of these structures, typically held within an arpcom structure.
155 *
156 * struct <foo>_softc {
157 * struct arpcom {
158 * struct ifnet ac_if;
159 * ...
160 * } <arpcom> ;
161 * ...
162 * };
163 *
164 * The assumption is used in a number of places, including many
165 * files in sys/net, device drivers, and sys/dev/mii.c:miibus_attach().
166 *
167 * Unfortunately devices' softc are opaque, so we depend on this layout
168 * to locate the struct ifnet from the softc in the generic code.
169 *
78195a76
MD
170 * MPSAFE NOTES:
171 *
a3dd34d2
SZ
172 * ifnet is protected by calling if_serialize, if_tryserialize and
173 * if_deserialize serialize functions with the ifnet_serialize parameter.
174 * ifnet.if_snd is protected by its own spinlock. Callers of if_ioctl,
175 * if_watchdog, if_init, if_resolvemulti, and if_poll should call the
176 * ifnet serialize functions with IFNET_SERIALIZE_ALL. Callers of if_start
177 * sould call the ifnet serialize functions with IFNET_SERIALIZE_TX.
178 *
179 * FIXME: Device drivers usually use the same serializer for their interrupt
180 * FIXME: but this is not required.
181 *
182 * Caller of if_output must not serialize ifnet by calling ifnet serialize
183 * functions; if_output will call the ifnet serialize functions based on
bb16d5d2
SZ
184 * its own needs. Caller of if_input does not necessarily hold the related
185 * serializer.
78195a76
MD
186 *
187 * If a device driver installs the same serializer for its interrupt
188 * as for ifnet, then the driver only really needs to worry about further
189 * serialization in timeout based entry points. All other entry points
190 * will already be serialized. Older ISA drivers still using the old
191 * interrupt infrastructure will have to obtain and release the serializer
192 * in their interrupt routine themselves.
984263bc
MD
193 */
194struct ifnet {
195 void *if_softc; /* pointer to driver state */
30809119 196 void *if_l2com; /* pointer to protocol bits */
f23061d4 197 TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */
1550dfd9 198 char if_xname[IFNAMSIZ]; /* external name (name + unit) */
3e4a09e7
MD
199 const char *if_dname; /* driver name */
200 int if_dunit; /* unit or IF_DUNIT_NONE */
9433ab01 201 void *if_vlantrunks; /* vlan trunks */
e71d70c2 202 struct ifaddrhead *if_addrheads; /* array[NCPU] of TAILQs of addresses per if */
984263bc 203 int if_pcount; /* number of promiscuous listeners */
5bd4422e 204 void *if_carp; /* carp interfaces */
984263bc
MD
205 struct bpf_if *if_bpf; /* packet filter structure */
206 u_short if_index; /* numeric abbreviation for this if */
984263bc 207 short if_timer; /* time 'til if_watchdog called */
3e4a09e7 208 int if_flags; /* up/down, broadcast, etc. */
34b4b6a2
JS
209 int if_capabilities; /* interface capabilities */
210 int if_capenable; /* enabled features */
984263bc
MD
211 void *if_linkmib; /* link-type-specific MIB data */
212 size_t if_linkmiblen; /* length of above data */
213 struct if_data if_data;
214 struct ifmultihead if_multiaddrs; /* multicast addresses configured */
215 int if_amcount; /* number of all-multicast requests */
216/* procedure handles */
217 int (*if_output) /* output routine (enqueue) */
218 (struct ifnet *, struct mbuf *, struct sockaddr *,
219 struct rtentry *);
3013ac0e
JS
220 void (*if_input) /* input routine from hardware driver */
221 (struct ifnet *, struct mbuf *);
984263bc 222 void (*if_start) /* initiate output routine */
f0a26983 223 (struct ifnet *, struct ifaltq_subque *);
984263bc 224 int (*if_ioctl) /* ioctl routine */
bd4539cc 225 (struct ifnet *, u_long, caddr_t, struct ucred *);
984263bc
MD
226 void (*if_watchdog) /* timer routine */
227 (struct ifnet *);
984263bc
MD
228 void (*if_init) /* Init routine */
229 (void *);
230 int (*if_resolvemulti) /* validate/resolve multicast */
231 (struct ifnet *, struct sockaddr **, struct sockaddr *);
dfd3b18b 232 void *if_unused5;
70224baa 233 TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
2cc2f639
SZ
234 int (*if_mapsubq)
235 (struct ifaltq *, int);
9b4bf5e3 236 int if_unused2;
a3dd34d2
SZ
237 void (*if_serialize)
238 (struct ifnet *, enum ifnet_serialize);
239 void (*if_deserialize)
240 (struct ifnet *, enum ifnet_serialize);
241 int (*if_tryserialize)
242 (struct ifnet *, enum ifnet_serialize);
2c9effcf
SZ
243#ifdef INVARIANTS
244 void (*if_serialize_assert)
245 (struct ifnet *, enum ifnet_serialize, boolean_t);
246#else
4aa0b844 247 /* Place holder */
2c9effcf
SZ
248 void (*if_serialize_unused)(void);
249#endif
b3a7093f 250#ifdef IFPOLL_ENABLE
f994de37 251 void (*if_npoll)
b3a7093f
SZ
252 (struct ifnet *, struct ifpoll_info *);
253#else
4aa0b844 254 /* Place holder */
f994de37 255 void (*if_npoll_unused)(void);
b3a7093f 256#endif
dfd3b18b 257 int if_unused3;
4d723e5a 258 struct ifaltq if_snd; /* output queue (includes altq) */
984263bc 259 struct ifprefixhead if_prefixhead; /* list of prefixes per if */
c401f0fd 260 const uint8_t *if_broadcastaddr;
db37145f 261 void *if_bridge; /* bridge glue */
698ac46c 262 void *if_afdata[AF_MAX];
141697b6 263 struct ifaddr *if_lladdr;
78195a76
MD
264 struct lwkt_serialize *if_serializer; /* serializer or MP lock */
265 struct lwkt_serialize if_default_serializer; /* if not supplied */
9683f229 266 struct mtx if_ioctl_mtx; /* high-level ioctl serializing mutex */
dfd3b18b 267 int if_unused4;
4aa0b844 268 void *if_unused6;
70224baa 269 void *if_pf_kif; /* pf interface abstraction */
4aa0b844 270 void *if_unused7;
984263bc
MD
271};
272typedef void if_init_f_t (void *);
273
984263bc
MD
274#define if_mtu if_data.ifi_mtu
275#define if_type if_data.ifi_type
276#define if_physical if_data.ifi_physical
277#define if_addrlen if_data.ifi_addrlen
278#define if_hdrlen if_data.ifi_hdrlen
279#define if_metric if_data.ifi_metric
6de83abe 280#define if_link_state if_data.ifi_link_state
984263bc
MD
281#define if_baudrate if_data.ifi_baudrate
282#define if_hwassist if_data.ifi_hwassist
283#define if_ipackets if_data.ifi_ipackets
284#define if_ierrors if_data.ifi_ierrors
285#define if_opackets if_data.ifi_opackets
286#define if_oerrors if_data.ifi_oerrors
287#define if_collisions if_data.ifi_collisions
288#define if_ibytes if_data.ifi_ibytes
289#define if_obytes if_data.ifi_obytes
290#define if_imcasts if_data.ifi_imcasts
291#define if_omcasts if_data.ifi_omcasts
292#define if_iqdrops if_data.ifi_iqdrops
293#define if_noproto if_data.ifi_noproto
294#define if_lastchange if_data.ifi_lastchange
295#define if_recvquota if_data.ifi_recvquota
296#define if_xmitquota if_data.ifi_xmitquota
60233e58 297#define if_rawoutput(if, m, sa) if_output(if, m, sa, NULL)
984263bc
MD
298
299/* for compatibility with other BSDs */
984263bc
MD
300#define if_list if_link
301
1afbcbac 302#endif
b2632176 303
984263bc 304/*
27282cbb
SZ
305 * Device private output queues and input queues are queues of messages
306 * stored on ifqueue structures (defined above). Entries are added to
307 * and deleted from these structures by these macros.
984263bc
MD
308 */
309#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
310#define IF_DROP(ifq) ((ifq)->ifq_drops++)
8e22f1e8 311#define IF_QLEN(ifq) ((ifq)->ifq_len)
fd81ccf9 312#define IF_QEMPTY(ifq) (IF_QLEN(ifq) == 0)
1afbcbac 313
501ade14 314#define IF_ENQUEUE(ifq, m) do { \
716a081c
SW
315 (m)->m_nextpkt = NULL; \
316 if ((ifq)->ifq_tail == NULL) \
501ade14
HT
317 (ifq)->ifq_head = m; \
318 else \
319 (ifq)->ifq_tail->m_nextpkt = m; \
320 (ifq)->ifq_tail = m; \
321 (ifq)->ifq_len++; \
322} while (0)
1afbcbac 323
501ade14
HT
324#define IF_PREPEND(ifq, m) do { \
325 (m)->m_nextpkt = (ifq)->ifq_head; \
716a081c 326 if ((ifq)->ifq_tail == NULL) \
501ade14
HT
327 (ifq)->ifq_tail = (m); \
328 (ifq)->ifq_head = (m); \
329 (ifq)->ifq_len++; \
330} while (0)
1afbcbac 331
501ade14
HT
332#define IF_DEQUEUE(ifq, m) do { \
333 (m) = (ifq)->ifq_head; \
334 if (m) { \
716a081c
SW
335 if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \
336 (ifq)->ifq_tail = NULL; \
337 (m)->m_nextpkt = NULL; \
501ade14
HT
338 (ifq)->ifq_len--; \
339 } \
340} while (0)
8e22f1e8
JS
341
342#define IF_POLL(ifq, m) ((m) = (ifq)->ifq_head)
343
8bde602d
JH
344#define IF_DRAIN(ifq) do { \
345 struct mbuf *m; \
346 while (1) { \
347 IF_DEQUEUE(ifq, m); \
348 if (m == NULL) \
349 break; \
350 m_freem(m); \
351 } \
352} while (0)
984263bc
MD
353
354#ifdef _KERNEL
355
19f10c78
RP
356/* interface link layer address change event */
357typedef void (*iflladdr_event_handler_t)(void *, struct ifnet *);
358EVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
359
2c9effcf
SZ
360#ifdef INVARIANTS
361#define ASSERT_IFNET_SERIALIZED_ALL(ifp) \
362 (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_ALL, TRUE)
363#define ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp) \
364 (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_ALL, FALSE)
365
3c4cd924
SZ
366#define ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq) \
367 (ifp)->if_serialize_assert((ifp), \
368 IFNET_SERIALIZE_TX((ifsq)->ifsq_index), TRUE)
369#define ASSERT_IFNET_NOT_SERIALIZED_TX(ifp, ifsq) \
370 (ifp)->if_serialize_assert((ifp), \
371 IFNET_SERIALIZE_TX((ifsq)->ifsq_index), FALSE)
aabfe6fb
SZ
372
373#define ASSERT_IFNET_SERIALIZED_MAIN(ifp) \
374 (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_MAIN, TRUE)
375#define ASSERT_IFNET_NOT_SERIALIZED_MAIN(ifp) \
376 (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_MAIN, FALSE)
2c9effcf
SZ
377#else
378#define ASSERT_IFNET_SERIALIZED_ALL(ifp) ((void)0)
379#define ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp) ((void)0)
3c4cd924
SZ
380#define ASSERT_IFNET_SERIALIZED_TX(ifp, ifsq) ((void)0)
381#define ASSERT_IFNET_NOT_SERIALIZED_TX(ifp, ifsq) ((void)0)
aabfe6fb
SZ
382#define ASSERT_IFNET_SERIALIZED_MAIN(ifp) ((void)0)
383#define ASSERT_IFNET_NOT_SERIALIZED_MAIN(ifp) ((void)0)
2c9effcf
SZ
384#endif
385
a3dd34d2
SZ
386static __inline void
387ifnet_serialize_all(struct ifnet *_ifp)
388{
389 _ifp->if_serialize(_ifp, IFNET_SERIALIZE_ALL);
390}
391
392static __inline void
393ifnet_deserialize_all(struct ifnet *_ifp)
394{
395 _ifp->if_deserialize(_ifp, IFNET_SERIALIZE_ALL);
396}
397
398static __inline int
399ifnet_tryserialize_all(struct ifnet *_ifp)
400{
401 return _ifp->if_tryserialize(_ifp, IFNET_SERIALIZE_ALL);
402}
403
404static __inline void
3c4cd924 405ifnet_serialize_tx(struct ifnet *_ifp, const struct ifaltq_subque *_ifsq)
a3dd34d2 406{
3c4cd924 407 _ifp->if_serialize(_ifp, IFNET_SERIALIZE_TX(_ifsq->ifsq_index));
a3dd34d2
SZ
408}
409
410static __inline void
3c4cd924 411ifnet_deserialize_tx(struct ifnet *_ifp, const struct ifaltq_subque *_ifsq)
a3dd34d2 412{
3c4cd924 413 _ifp->if_deserialize(_ifp, IFNET_SERIALIZE_TX(_ifsq->ifsq_index));
a3dd34d2
SZ
414}
415
416static __inline int
3c4cd924 417ifnet_tryserialize_tx(struct ifnet *_ifp, const struct ifaltq_subque *_ifsq)
a3dd34d2 418{
3c4cd924
SZ
419 return _ifp->if_tryserialize(_ifp,
420 IFNET_SERIALIZE_TX(_ifsq->ifsq_index));
a3dd34d2
SZ
421}
422
aabfe6fb
SZ
423static __inline void
424ifnet_serialize_main(struct ifnet *_ifp)
425{
426 _ifp->if_serialize(_ifp, IFNET_SERIALIZE_MAIN);
427}
428
429static __inline void
430ifnet_deserialize_main(struct ifnet *_ifp)
431{
432 _ifp->if_deserialize(_ifp, IFNET_SERIALIZE_MAIN);
433}
434
435static __inline int
436ifnet_tryserialize_main(struct ifnet *_ifp)
437{
438 return _ifp->if_tryserialize(_ifp, IFNET_SERIALIZE_MAIN);
439}
440
78195a76 441/*
984263bc
MD
442 * 72 was chosen below because it is the size of a TCP/IP
443 * header (40) + the minimum mss (32).
444 */
445#define IF_MINMTU 72
446#define IF_MAXMTU 65535
447
448#endif /* _KERNEL */
449
1b562c24
SZ
450struct in_ifaddr;
451
452struct in_ifaddr_container {
453 struct in_ifaddr *ia;
454 LIST_ENTRY(in_ifaddr_container) ia_hash;
455 /* entry in bucket of inet addresses */
456 TAILQ_ENTRY(in_ifaddr_container) ia_link;
457 /* list of internet addresses */
458 struct ifaddr_container *ia_ifac; /* parent ifaddr_container */
459};
460
b2632176
SZ
461struct ifaddr_container {
462#define IFA_CONTAINER_MAGIC 0x19810219
463#define IFA_CONTAINER_DEAD 0xc0dedead
464 uint32_t ifa_magic; /* IFA_CONTAINER_MAGIC */
465 struct ifaddr *ifa;
466 TAILQ_ENTRY(ifaddr_container) ifa_link; /* queue macro glue */
467 u_int ifa_refcnt; /* references to this structure */
5bd4422e
SZ
468 uint16_t ifa_listmask; /* IFA_LIST_ */
469 uint16_t ifa_prflags; /* protocol specific flags */
1b562c24
SZ
470
471 /*
472 * Protocol specific states
473 */
474 union {
475 struct in_ifaddr_container u_in_ifac;
476 } ifa_proto_u;
b2632176
SZ
477};
478
5bd4422e
SZ
479#define IFA_LIST_IFADDRHEAD 0x01 /* on ifnet.if_addrheads[cpuid] */
480#define IFA_LIST_IN_IFADDRHEAD 0x02 /* on in_ifaddrheads[cpuid] */
481#define IFA_LIST_IN_IFADDRHASH 0x04 /* on in_ifaddrhashtbls[cpuid] */
482
483#define IFA_PRF_FLAG0 0x01
484#define IFA_PRF_FLAG1 0x02
485#define IFA_PRF_FLAG2 0x04
486#define IFA_PRF_FLAG3 0x08
40f667f2 487
984263bc
MD
488/*
489 * The ifaddr structure contains information about one address
490 * of an interface. They are maintained by the different address families,
491 * are allocated and attached when an address is set, and are linked
492 * together so all addresses for an interface can be located.
493 */
494struct ifaddr {
495 struct sockaddr *ifa_addr; /* address of interface */
496 struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
497#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
498 struct sockaddr *ifa_netmask; /* used to determine subnet */
499 struct if_data if_data; /* not all members are meaningful */
500 struct ifnet *ifa_ifp; /* back-pointer to interface */
b2632176
SZ
501 void *ifa_link_pad;
502 struct ifaddr_container *ifa_containers;
984263bc
MD
503 void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */
504 (int, struct rtentry *, struct rt_addrinfo *);
505 u_short ifa_flags; /* mostly rt_flags for cloning */
d5a2b87c 506 int ifa_ncnt; /* # of valid ifaddr_container */
984263bc
MD
507 int ifa_metric; /* cost of going out this interface */
508#ifdef notdef
509 struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */
510#endif
511 int (*ifa_claim_addr) /* check if an addr goes to this if */
512 (struct ifaddr *, struct sockaddr *);
513
514};
515#define IFA_ROUTE RTF_UP /* route installed */
516
517/* for compatibility with other BSDs */
518#define ifa_list ifa_link
519
520/*
521 * The prefix structure contains information about one prefix
522 * of an interface. They are maintained by the different address families,
523 * are allocated and attached when an prefix or an address is set,
524 * and are linked together so all prefixes for an interface can be located.
525 */
526struct ifprefix {
527 struct sockaddr *ifpr_prefix; /* prefix of interface */
528 struct ifnet *ifpr_ifp; /* back-pointer to interface */
529 TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
530 u_char ifpr_plen; /* prefix length in bits */
531 u_char ifpr_type; /* protocol dependent prefix type */
532};
533
534/*
535 * Multicast address structure. This is analogous to the ifaddr
536 * structure except that it keeps track of multicast addresses.
537 * Also, the reference count here is a count of requests for this
538 * address, not a count of pointers to this structure.
539 */
540struct ifmultiaddr {
441d34b2 541 TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
f23061d4 542 struct sockaddr *ifma_addr; /* address this membership is for */
984263bc
MD
543 struct sockaddr *ifma_lladdr; /* link-layer translation, if any */
544 struct ifnet *ifma_ifp; /* back-pointer to interface */
545 u_int ifma_refcount; /* reference count */
546 void *ifma_protospec; /* protocol-specific state, if any */
547};
548
549#ifdef _KERNEL
5bd4422e 550
c2e1bb63
SZ
551#ifndef _SYS_SERIALIZE2_H_
552#include <sys/serialize2.h>
553#endif
554
5bd4422e
SZ
555enum ifaddr_event {
556 IFADDR_EVENT_ADD,
557 IFADDR_EVENT_DELETE,
558 IFADDR_EVENT_CHANGE
559};
560
f2bd8b67 561/* interface address change event */
5bd4422e
SZ
562typedef void (*ifaddr_event_handler_t)(void *, struct ifnet *,
563 enum ifaddr_event, struct ifaddr *);
f2bd8b67
JS
564EVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
565/* new interface attach event */
566typedef void (*ifnet_attach_event_handler_t)(void *, struct ifnet *);
567EVENTHANDLER_DECLARE(ifnet_attach_event, ifnet_attach_event_handler_t);
568/* interface detach event */
569typedef void (*ifnet_detach_event_handler_t)(void *, struct ifnet *);
570EVENTHANDLER_DECLARE(ifnet_detach_event, ifnet_detach_event_handler_t);
f2bd8b67 571
70224baa
JL
572/*
573 * interface groups
574 */
575struct ifg_group {
576 char ifg_group[IFNAMSIZ];
577 u_int ifg_refcnt;
578 void *ifg_pf_kif;
315a7da3 579 int ifg_carp_demoted;
70224baa
JL
580 TAILQ_HEAD(, ifg_member) ifg_members;
581 TAILQ_ENTRY(ifg_group) ifg_next;
582};
583
584struct ifg_member {
585 TAILQ_ENTRY(ifg_member) ifgm_next;
586 struct ifnet *ifgm_ifp;
587};
588
589struct ifg_list {
590 struct ifg_group *ifgl_group;
591 TAILQ_ENTRY(ifg_list) ifgl_next;
592};
593
594/* group attach event */
595typedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
596EVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
597/* group detach event */
598typedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
599EVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
600/* group change event */
601typedef void (*group_change_event_handler_t)(void *, const char *);
602EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
603
604
09ff6081
SZ
605#ifdef INVARIANTS
606#define ASSERT_IFAC_VALID(ifac) do { \
607 KKASSERT((ifac)->ifa_magic == IFA_CONTAINER_MAGIC); \
608 KKASSERT((ifac)->ifa_refcnt > 0); \
609} while (0)
610#else
611#define ASSERT_IFAC_VALID(ifac) ((void)0)
612#endif
613
f23061d4 614static __inline void
b2632176
SZ
615_IFAREF(struct ifaddr *_ifa, int _cpu_id)
616{
617 struct ifaddr_container *_ifac = &_ifa->ifa_containers[_cpu_id];
618
619 crit_enter();
09ff6081 620 ASSERT_IFAC_VALID(_ifac);
b2632176
SZ
621 ++_ifac->ifa_refcnt;
622 crit_exit();
623}
624
625static __inline void
235f6526 626IFAREF(struct ifaddr *_ifa)
f23061d4 627{
b2632176 628 _IFAREF(_ifa, mycpuid);
f23061d4
JH
629}
630
631#include <sys/malloc.h>
632
633MALLOC_DECLARE(M_IFADDR);
634MALLOC_DECLARE(M_IFMADDR);
cb80735c 635MALLOC_DECLARE(M_IFNET);
f23061d4 636
b2632176
SZ
637void ifac_free(struct ifaddr_container *, int);
638
639static __inline void
640_IFAFREE(struct ifaddr *_ifa, int _cpu_id)
641{
642 struct ifaddr_container *_ifac = &_ifa->ifa_containers[_cpu_id];
643
644 crit_enter();
09ff6081 645 ASSERT_IFAC_VALID(_ifac);
b2632176
SZ
646 if (--_ifac->ifa_refcnt == 0)
647 ifac_free(_ifac, _cpu_id);
648 crit_exit();
649}
650
f23061d4 651static __inline void
235f6526 652IFAFREE(struct ifaddr *_ifa)
f23061d4 653{
b2632176 654 _IFAFREE(_ifa, mycpuid);
f23061d4 655}
984263bc 656
d7944f0b 657struct lwkt_port *ifnet_portfn(int);
2a3e1dbd 658int ifnet_domsg(struct lwkt_msg *, int);
8967ddc7 659void ifnet_sendmsg(struct lwkt_msg *, int);
c4882b7e 660void ifnet_forwardmsg(struct lwkt_msg *, int);
bd08b792 661struct ifnet *ifnet_byindex(unsigned short);
d7944f0b 662
2a3e1dbd 663static __inline int
c4882b7e
SZ
664ifa_domsg(struct lwkt_msg *_lmsg, int _cpu)
665{
2a3e1dbd 666 return ifnet_domsg(_lmsg, _cpu);
c4882b7e
SZ
667}
668
669static __inline void
8967ddc7
SZ
670ifa_sendmsg(struct lwkt_msg *_lmsg, int _cpu)
671{
672 ifnet_sendmsg(_lmsg, _cpu);
673}
674
675static __inline void
c4882b7e 676ifa_forwardmsg(struct lwkt_msg *_lmsg, int _nextcpu)
d7944f0b 677{
c4882b7e 678 ifnet_forwardmsg(_lmsg, _nextcpu);
d7944f0b
SZ
679}
680
c2e1bb63
SZ
681static __inline int
682ifnet_serialize_array_index(int _arrcnt, int _txoff, int _rxoff,
683 enum ifnet_serialize _slz)
684{
685 int _off;
686
687 if (_slz == IFNET_SERIALIZE_MAIN) {
688 _off = 0;
689 } else if (_slz & IFNET_SERIALIZE_TX_BASE) {
690 _off = (_slz & ~IFNET_SERIALIZE_TX_BASE) + _txoff;
691 KASSERT(_off < _arrcnt,
692 ("invalid TX serializer %#x", _slz));
693 } else if (_slz & IFNET_SERIALIZE_RX_BASE) {
694 _off = (_slz & ~IFNET_SERIALIZE_RX_BASE) + _rxoff;
695 KASSERT(_off < _arrcnt,
696 ("invalid RX serializer %#x", _slz));
697 } else {
698 panic("unknown serializer %#x", _slz);
699 }
700 return _off;
701}
702
703static __inline void
704ifnet_serialize_array_enter(lwkt_serialize_t *_arr, int _arrcnt,
705 int _txoff, int _rxoff, enum ifnet_serialize _slz)
706{
707 int _off;
708
709 if (_slz == IFNET_SERIALIZE_ALL) {
710 lwkt_serialize_array_enter(_arr, _arrcnt, 0);
711 return;
712 }
713
714 _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
715 lwkt_serialize_enter(_arr[_off]);
716}
717
718static __inline void
719ifnet_serialize_array_exit(lwkt_serialize_t *_arr, int _arrcnt,
720 int _txoff, int _rxoff, enum ifnet_serialize _slz)
721{
722 int _off;
723
724 if (_slz == IFNET_SERIALIZE_ALL) {
725 lwkt_serialize_array_exit(_arr, _arrcnt, 0);
726 return;
727 }
728
729 _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
730 lwkt_serialize_exit(_arr[_off]);
731}
732
733static __inline int
734ifnet_serialize_array_try(lwkt_serialize_t *_arr, int _arrcnt,
735 int _txoff, int _rxoff, enum ifnet_serialize _slz)
736{
737 int _off;
738
739 if (_slz == IFNET_SERIALIZE_ALL)
740 return lwkt_serialize_array_try(_arr, _arrcnt, 0);
741
742 _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
743 return lwkt_serialize_try(_arr[_off]);
744}
745
746#ifdef INVARIANTS
747
748static __inline void
749ifnet_serialize_array_assert(lwkt_serialize_t *_arr, int _arrcnt,
750 int _txoff, int _rxoff, enum ifnet_serialize _slz, boolean_t _serialized)
751{
752 int _off;
753
754 if (_slz == IFNET_SERIALIZE_ALL) {
755 int _i;
756
757 if (_serialized) {
758 for (_i = 0; _i < _arrcnt; ++_i)
759 ASSERT_SERIALIZED(_arr[_i]);
760 } else {
761 for (_i = 0; _i < _arrcnt; ++_i)
762 ASSERT_NOT_SERIALIZED(_arr[_i]);
763 }
764 return;
765 }
766
767 _off = ifnet_serialize_array_index(_arrcnt, _txoff, _rxoff, _slz);
768 if (_serialized)
769 ASSERT_SERIALIZED(_arr[_off]);
770 else
771 ASSERT_NOT_SERIALIZED(_arr[_off]);
772}
773
774#endif /* INVARIANTS */
775
4ee4f753
MD
776#define REINPUT_KEEPRCVIF 0x0001 /* ether_reinput_oncpu() */
777#define REINPUT_RUNBPF 0x0002 /* ether_reinput_oncpu() */
778
984263bc
MD
779extern struct ifnethead ifnet;
780extern struct ifnet **ifindex2ifnet;
781extern int ifqmaxlen;
782extern struct ifnet loif[];
783extern int if_index;
984263bc 784
5f60906c
SZ
785struct ip;
786struct tcphdr;
787
78195a76
MD
788void ether_ifattach(struct ifnet *, uint8_t *, struct lwkt_serialize *);
789void ether_ifattach_bpf(struct ifnet *, uint8_t *, u_int, u_int,
790 struct lwkt_serialize *);
0a8b5977 791void ether_ifdetach(struct ifnet *);
48242f47 792void ether_demux(struct mbuf *);
297c8124 793void ether_demux_oncpu(struct ifnet *, struct mbuf *);
b9ed4403 794void ether_reinput_oncpu(struct ifnet *, struct mbuf *, int);
eda7db08 795void ether_input_pkt(struct ifnet *, struct mbuf *, const struct pktinfo *);
984263bc 796int ether_output_frame(struct ifnet *, struct mbuf *);
fecfec53 797int ether_ioctl(struct ifnet *, u_long, caddr_t);
5f60906c
SZ
798boolean_t ether_tso_pullup(struct mbuf **, int *, struct ip **, int *,
799 struct tcphdr **, int *);
70d9a675 800struct ifnet *ether_bridge_interface(struct ifnet *ifp);
d6018c31
JS
801uint32_t ether_crc32_le(const uint8_t *, size_t);
802uint32_t ether_crc32_be(const uint8_t *, size_t);
984263bc
MD
803
804int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
805int if_allmulti(struct ifnet *, int);
78195a76 806void if_attach(struct ifnet *, struct lwkt_serialize *);
984263bc 807int if_delmulti(struct ifnet *, struct sockaddr *);
3976c93a 808void if_delallmulti(struct ifnet *ifp);
c727e142 809void if_purgeaddrs_nolink(struct ifnet *);
984263bc
MD
810void if_detach(struct ifnet *);
811void if_down(struct ifnet *);
6de83abe 812void if_link_state_change(struct ifnet *);
1550dfd9 813void if_initname(struct ifnet *, const char *, int);
e9bd1548 814int if_getanyethermac(uint16_t *, int);
984263bc 815int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
cb80735c
RP
816struct ifnet *if_alloc(uint8_t);
817void if_free(struct ifnet *);
984263bc
MD
818void if_route(struct ifnet *, int flag, int fam);
819int if_setlladdr(struct ifnet *, const u_char *, int);
820void if_unroute(struct ifnet *, int flag, int fam);
821void if_up(struct ifnet *);
822/*void ifinit(void);*/ /* declared in systm.h for main() */
87de5057 823int ifioctl(struct socket *, u_long, caddr_t, struct ucred *);
984263bc
MD
824int ifpromisc(struct ifnet *, int);
825struct ifnet *ifunit(const char *);
826struct ifnet *if_withname(struct sockaddr *);
827
315a7da3
JL
828struct ifg_group *if_creategroup(const char *);
829int if_addgroup(struct ifnet *, const char *);
830int if_delgroup(struct ifnet *, const char *);
831int if_getgroup(caddr_t, struct ifnet *);
832int if_getgroupmembers(caddr_t);
833
984263bc
MD
834struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
835struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
836struct ifaddr *ifa_ifwithnet(struct sockaddr *);
837struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
838struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
984263bc 839
aeb3c11e
RP
840typedef void *if_com_alloc_t(u_char type, struct ifnet *ifp);
841typedef void if_com_free_t(void *com, u_char type);
842void if_register_com_alloc(u_char, if_com_alloc_t *a, if_com_free_t *);
843void if_deregister_com_alloc(u_char);
844
b2632176
SZ
845void *ifa_create(int, int);
846void ifa_destroy(struct ifaddr *);
847void ifa_iflink(struct ifaddr *, struct ifnet *, int);
848void ifa_ifunlink(struct ifaddr *, struct ifnet *);
b2632176 849
bd08b792
RP
850struct ifaddr *ifaddr_byindex(unsigned short);
851
984263bc
MD
852struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *);
853int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
f0a26983
SZ
854void if_devstart(struct ifnet *ifp); /* COMPAT */
855void if_devstart_sched(struct ifnet *ifp); /* COMPAT */
a317449e 856int if_ring_count2(int cnt, int cnt_max);
984263bc 857
f2682cb9 858#define IF_LLSOCKADDR(ifp) \
141697b6 859 ((struct sockaddr_dl *)(ifp)->if_lladdr->ifa_addr)
f2682cb9 860#define IF_LLADDR(ifp) LLADDR(IF_LLSOCKADDR(ifp))
984263bc 861
b3a7093f
SZ
862#ifdef IFPOLL_ENABLE
863int ifpoll_register(struct ifnet *);
864int ifpoll_deregister(struct ifnet *);
865#endif /* IFPOLL_ENABLE */
866
984263bc
MD
867#endif /* _KERNEL */
868
869#endif /* !_NET_IF_VAR_H_ */