Update to FreeBSD head 2018-06-01

Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9.

Update #3472.
This commit is contained in:
Sebastian Huber
2018-08-21 13:47:02 +02:00
parent 2df56dbd60
commit bcdce02d9b
340 changed files with 27754 additions and 11720 deletions

View File

@@ -436,8 +436,8 @@ tbr_timeout(arg)
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
for (ifp = TAILQ_FIRST(&V_ifnet); ifp;
ifp = TAILQ_NEXT(ifp, if_link)) {
for (ifp = CK_STAILQ_FIRST(&V_ifnet); ifp;
ifp = CK_STAILQ_NEXT(ifp, if_link)) {
/* read from if_snd unlocked */
if (!TBR_IS_ENABLED(&ifp->if_snd))
continue;

View File

@@ -42,7 +42,6 @@
__FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_bpf.h>
#include <rtems/bsd/local/opt_compat.h>
#include <rtems/bsd/local/opt_ddb.h>
#include <rtems/bsd/local/opt_netgraph.h>
@@ -106,6 +105,10 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_BPF, "BPF", "BPF data");
static struct bpf_if_ext dead_bpf_if = {
.bif_dlist = LIST_HEAD_INITIALIZER()
};
struct bpf_if {
#define bif_next bif_ext.bif_next
#define bif_dlist bif_ext.bif_dlist
@@ -167,6 +170,9 @@ struct bpf_dltlist32 {
#define BIOCSETFNR32 _IOW('B', 130, struct bpf_program32)
#endif
#define BPF_LOCK() sx_xlock(&bpf_sx)
#define BPF_UNLOCK() sx_xunlock(&bpf_sx)
#define BPF_LOCK_ASSERT() sx_assert(&bpf_sx, SA_XLOCKED)
/*
* bpf_iflist is a list of BPF interface structures, each corresponding to a
* specific DLT. The same network interface might have several BPF interface
@@ -174,7 +180,7 @@ struct bpf_dltlist32 {
* frames, ethernet frames, etc).
*/
static LIST_HEAD(, bpf_if) bpf_iflist, bpf_freelist;
static struct mtx bpf_mtx; /* bpf global lock */
static struct sx bpf_sx; /* bpf global lock */
static int bpf_bpfd_cnt;
static void bpf_attachd(struct bpf_d *, struct bpf_if *);
@@ -2752,7 +2758,7 @@ bpfdetach(struct ifnet *ifp)
*/
BPFIF_WLOCK(bp);
bp->bif_flags |= BPFIF_FLAG_DYING;
*bp->bif_bpf = NULL;
*bp->bif_bpf = (struct bpf_if *)&dead_bpf_if;
BPFIF_WUNLOCK(bp);
CTR4(KTR_NET, "%s: sheduling free for encap %d (%p) for if %p",
@@ -3090,7 +3096,7 @@ bpf_drvinit(void *unused)
int rv;
#endif /* __rtems__ */
mtx_init(&bpf_mtx, "bpf global lock", NULL, MTX_DEF);
sx_init(&bpf_sx, "bpf global lock");
LIST_INIT(&bpf_iflist);
LIST_INIT(&bpf_freelist);
@@ -3253,13 +3259,13 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS)
SYSINIT(bpfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE,bpf_drvinit,NULL);
#else /* !DEV_BPF && !NETGRAPH_BPF */
/*
* NOP stubs to allow bpf-using drivers to load and function.
*
* A 'better' implementation would allow the core bpf functionality
* to be loaded at runtime.
*/
static struct bpf_if bp_null;
void
bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen)
@@ -3287,7 +3293,7 @@ void
bpfattach2(struct ifnet *ifp, u_int dlt, u_int hdrlen, struct bpf_if **driverp)
{
*driverp = &bp_null;
*driverp = (struct bpf_if *)&dead_bpf_if;
}
void

View File

@@ -125,9 +125,6 @@ struct bpf_d {
#define BPF_PID_REFRESH_CUR(bd) do { } while (0)
#endif /* __rtems__ */
#define BPF_LOCK() mtx_lock(&bpf_mtx)
#define BPF_UNLOCK() mtx_unlock(&bpf_mtx)
#define BPF_LOCK_ASSERT() mtx_assert(&bpf_mtx, MA_OWNED)
/*
* External representation of the bpf descriptor
*/

View File

@@ -2045,7 +2045,7 @@ bstp_reinit(struct bstp_state *bs)
* bridges in the same STP domain.
*/
IFNET_RLOCK_NOSLEEP();
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (ifp->if_type != IFT_ETHER)
continue; /* Not Ethernet */

View File

@@ -122,9 +122,9 @@
/*
* 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and
* Mac OS X; don't use it for anything else. (FreeBSD uses 121,
* which collides with DLT_HHDLC, even though it doesn't use 18
* for anything and doesn't appear to have ever used it for anything.)
* macOS; don't use it for anything else. (FreeBSD uses 121, which
* collides with DLT_HHDLC, even though it doesn't use 18 for
* anything and doesn't appear to have ever used it for anything.)
*
* We define it as 18 on those platforms; it is, unfortunately, used
* for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC
@@ -342,7 +342,7 @@
*
* FreeBSD's libpcap won't map a link-layer header type of 18 - i.e.,
* DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD,
* DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's
* DragonFly BSD, and macOS - to DLT_PFSYNC, so code built with FreeBSD's
* libpcap won't treat those files as DLT_PFSYNC files.
*
* Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC;
@@ -948,14 +948,14 @@
* the pseudo-header is:
*
* struct dl_ipnetinfo {
* u_int8_t dli_version;
* u_int8_t dli_family;
* u_int16_t dli_htype;
* u_int32_t dli_pktlen;
* u_int32_t dli_ifindex;
* u_int32_t dli_grifindex;
* u_int32_t dli_zsrc;
* u_int32_t dli_zdst;
* uint8_t dli_version;
* uint8_t dli_family;
* uint16_t dli_htype;
* uint32_t dli_pktlen;
* uint32_t dli_ifindex;
* uint32_t dli_grifindex;
* uint32_t dli_zsrc;
* uint32_t dli_zdst;
* };
*
* dli_version is 2 for the current version of the pseudo-header.
@@ -1231,7 +1231,7 @@
* So I'll just give them one; hopefully this will show up in a
* libpcap release in time for them to get this into 10.10 Big Sur
* or whatever Mavericks' successor is called. LINKTYPE_PKTAP
* will be 258 *even on OS X*; that is *intentional*, so that
* will be 258 *even on macOS*; that is *intentional*, so that
* PKTAP files look the same on *all* OSes (different OSes can have
* different numerical values for a given DLT_, but *MUST NOT* have
* different values for what goes in a file, as files can be moved
@@ -1243,9 +1243,9 @@
* and that will continue to be DLT_USER2 on Darwin-based OSes. That way,
* binary compatibility with Mavericks is preserved for programs using
* this version of libpcap. This does mean that if you were using
* DLT_USER2 for some capture device on OS X, you can't do so with
* DLT_USER2 for some capture device on macOS, you can't do so with
* this version of libpcap, just as you can't with Apple's libpcap -
* on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't
* on macOS, they define DLT_PKTAP to be DLT_USER2, so programs won't
* be able to distinguish between PKTAP and whatever you were using
* DLT_USER2 for.
*
@@ -1304,6 +1304,66 @@
*/
#define DLT_RDS 265
/*
* USB packets, beginning with a Darwin (macOS, etc.) header.
*/
#define DLT_USB_DARWIN 266
/*
* OpenBSD DLT_OPENFLOW.
*/
#define DLT_OPENFLOW 267
/*
* SDLC frames containing SNA PDUs.
*/
#define DLT_SDLC 268
/*
* per "Selvig, Bjorn" <b.selvig@ti.com> used for
* TI protocol sniffer.
*/
#define DLT_TI_LLN_SNIFFER 269
/*
* per: Erik de Jong <erikdejong at gmail.com> for
* https://github.com/eriknl/LoRaTap/releases/tag/v0.1
*/
#define DLT_LORATAP 270
/*
* per: Stefanha at gmail.com for
* http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html
* and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h
* for: http://qemu-project.org/Features/VirtioVsock
*/
#define DLT_VSOCK 271
/*
* Nordic Semiconductor Bluetooth LE sniffer.
*/
#define DLT_NORDIC_BLE 272
/*
* Excentis DOCSIS 3.1 RF sniffer (XRA-31)
* per: bruno.verstuyft at excentis.com
* http://www.xra31.com/xra-header
*/
#define DLT_DOCSIS31_XRA31 273
/*
* mPackets, as specified by IEEE 802.3br Figure 99-4, starting
* with the preamble and always ending with a CRC field.
*/
#define DLT_ETHERNET_MPACKET 274
/*
* DisplayPort AUX channel monitoring data as specified by VESA
* DisplayPort(DP) Standard preceeded by a pseudo-header.
* per dirk.eibach at gdsys.cc
*/
#define DLT_DISPLAYPORT_AUX 275
/*
* In case the code that includes this file (directly or indirectly)
* has also included OS files that happen to define DLT_MATCHING_MAX,
@@ -1314,7 +1374,7 @@
#ifdef DLT_MATCHING_MAX
#undef DLT_MATCHING_MAX
#endif
#define DLT_MATCHING_MAX 265 /* highest value in the "matching" range */
#define DLT_MATCHING_MAX 275 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and

View File

@@ -1,107 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1995 Matt Thomas (thomas@lkg.dec.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_fddi.h 8.1 (Berkeley) 6/10/93
* $FreeBSD$
*/
#ifndef _NETINET_IF_FDDI_H_
#define _NETINET_IF_FDDI_H_
#define FDDIIPMTU 4352
#define FDDIMTU 4470
#define FDDIMIN 3
#define FDDIFC_C 0x80 /* 0b10000000 */
#define FDDIFC_L 0x40 /* 0b01000000 */
#define FDDIFC_F 0x30 /* 0b00110000 */
#define FDDIFC_Z 0x0F /* 0b00001111 */
#define FDDIFC_CLFF 0xF0 /* Class/Length/Format bits */
#define FDDIFC_ZZZZ 0x0F /* Control bits */
/*
* FDDI Frame Control values. (48-bit addressing only).
*/
#define FDDIFC_VOID 0x40 /* Void frame */
#define FDDIFC_NRT 0x80 /* Nonrestricted token */
#define FDDIFC_RT 0xc0 /* Restricted token */
#define FDDIFC_MAC_BEACON 0xc2 /* MAC Beacon frame */
#define FDDIFC_MAC_CLAIM 0xc3 /* MAC Claim frame */
#define FDDIFC_LLC_ASYNC 0x50
#define FDDIFC_LLC_PRIO0 0
#define FDDIFC_LLC_PRIO1 1
#define FDDIFC_LLC_PRIO2 2
#define FDDIFC_LLC_PRIO3 3
#define FDDIFC_LLC_PRIO4 4
#define FDDIFC_LLC_PRIO5 5
#define FDDIFC_LLC_PRIO6 6
#define FDDIFC_LLC_PRIO7 7
#define FDDIFC_LLC_SYNC 0xd0
#define FDDIFC_IMP_ASYNC 0x60 /* Implementor Async. */
#define FDDIFC_IMP_SYNC 0xe0 /* Implementor Synch. */
#define FDDIFC_SMT 0x40
#define FDDIFC_SMT_INFO 0x41 /* SMT Info */
#define FDDIFC_SMT_NSA 0x4F /* SMT Next station adrs */
#define FDDIFC_MAC 0xc0 /* MAC frame */
#define FDDI_ADDR_LEN 6
#define FDDI_HDR_LEN (sizeof(struct fddi_header))
/*
* Structure of an 100Mb/s FDDI header.
*/
struct fddi_header {
u_char fddi_fc;
u_char fddi_dhost[FDDI_ADDR_LEN];
u_char fddi_shost[FDDI_ADDR_LEN];
};
#if defined(_KERNEL)
#define fddi_ipmulticast_min ether_ipmulticast_min
#define fddi_ipmulticast_max ether_ipmulticast_max
#define fddi_addmulti ether_addmulti
#define fddi_delmulti ether_delmulti
#define fddi_sprintf ether_sprintf
#define FDDI_BPF_UNSUPPORTED 0
#define FDDI_BPF_SUPPORTED 1
void fddi_ifattach(struct ifnet *, const u_int8_t *, int);
void fddi_ifdetach(struct ifnet *, int);
int fddi_ioctl(struct ifnet *, u_long, caddr_t);
#endif /* _KERNEL */
#endif /* _NET_FDDI_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,145 +0,0 @@
/* $NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp $ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: NetBSD: if_ether.h,v 1.10 1994/06/29 06:37:55 cgd Exp
* @(#)if_ether.h 8.1 (Berkeley) 6/10/93
*/
#ifndef _NET_IF_ARC_H_
#define _NET_IF_ARC_H_
/*
* Arcnet address - 1 octets
* don't know who uses this.
*/
struct arc_addr {
u_int8_t arc_addr_octet[1];
} __packed;
/*
* Structure of a 2.5MB/s Arcnet header.
* as given to interface code.
*/
struct arc_header {
u_int8_t arc_shost;
u_int8_t arc_dhost;
u_int8_t arc_type;
/*
* only present for newstyle encoding with LL fragmentation.
* Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead.
*/
u_int8_t arc_flag;
u_int16_t arc_seqid;
/*
* only present in exception packets (arc_flag == 0xff)
*/
u_int8_t arc_type2; /* same as arc_type */
u_int8_t arc_flag2; /* real flag value */
u_int16_t arc_seqid2; /* real seqid value */
} __packed;
#define ARC_ADDR_LEN 1
#define ARC_HDRLEN 3
#define ARC_HDRNEWLEN 6
#define ARC_HDRNEWLEN_EXC 10
/* these lengths are data link layer length - 2 * ARC_ADDR_LEN */
#define ARC_MIN_LEN 1
#define ARC_MIN_FORBID_LEN 254
#define ARC_MAX_FORBID_LEN 256
#define ARC_MAX_LEN 508
#define ARC_MAX_DATA 504
/* RFC 1051 */
#define ARCTYPE_IP_OLD 240 /* IP protocol */
#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
/* RFC 1201 */
#define ARCTYPE_IP 212 /* IP protocol */
#define ARCTYPE_ARP 213 /* address resolution protocol */
#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
#define ARCTYPE_ATALK 221 /* Appletalk */
#define ARCTYPE_BANIAN 247 /* Banyan Vines */
#define ARCTYPE_IPX 250 /* Novell IPX */
#define ARCTYPE_INET6 0xc4 /* IPng */
#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */
#define ARCMTU 507
#define ARCMIN 0
#define ARC_PHDS_MAXMTU 60480
struct arccom {
struct ifnet *ac_ifp; /* network-visible interface */
u_int16_t ac_seqid; /* seq. id used by PHDS encap. */
u_int8_t arc_shost;
u_int8_t arc_dhost;
u_int8_t arc_type;
u_int8_t dummy0;
u_int16_t dummy1;
int sflag, fsflag, rsflag;
struct mbuf *curr_frag;
struct ac_frag {
u_int8_t af_maxflag; /* from first packet */
u_int8_t af_lastseen; /* last split flag seen */
u_int16_t af_seqid;
struct mbuf *af_packet;
} ac_fragtab[256]; /* indexed by sender ll address */
};
#ifdef _KERNEL
extern u_int8_t arcbroadcastaddr;
extern int arc_ipmtu; /* XXX new ip only, no RFC 1051! */
void arc_ifattach(struct ifnet *, u_int8_t);
void arc_ifdetach(struct ifnet *);
void arc_storelladdr(struct ifnet *, u_int8_t);
int arc_isphds(u_int8_t);
void arc_input(struct ifnet *, struct mbuf *);
int arc_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);
int arc_ioctl(struct ifnet *, u_long, caddr_t);
void arc_frag_init(struct ifnet *);
struct mbuf * arc_frag_next(struct ifnet *);
#endif
#endif /* _NET_IF_ARC_H_ */

View File

@@ -1,833 +0,0 @@
#include <machine/rtems-bsd-kernel-space.h>
/* $NetBSD: if_arcsubr.c,v 1.36 2001/06/14 05:44:23 itojun Exp $ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1994, 1995 Ignatios Souvatzis
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: NetBSD: if_ethersubr.c,v 1.9 1994/06/29 06:36:11 cgd Exp
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
*
*/
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <machine/cpu.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/if_arc.h>
#include <net/if_arp.h>
#include <net/bpf.h>
#include <net/if_llatbl.h>
#if defined(INET) || defined(INET6)
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
#endif
#ifdef INET6
#include <netinet6/nd6.h>
#endif
#define ARCNET_ALLOW_BROKEN_ARP
static struct mbuf *arc_defrag(struct ifnet *, struct mbuf *);
static int arc_resolvemulti(struct ifnet *, struct sockaddr **,
struct sockaddr *);
u_int8_t arcbroadcastaddr = 0;
#define ARC_LLADDR(ifp) (*(u_int8_t *)IF_LLADDR(ifp))
#define senderr(e) { error = (e); goto bad;}
#define SIN(s) ((const struct sockaddr_in *)(s))
/*
* ARCnet output routine.
* Encapsulate a packet of type family for the local net.
* Assumes that ifp is actually pointer to arccom structure.
*/
int
arc_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro)
{
struct arc_header *ah;
int error;
u_int8_t atype, adst;
int loop_copy = 0;
int isphds;
#if defined(INET) || defined(INET6)
int is_gw = 0;
#endif
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
return(ENETDOWN); /* m, m1 aren't initialized yet */
error = 0;
#if defined(INET) || defined(INET6)
if (ro != NULL)
is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
/*
* For now, use the simple IP addr -> ARCnet addr mapping
*/
if (m->m_flags & (M_BCAST|M_MCAST))
adst = arcbroadcastaddr; /* ARCnet broadcast address */
else if (ifp->if_flags & IFF_NOARP)
adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF;
else {
error = arpresolve(ifp, is_gw, m, dst, &adst, NULL,
NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
atype = (ifp->if_flags & IFF_LINK0) ?
ARCTYPE_IP_OLD : ARCTYPE_IP;
break;
case AF_ARP:
{
struct arphdr *ah;
ah = mtod(m, struct arphdr *);
ah->ar_hrd = htons(ARPHRD_ARCNET);
loop_copy = -1; /* if this is for us, don't do it */
switch(ntohs(ah->ar_op)) {
case ARPOP_REVREQUEST:
case ARPOP_REVREPLY:
atype = ARCTYPE_REVARP;
break;
case ARPOP_REQUEST:
case ARPOP_REPLY:
default:
atype = ARCTYPE_ARP;
break;
}
if (m->m_flags & M_BCAST)
bcopy(ifp->if_broadcastaddr, &adst, ARC_ADDR_LEN);
else
bcopy(ar_tha(ah), &adst, ARC_ADDR_LEN);
}
break;
#endif
#ifdef INET6
case AF_INET6:
if ((m->m_flags & M_MCAST) != 0)
adst = arcbroadcastaddr; /* ARCnet broadcast address */
else {
error = nd6_resolve(ifp, is_gw, m, dst, &adst, NULL,
NULL);
if (error != 0)
return (error == EWOULDBLOCK ? 0 : error);
}
atype = ARCTYPE_INET6;
break;
#endif
case AF_UNSPEC:
{
const struct arc_header *ah;
loop_copy = -1;
ah = (const struct arc_header *)dst->sa_data;
adst = ah->arc_dhost;
atype = ah->arc_type;
if (atype == ARCTYPE_ARP) {
atype = (ifp->if_flags & IFF_LINK0) ?
ARCTYPE_ARP_OLD: ARCTYPE_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
/*
* XXX It's not clear per RFC826 if this is needed, but
* "assigned numbers" say this is wrong.
* However, e.g., AmiTCP 3.0Beta used it... we make this
* switchable for emergency cases. Not perfect, but...
*/
if (ifp->if_flags & IFF_LINK2)
mtod(m, struct arphdr *)->ar_pro = atype - 1;
#endif
}
break;
}
default:
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
senderr(EAFNOSUPPORT);
}
isphds = arc_isphds(atype);
M_PREPEND(m, isphds ? ARC_HDRNEWLEN : ARC_HDRLEN, M_NOWAIT);
if (m == NULL)
senderr(ENOBUFS);
ah = mtod(m, struct arc_header *);
ah->arc_type = atype;
ah->arc_dhost = adst;
ah->arc_shost = ARC_LLADDR(ifp);
if (isphds) {
ah->arc_flag = 0;
ah->arc_seqid = 0;
}
if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
(void) if_simloop(ifp, n, dst->sa_family, ARC_HDRLEN);
} else if (ah->arc_dhost == ah->arc_shost) {
(void) if_simloop(ifp, m, dst->sa_family, ARC_HDRLEN);
return (0); /* XXX */
}
}
BPF_MTAP(ifp, m);
error = ifp->if_transmit(ifp, m);
return (error);
bad:
if (m)
m_freem(m);
return (error);
}
void
arc_frag_init(struct ifnet *ifp)
{
struct arccom *ac;
ac = (struct arccom *)ifp->if_l2com;
ac->curr_frag = 0;
}
struct mbuf *
arc_frag_next(struct ifnet *ifp)
{
struct arccom *ac;
struct mbuf *m;
struct arc_header *ah;
ac = (struct arccom *)ifp->if_l2com;
if ((m = ac->curr_frag) == NULL) {
int tfrags;
/* dequeue new packet */
IF_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
return 0;
ah = mtod(m, struct arc_header *);
if (!arc_isphds(ah->arc_type))
return m;
++ac->ac_seqid; /* make the seqid unique */
tfrags = howmany(m->m_pkthdr.len, ARC_MAX_DATA);
ac->fsflag = 2 * tfrags - 3;
ac->sflag = 0;
ac->rsflag = ac->fsflag;
ac->arc_dhost = ah->arc_dhost;
ac->arc_shost = ah->arc_shost;
ac->arc_type = ah->arc_type;
m_adj(m, ARC_HDRNEWLEN);
ac->curr_frag = m;
}
/* split out next fragment and return it */
if (ac->sflag < ac->fsflag) {
/* we CAN'T have short packets here */
ac->curr_frag = m_split(m, ARC_MAX_DATA, M_NOWAIT);
if (ac->curr_frag == 0) {
m_freem(m);
return 0;
}
M_PREPEND(m, ARC_HDRNEWLEN, M_NOWAIT);
if (m == NULL) {
m_freem(ac->curr_frag);
ac->curr_frag = 0;
return 0;
}
ah = mtod(m, struct arc_header *);
ah->arc_flag = ac->rsflag;
ah->arc_seqid = ac->ac_seqid;
ac->sflag += 2;
ac->rsflag = ac->sflag;
} else if ((m->m_pkthdr.len >=
ARC_MIN_FORBID_LEN - ARC_HDRNEWLEN + 2) &&
(m->m_pkthdr.len <=
ARC_MAX_FORBID_LEN - ARC_HDRNEWLEN + 2)) {
ac->curr_frag = 0;
M_PREPEND(m, ARC_HDRNEWLEN_EXC, M_NOWAIT);
if (m == NULL)
return 0;
ah = mtod(m, struct arc_header *);
ah->arc_flag = 0xFF;
ah->arc_seqid = 0xFFFF;
ah->arc_type2 = ac->arc_type;
ah->arc_flag2 = ac->sflag;
ah->arc_seqid2 = ac->ac_seqid;
} else {
ac->curr_frag = 0;
M_PREPEND(m, ARC_HDRNEWLEN, M_NOWAIT);
if (m == NULL)
return 0;
ah = mtod(m, struct arc_header *);
ah->arc_flag = ac->sflag;
ah->arc_seqid = ac->ac_seqid;
}
ah->arc_dhost = ac->arc_dhost;
ah->arc_shost = ac->arc_shost;
ah->arc_type = ac->arc_type;
return m;
}
/*
* Defragmenter. Returns mbuf if last packet found, else
* NULL. frees incoming mbuf as necessary.
*/
static __inline struct mbuf *
arc_defrag(struct ifnet *ifp, struct mbuf *m)
{
struct arc_header *ah, *ah1;
struct arccom *ac;
struct ac_frag *af;
struct mbuf *m1;
char *s;
int newflen;
u_char src,dst,typ;
ac = (struct arccom *)ifp->if_l2com;
if (m->m_len < ARC_HDRNEWLEN) {
m = m_pullup(m, ARC_HDRNEWLEN);
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
return NULL;
}
}
ah = mtod(m, struct arc_header *);
typ = ah->arc_type;
if (!arc_isphds(typ))
return m;
src = ah->arc_shost;
dst = ah->arc_dhost;
if (ah->arc_flag == 0xff) {
m_adj(m, 4);
if (m->m_len < ARC_HDRNEWLEN) {
m = m_pullup(m, ARC_HDRNEWLEN);
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
return NULL;
}
}
ah = mtod(m, struct arc_header *);
}
af = &ac->ac_fragtab[src];
m1 = af->af_packet;
s = "debug code error";
if (ah->arc_flag & 1) {
/*
* first fragment. We always initialize, which is
* about the right thing to do, as we only want to
* accept one fragmented packet per src at a time.
*/
if (m1 != NULL)
m_freem(m1);
af->af_packet = m;
m1 = m;
af->af_maxflag = ah->arc_flag;
af->af_lastseen = 0;
af->af_seqid = ah->arc_seqid;
return NULL;
/* notreached */
} else {
/* check for unfragmented packet */
if (ah->arc_flag == 0)
return m;
/* do we have a first packet from that src? */
if (m1 == NULL) {
s = "no first frag";
goto outofseq;
}
ah1 = mtod(m1, struct arc_header *);
if (ah->arc_seqid != ah1->arc_seqid) {
s = "seqid differs";
goto outofseq;
}
if (typ != ah1->arc_type) {
s = "type differs";
goto outofseq;
}
if (dst != ah1->arc_dhost) {
s = "dest host differs";
goto outofseq;
}
/* typ, seqid and dst are ok here. */
if (ah->arc_flag == af->af_lastseen) {
m_freem(m);
return NULL;
}
if (ah->arc_flag == af->af_lastseen + 2) {
/* ok, this is next fragment */
af->af_lastseen = ah->arc_flag;
m_adj(m,ARC_HDRNEWLEN);
/*
* m_cat might free the first mbuf (with pkthdr)
* in 2nd chain; therefore:
*/
newflen = m->m_pkthdr.len;
m_cat(m1,m);
m1->m_pkthdr.len += newflen;
/* is it the last one? */
if (af->af_lastseen > af->af_maxflag) {
af->af_packet = NULL;
return(m1);
} else
return NULL;
}
s = "other reason";
/* if all else fails, it is out of sequence, too */
}
outofseq:
if (m1) {
m_freem(m1);
af->af_packet = NULL;
}
if (m)
m_freem(m);
log(LOG_INFO,"%s: got out of seq. packet: %s\n",
ifp->if_xname, s);
return NULL;
}
/*
* return 1 if Packet Header Definition Standard, else 0.
* For now: old IP, old ARP aren't obviously. Lacking correct information,
* we guess that besides new IP and new ARP also IPX and APPLETALK are PHDS.
* (Apple and Novell corporations were involved, among others, in PHDS work).
* Easiest is to assume that everybody else uses that, too.
*/
int
arc_isphds(u_int8_t type)
{
return (type != ARCTYPE_IP_OLD &&
type != ARCTYPE_ARP_OLD &&
type != ARCTYPE_DIAGNOSE);
}
/*
* Process a received Arcnet packet;
* the packet is in the mbuf chain m with
* the ARCnet header.
*/
void
arc_input(struct ifnet *ifp, struct mbuf *m)
{
struct arc_header *ah;
int isr;
u_int8_t atype;
if ((ifp->if_flags & IFF_UP) == 0) {
m_freem(m);
return;
}
/* possibly defragment: */
m = arc_defrag(ifp, m);
if (m == NULL)
return;
BPF_MTAP(ifp, m);
ah = mtod(m, struct arc_header *);
/* does this belong to us? */
if ((ifp->if_flags & IFF_PROMISC) == 0
&& ah->arc_dhost != arcbroadcastaddr
&& ah->arc_dhost != ARC_LLADDR(ifp)) {
m_freem(m);
return;
}
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
if (ah->arc_dhost == arcbroadcastaddr) {
m->m_flags |= M_BCAST|M_MCAST;
if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1);
}
atype = ah->arc_type;
switch (atype) {
#ifdef INET
case ARCTYPE_IP:
m_adj(m, ARC_HDRNEWLEN);
isr = NETISR_IP;
break;
case ARCTYPE_IP_OLD:
m_adj(m, ARC_HDRLEN);
isr = NETISR_IP;
break;
case ARCTYPE_ARP:
if (ifp->if_flags & IFF_NOARP) {
/* Discard packet if ARP is disabled on interface */
m_freem(m);
return;
}
m_adj(m, ARC_HDRNEWLEN);
isr = NETISR_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
mtod(m, struct arphdr *)->ar_pro = htons(ETHERTYPE_IP);
#endif
break;
case ARCTYPE_ARP_OLD:
if (ifp->if_flags & IFF_NOARP) {
/* Discard packet if ARP is disabled on interface */
m_freem(m);
return;
}
m_adj(m, ARC_HDRLEN);
isr = NETISR_ARP;
#ifdef ARCNET_ALLOW_BROKEN_ARP
mtod(m, struct arphdr *)->ar_pro = htons(ETHERTYPE_IP);
#endif
break;
#endif
#ifdef INET6
case ARCTYPE_INET6:
m_adj(m, ARC_HDRNEWLEN);
isr = NETISR_IPV6;
break;
#endif
default:
m_freem(m);
return;
}
M_SETFIB(m, ifp->if_fib);
netisr_dispatch(isr, m);
}
/*
* Register (new) link level address.
*/
void
arc_storelladdr(struct ifnet *ifp, u_int8_t lla)
{
ARC_LLADDR(ifp) = lla;
}
/*
* Perform common duties while attaching to interface list
*/
void
arc_ifattach(struct ifnet *ifp, u_int8_t lla)
{
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
struct arccom *ac;
if_attach(ifp);
ifp->if_addrlen = 1;
ifp->if_hdrlen = ARC_HDRLEN;
ifp->if_mtu = 1500;
ifp->if_resolvemulti = arc_resolvemulti;
if (ifp->if_baudrate == 0)
ifp->if_baudrate = 2500000;
ifa = ifp->if_addr;
KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_ARCNET;
sdl->sdl_alen = ifp->if_addrlen;
if (ifp->if_flags & IFF_BROADCAST)
ifp->if_flags |= IFF_MULTICAST|IFF_ALLMULTI;
ac = (struct arccom *)ifp->if_l2com;
ac->ac_seqid = (time_second) & 0xFFFF; /* try to make seqid unique */
if (lla == 0) {
/* XXX this message isn't entirely clear, to me -- cgd */
log(LOG_ERR,"%s: link address 0 reserved for broadcasts. Please change it and ifconfig %s down up\n",
ifp->if_xname, ifp->if_xname);
}
arc_storelladdr(ifp, lla);
ifp->if_broadcastaddr = &arcbroadcastaddr;
bpfattach(ifp, DLT_ARCNET, ARC_HDRLEN);
}
void
arc_ifdetach(struct ifnet *ifp)
{
bpfdetach(ifp);
if_detach(ifp);
}
int
arc_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
struct ifaddr *ifa = (struct ifaddr *) data;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0;
switch (command) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
ifp->if_init(ifp->if_softc); /* before arpwhohas */
arp_ifinit(ifp, ifa);
break;
#endif
default:
ifp->if_init(ifp->if_softc);
break;
}
break;
case SIOCGIFADDR:
ifr->ifr_addr.sa_data[0] = ARC_LLADDR(ifp);
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
if (ifr == NULL)
error = EAFNOSUPPORT;
else {
switch (ifr->ifr_addr.sa_family) {
case AF_INET:
case AF_INET6:
error = 0;
break;
default:
error = EAFNOSUPPORT;
break;
}
}
break;
case SIOCSIFMTU:
/*
* Set the interface MTU.
* mtu can't be larger than ARCMTU for RFC1051
* and can't be larger than ARC_PHDS_MTU
*/
if (((ifp->if_flags & IFF_LINK0) && ifr->ifr_mtu > ARCMTU) ||
ifr->ifr_mtu > ARC_PHDS_MAXMTU)
error = EINVAL;
else
ifp->if_mtu = ifr->ifr_mtu;
break;
}
return (error);
}
/* based on ether_resolvemulti() */
int
arc_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa,
struct sockaddr *sa)
{
struct sockaddr_dl *sdl;
#ifdef INET
struct sockaddr_in *sin;
#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
switch(sa->sa_family) {
case AF_LINK:
/*
* No mapping needed. Just check that it's a valid MC address.
*/
sdl = (struct sockaddr_dl *)sa;
if (*LLADDR(sdl) != arcbroadcastaddr)
return EADDRNOTAVAIL;
*llsa = NULL;
return 0;
#ifdef INET
case AF_INET:
sin = (struct sockaddr_in *)sa;
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
return EADDRNOTAVAIL;
sdl = link_init_sdl(ifp, *llsa, IFT_ETHER);
sdl->sdl_alen = ARC_ADDR_LEN;
*LLADDR(sdl) = 0;
*llsa = (struct sockaddr *)sdl;
return 0;
#endif
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)sa;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/*
* An IP6 address of 0 means listen to all
* of the Ethernet multicast address used for IP6.
* (This is used for multicast routers.)
*/
ifp->if_flags |= IFF_ALLMULTI;
*llsa = NULL;
return 0;
}
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return EADDRNOTAVAIL;
sdl = link_init_sdl(ifp, *llsa, IFT_ETHER);
sdl->sdl_alen = ARC_ADDR_LEN;
*LLADDR(sdl) = 0;
*llsa = (struct sockaddr *)sdl;
return 0;
#endif
default:
/*
* Well, the text isn't quite right, but it's the name
* that counts...
*/
return EAFNOSUPPORT;
}
}
static MALLOC_DEFINE(M_ARCCOM, "arccom", "ARCNET interface internals");
static void*
arc_alloc(u_char type, struct ifnet *ifp)
{
struct arccom *ac;
ac = malloc(sizeof(struct arccom), M_ARCCOM, M_WAITOK | M_ZERO);
ac->ac_ifp = ifp;
return (ac);
}
static void
arc_free(void *com, u_char type)
{
free(com, M_ARCCOM);
}
static int
arc_modevent(module_t mod, int type, void *data)
{
switch (type) {
case MOD_LOAD:
if_register_com_alloc(IFT_ARCNET, arc_alloc, arc_free);
break;
case MOD_UNLOAD:
if_deregister_com_alloc(IFT_ARCNET);
break;
default:
return EOPNOTSUPP;
}
return (0);
}
static moduledata_t arc_mod = {
"arcnet",
arc_modevent,
0
};
DECLARE_MODULE(arcnet, arc_mod, SI_SUB_INIT_IF, SI_ORDER_ANY);
MODULE_VERSION(arcnet, 1);

View File

@@ -49,7 +49,6 @@ struct arphdr {
u_short ar_hrd; /* format of hardware address */
#define ARPHRD_ETHER 1 /* ethernet hardware format */
#define ARPHRD_IEEE802 6 /* token-ring hardware format */
#define ARPHRD_ARCNET 7 /* arcnet hardware format */
#define ARPHRD_FRELAY 15 /* frame relay hardware format */
#define ARPHRD_IEEE1394 24 /* firewire hardware format */
#define ARPHRD_INFINIBAND 32 /* infiniband hardware format */

View File

@@ -74,8 +74,8 @@
*
* - Currently only supports Ethernet-like interfaces (Ethernet,
* 802.11, VLANs on Ethernet, etc.) Figure out a nice way
* to bridge other types of interfaces (FDDI-FDDI, and maybe
* consider heterogeneous bridges).
* to bridge other types of interfaces (maybe consider
* heterogeneous bridges).
*/
#include <sys/cdefs.h>
@@ -342,7 +342,6 @@ static int bridge_fragment(struct ifnet *, struct mbuf **mp,
static void bridge_linkstate(struct ifnet *ifp);
static void bridge_linkcheck(struct bridge_softc *sc);
extern void (*bridge_linkstate_p)(struct ifnet *ifp);
/* The default bridge vlan is 1 (IEEE 802.1Q-2003 Table 9-2) */
#define VLANTAGOF(_m) \
@@ -558,10 +557,7 @@ bridge_modevent(module_t mod, int type, void *data)
bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
bridge_input_p = bridge_input;
bridge_output_p = bridge_output;
bridge_dn_p = bridge_dummynet;
bridge_linkstate_p = bridge_linkstate;
bridge_detach_cookie = EVENTHANDLER_REGISTER(
ifnet_departure_event, bridge_ifdetach, NULL,
EVENTHANDLER_PRI_ANY);
@@ -570,10 +566,7 @@ bridge_modevent(module_t mod, int type, void *data)
EVENTHANDLER_DEREGISTER(ifnet_departure_event,
bridge_detach_cookie);
uma_zdestroy(bridge_rtnode_zone);
bridge_input_p = NULL;
bridge_output_p = NULL;
bridge_dn_p = NULL;
bridge_linkstate_p = NULL;
break;
default:
return (EOPNOTSUPP);
@@ -1043,6 +1036,9 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
KASSERT(bif->bif_addrcnt == 0,
("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt));
ifs->if_bridge_output = NULL;
ifs->if_bridge_input = NULL;
ifs->if_bridge_linkstate = NULL;
BRIDGE_UNLOCK(sc);
if (!gone) {
switch (ifs->if_type) {
@@ -1200,6 +1196,9 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
}
ifs->if_bridge = sc;
ifs->if_bridge_output = bridge_output;
ifs->if_bridge_input = bridge_input;
ifs->if_bridge_linkstate = bridge_linkstate;
bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp);
/*
* XXX: XLOCK HERE!?!

View File

@@ -309,23 +309,20 @@ struct ifbpstpconf {
(_sc)->sc_iflist_xcnt--; \
} while (0)
#define BRIDGE_INPUT(_ifp, _m) do { \
KASSERT(bridge_input_p != NULL, \
#define BRIDGE_INPUT(_ifp, _m) do { \
KASSERT((_ifp)->if_bridge_input != NULL, \
("%s: if_bridge not loaded!", __func__)); \
_m = (*bridge_input_p)(_ifp, _m); \
_m = (*(_ifp)->if_bridge_input)(_ifp, _m); \
if (_m != NULL) \
_ifp = _m->m_pkthdr.rcvif; \
} while (0)
#define BRIDGE_OUTPUT(_ifp, _m, _err) do { \
KASSERT(bridge_output_p != NULL, \
KASSERT((_ifp)->if_bridge_output != NULL, \
("%s: if_bridge not loaded!", __func__)); \
_err = (*bridge_output_p)(_ifp, _m, NULL, NULL); \
_err = (*(_ifp)->if_bridge_output)(_ifp, _m, NULL, NULL); \
} while (0)
extern struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
extern int (*bridge_output_p)(struct ifnet *, struct mbuf *,
struct sockaddr *, struct rtentry *);
extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
#endif /* _KERNEL */

View File

@@ -69,6 +69,7 @@ struct if_clone {
char ifc_name[IFCLOSIZ]; /* (c) Name of device, e.g. `gif' */
struct unrhdr *ifc_unrhdr; /* (c) alloc_unr(9) header */
int ifc_maxunit; /* (c) maximum unit number */
int ifc_flags;
long ifc_refcnt; /* (i) Reference count. */
LIST_HEAD(, ifnet) ifc_iflist; /* (i) List of cloned interfaces */
struct mtx ifc_mtx; /* Mutex to protect members. */
@@ -234,7 +235,8 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
if (ifp == NULL)
panic("%s: lookup failed for %s", __func__, name);
if_addgroup(ifp, ifc->ifc_name);
if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
if_addgroup(ifp, ifc->ifc_name);
IF_CLONE_LOCK(ifc);
IFC_IFLIST_INSERT(ifc, ifp);
@@ -321,8 +323,8 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
CURVNET_RESTORE();
return (ENXIO); /* ifp is not on the list. */
}
if_delgroup(ifp, ifc->ifc_name);
if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
if_delgroup(ifp, ifc->ifc_name);
if (ifc->ifc_type == SIMPLE)
err = ifc_simple_destroy(ifc, ifp);
@@ -330,7 +332,8 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
err = (*ifc->ifc_destroy)(ifc, ifp);
if (err != 0) {
if_addgroup(ifp, ifc->ifc_name);
if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
if_addgroup(ifp, ifc->ifc_name);
IF_CLONE_LOCK(ifc);
IFC_IFLIST_INSERT(ifc, ifp);
@@ -415,7 +418,7 @@ if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy,
for (unit = 0; unit < minifs; unit++) {
char name[IFNAMSIZ];
int error;
int error __unused;
snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
error = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
@@ -555,9 +558,10 @@ if_clone_findifc(struct ifnet *ifp)
void
if_clone_addgroup(struct ifnet *ifp, struct if_clone *ifc)
{
if_addgroup(ifp, ifc->ifc_name);
IF_CLONE_REMREF(ifc);
if ((ifc->ifc_flags & IFC_NOGROUP) == 0) {
if_addgroup(ifp, ifc->ifc_name);
IF_CLONE_REMREF(ifc);
}
}
/*
@@ -734,3 +738,21 @@ ifc_simple_destroy(struct if_clone *ifc, struct ifnet *ifp)
return (0);
}
const char *
ifc_name(struct if_clone *ifc)
{
return (ifc->ifc_name);
}
void
ifc_flags_set(struct if_clone *ifc, int flags)
{
ifc->ifc_flags = flags;
}
int
ifc_flags_get(struct if_clone *ifc)
{
return (ifc->ifc_flags);
}

View File

@@ -37,6 +37,8 @@
#ifdef _KERNEL
#define IFC_NOGROUP 0x1
struct if_clone;
/* Methods. */
@@ -59,6 +61,9 @@ void if_clone_detach(struct if_clone *);
int ifc_name2unit(const char *name, int *unit);
int ifc_alloc_unit(struct if_clone *, int *);
void ifc_free_unit(struct if_clone *, int);
const char *ifc_name(struct if_clone *);
void ifc_flags_set(struct if_clone *, int flags);
int ifc_flags_get(struct if_clone *);
#ifdef _SYS_EVENTHANDLER_H_
/* Interface clone event. */

View File

@@ -55,10 +55,14 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/hash.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/proc.h>
#include <sys/refcount.h>
#include <sys/queue.h>
#include <sys/smp.h>
@@ -253,7 +257,7 @@ static void
epair_nh_sintr(struct mbuf *m)
{
struct ifnet *ifp;
struct epair_softc *sc;
struct epair_softc *sc __unused;
ifp = m->m_pkthdr.rcvif;
(*ifp->if_input)(ifp, m);
@@ -298,7 +302,7 @@ epair_nh_drainedcpu(u_int cpuid)
IFQ_LOCK(&ifp->if_snd);
if (IFQ_IS_EMPTY(&ifp->if_snd)) {
struct epair_softc *sc;
struct epair_softc *sc __unused;
STAILQ_REMOVE(&epair_dpcpu->epair_ifp_drain_list,
elm, epair_ifp_drain, ifp_next);
@@ -339,7 +343,7 @@ epair_remove_ifp_from_draining(struct ifnet *ifp)
STAILQ_FOREACH_SAFE(elm, &epair_dpcpu->epair_ifp_drain_list,
ifp_next, tvar) {
if (ifp == elm->ifp) {
struct epair_softc *sc;
struct epair_softc *sc __unused;
STAILQ_REMOVE(
&epair_dpcpu->epair_ifp_drain_list, elm,
@@ -715,6 +719,9 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
struct ifnet *ifp;
char *dp;
int error, unit, wildcard;
uint64_t hostid;
uint32_t key[3];
uint32_t hash;
uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */
/*
@@ -726,14 +733,12 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
if (params) {
scb = (struct epair_softc *)params;
ifp = scb->ifp;
/* Assign a hopefully unique, locally administered etheraddr. */
eaddr[0] = 0x02;
eaddr[3] = (ifp->if_index >> 8) & 0xff;
eaddr[4] = ifp->if_index & 0xff;
/* Copy epairNa etheraddr and change the last byte. */
memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN);
eaddr[5] = 0x0b;
ether_ifattach(ifp, eaddr);
/* Correctly set the name for the cloner list. */
strlcpy(name, scb->ifp->if_xname, len);
strlcpy(name, ifp->if_xname, len);
return (0);
}
@@ -837,10 +842,21 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
ifp->if_init = epair_init;
if_setsendqlen(ifp, ifqmaxlen);
if_setsendqready(ifp);
/* Assign a hopefully unique, locally administered etheraddr. */
/*
* Calculate the etheraddr hashing the hostid and the
* interface index. The result would be hopefully unique
*/
getcredhostid(curthread->td_ucred, (unsigned long *)&hostid);
if (hostid == 0)
arc4rand(&hostid, sizeof(hostid), 0);
key[0] = (uint32_t)ifp->if_index;
key[1] = (uint32_t)(hostid & 0xffffffff);
key[2] = (uint32_t)((hostid >> 32) & 0xfffffffff);
hash = jenkins_hash32(key, 3, 0);
eaddr[0] = 0x02;
eaddr[3] = (ifp->if_index >> 8) & 0xff;
eaddr[4] = ifp->if_index & 0xff;
memcpy(&eaddr[1], &hash, 4);
eaddr[5] = 0x0a;
ether_ifattach(ifp, eaddr);
sca->if_qflush = ifp->if_qflush;

View File

@@ -104,9 +104,6 @@ void (*ng_ether_detach_p)(struct ifnet *ifp);
void (*vlan_input_p)(struct ifnet *, struct mbuf *);
/* if_bridge(4) support */
struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
int (*bridge_output_p)(struct ifnet *, struct mbuf *,
struct sockaddr *, struct rtentry *);
void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
/* if_lagg(4) support */
@@ -518,7 +515,7 @@ ether_input_internal(struct ifnet *ifp, struct mbuf *m)
}
eh = mtod(m, struct ether_header *);
etype = ntohs(eh->ether_type);
random_harvest_queue(m, sizeof(*m), 2, RANDOM_NET_ETHER);
random_harvest_queue_ether(m, sizeof(*m), 2);
CURVNET_SET_QUIET(ifp->if_vnet);
@@ -1130,10 +1127,13 @@ ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (error != 0)
break;
if (ifr->ifr_lan_pcp > 7 &&
ifr->ifr_lan_pcp != IFNET_PCP_NONE)
ifr->ifr_lan_pcp != IFNET_PCP_NONE) {
error = EINVAL;
else
} else {
ifp->if_pcp = ifr->ifr_lan_pcp;
/* broadcast event about PCP change */
EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_PCP);
}
break;
case SIOCGLANPCP:

View File

@@ -1,669 +0,0 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1995, 1996
* Matt Thomas <matt@3am-software.com>. All rights reserved.
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: if_ethersubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp
* $FreeBSD$
*/
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <net/if_types.h>
#include <net/if_llatbl.h>
#include <net/ethernet.h>
#include <net/netisr.h>
#include <net/route.h>
#include <net/bpf.h>
#include <net/fddi.h>
#if defined(INET) || defined(INET6)
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
#endif
#ifdef INET6
#include <netinet6/nd6.h>
#endif
#ifdef DECNET
#include <netdnet/dn.h>
#endif
#include <security/mac/mac_framework.h>
static const u_char fddibroadcastaddr[FDDI_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static int fddi_resolvemulti(struct ifnet *, struct sockaddr **,
struct sockaddr *);
static int fddi_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
struct route *);
static void fddi_input(struct ifnet *ifp, struct mbuf *m);
#define senderr(e) do { error = (e); goto bad; } while (0)
/*
* FDDI output routine.
* Encapsulate a packet of type family for the local net.
* Use trailer local net encapsulation if enough data in first
* packet leaves a multiple of 512 bytes of data in remainder.
*/
static int
fddi_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro)
{
u_int16_t type;
int loop_copy = 0, error = 0, hdrcmplt = 0;
u_char esrc[FDDI_ADDR_LEN], edst[FDDI_ADDR_LEN];
struct fddi_header *fh;
#if defined(INET) || defined(INET6)
int is_gw = 0;
#endif
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error)
senderr(error);
#endif
if (ifp->if_flags & IFF_MONITOR)
senderr(ENETDOWN);
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
senderr(ENETDOWN);
getmicrotime(&ifp->if_lastchange);
#if defined(INET) || defined(INET6)
if (ro != NULL)
is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
#endif
switch (dst->sa_family) {
#ifdef INET
case AF_INET: {
error = arpresolve(ifp, is_gw, m, dst, edst, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IP);
break;
}
case AF_ARP:
{
struct arphdr *ah;
ah = mtod(m, struct arphdr *);
ah->ar_hrd = htons(ARPHRD_ETHER);
loop_copy = -1; /* if this is for us, don't do it */
switch (ntohs(ah->ar_op)) {
case ARPOP_REVREQUEST:
case ARPOP_REVREPLY:
type = htons(ETHERTYPE_REVARP);
break;
case ARPOP_REQUEST:
case ARPOP_REPLY:
default:
type = htons(ETHERTYPE_ARP);
break;
}
if (m->m_flags & M_BCAST)
bcopy(ifp->if_broadcastaddr, edst, FDDI_ADDR_LEN);
else
bcopy(ar_tha(ah), edst, FDDI_ADDR_LEN);
}
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IPV6);
break;
#endif /* INET6 */
case pseudo_AF_HDRCMPLT:
{
const struct ether_header *eh;
hdrcmplt = 1;
eh = (const struct ether_header *)dst->sa_data;
bcopy(eh->ether_shost, esrc, FDDI_ADDR_LEN);
/* FALLTHROUGH */
}
case AF_UNSPEC:
{
const struct ether_header *eh;
loop_copy = -1;
eh = (const struct ether_header *)dst->sa_data;
bcopy(eh->ether_dhost, edst, FDDI_ADDR_LEN);
if (*edst & 1)
m->m_flags |= (M_BCAST|M_MCAST);
type = eh->ether_type;
break;
}
case AF_IMPLINK:
{
fh = mtod(m, struct fddi_header *);
error = EPROTONOSUPPORT;
switch (fh->fddi_fc & (FDDIFC_C|FDDIFC_L|FDDIFC_F)) {
case FDDIFC_LLC_ASYNC: {
/* legal priorities are 0 through 7 */
if ((fh->fddi_fc & FDDIFC_Z) > 7)
goto bad;
break;
}
case FDDIFC_LLC_SYNC: {
/* FDDIFC_Z bits reserved, must be zero */
if (fh->fddi_fc & FDDIFC_Z)
goto bad;
break;
}
case FDDIFC_SMT: {
/* FDDIFC_Z bits must be non zero */
if ((fh->fddi_fc & FDDIFC_Z) == 0)
goto bad;
break;
}
default: {
/* anything else is too dangerous */
goto bad;
}
}
error = 0;
if (fh->fddi_dhost[0] & 1)
m->m_flags |= (M_BCAST|M_MCAST);
goto queue_it;
}
default:
if_printf(ifp, "can't handle af%d\n", dst->sa_family);
senderr(EAFNOSUPPORT);
}
/*
* Add LLC header.
*/
if (type != 0) {
struct llc *l;
M_PREPEND(m, LLC_SNAPFRAMELEN, M_NOWAIT);
if (m == NULL)
senderr(ENOBUFS);
l = mtod(m, struct llc *);
l->llc_control = LLC_UI;
l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP;
l->llc_snap.org_code[0] =
l->llc_snap.org_code[1] =
l->llc_snap.org_code[2] = 0;
l->llc_snap.ether_type = htons(type);
}
/*
* Add local net header. If no space in first mbuf,
* allocate another.
*/
M_PREPEND(m, FDDI_HDR_LEN, M_NOWAIT);
if (m == NULL)
senderr(ENOBUFS);
fh = mtod(m, struct fddi_header *);
fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
bcopy((caddr_t)edst, (caddr_t)fh->fddi_dhost, FDDI_ADDR_LEN);
queue_it:
if (hdrcmplt)
bcopy((caddr_t)esrc, (caddr_t)fh->fddi_shost, FDDI_ADDR_LEN);
else
bcopy(IF_LLADDR(ifp), (caddr_t)fh->fddi_shost,
FDDI_ADDR_LEN);
/*
* If a simplex interface, and the packet is being sent to our
* Ethernet address or a broadcast address, loopback a copy.
* XXX To make a simplex device behave exactly like a duplex
* device, we should copy in the case of sending to our own
* ethernet address (thus letting the original actually appear
* on the wire). However, we don't do that here for security
* reasons and compatibility with the original behavior.
*/
if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
struct mbuf *n;
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
(void) if_simloop(ifp, n, dst->sa_family,
FDDI_HDR_LEN);
} else if (bcmp(fh->fddi_dhost, fh->fddi_shost,
FDDI_ADDR_LEN) == 0) {
(void) if_simloop(ifp, m, dst->sa_family,
FDDI_HDR_LEN);
return (0); /* XXX */
}
}
error = (ifp->if_transmit)(ifp, m);
if (error)
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return (error);
bad:
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
if (m)
m_freem(m);
return (error);
}
/*
* Process a received FDDI packet.
*/
static void
fddi_input(ifp, m)
struct ifnet *ifp;
struct mbuf *m;
{
int isr;
struct llc *l;
struct fddi_header *fh;
/*
* Do consistency checks to verify assumptions
* made by code past this point.
*/
if ((m->m_flags & M_PKTHDR) == 0) {
if_printf(ifp, "discard frame w/o packet header\n");
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
return;
}
if (m->m_pkthdr.rcvif == NULL) {
if_printf(ifp, "discard frame w/o interface pointer\n");
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
return;
}
m = m_pullup(m, FDDI_HDR_LEN);
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto dropanyway;
}
fh = mtod(m, struct fddi_header *);
/*
* Discard packet if interface is not up.
*/
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
goto dropanyway;
/*
* Give bpf a chance at the packet.
*/
BPF_MTAP(ifp, m);
/*
* Interface marked for monitoring; discard packet.
*/
if (ifp->if_flags & IFF_MONITOR) {
m_freem(m);
return;
}
#ifdef MAC
mac_ifnet_create_mbuf(ifp, m);
#endif
/*
* Update interface statistics.
*/
if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
getmicrotime(&ifp->if_lastchange);
/*
* Discard non local unicast packets when interface
* is in promiscuous mode.
*/
if ((ifp->if_flags & IFF_PROMISC) && ((fh->fddi_dhost[0] & 1) == 0) &&
(bcmp(IF_LLADDR(ifp), (caddr_t)fh->fddi_dhost,
FDDI_ADDR_LEN) != 0))
goto dropanyway;
/*
* Set mbuf flags for bcast/mcast.
*/
if (fh->fddi_dhost[0] & 1) {
if (bcmp(ifp->if_broadcastaddr, fh->fddi_dhost,
FDDI_ADDR_LEN) == 0)
m->m_flags |= M_BCAST;
else
m->m_flags |= M_MCAST;
if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1);
}
#ifdef M_LINK0
/*
* If this has a LLC priority of 0, then mark it so upper
* layers have a hint that it really came via a FDDI/Ethernet
* bridge.
*/
if ((fh->fddi_fc & FDDIFC_LLC_PRIO7) == FDDIFC_LLC_PRIO0)
m->m_flags |= M_LINK0;
#endif
/* Strip off FDDI header. */
m_adj(m, FDDI_HDR_LEN);
m = m_pullup(m, LLC_SNAPFRAMELEN);
if (m == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto dropanyway;
}
l = mtod(m, struct llc *);
switch (l->llc_dsap) {
case LLC_SNAP_LSAP:
{
u_int16_t type;
if ((l->llc_control != LLC_UI) ||
(l->llc_ssap != LLC_SNAP_LSAP)) {
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
goto dropanyway;
}
if (l->llc_snap.org_code[0] != 0 ||
l->llc_snap.org_code[1] != 0 ||
l->llc_snap.org_code[2] != 0) {
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
goto dropanyway;
}
type = ntohs(l->llc_snap.ether_type);
m_adj(m, LLC_SNAPFRAMELEN);
switch (type) {
#ifdef INET
case ETHERTYPE_IP:
isr = NETISR_IP;
break;
case ETHERTYPE_ARP:
if (ifp->if_flags & IFF_NOARP)
goto dropanyway;
isr = NETISR_ARP;
break;
#endif
#ifdef INET6
case ETHERTYPE_IPV6:
isr = NETISR_IPV6;
break;
#endif
#ifdef DECNET
case ETHERTYPE_DECNET:
isr = NETISR_DECNET;
break;
#endif
default:
/* printf("fddi_input: unknown protocol 0x%x\n", type); */
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
goto dropanyway;
}
break;
}
default:
/* printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap); */
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
goto dropanyway;
}
M_SETFIB(m, ifp->if_fib);
netisr_dispatch(isr, m);
return;
dropanyway:
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
if (m)
m_freem(m);
return;
}
/*
* Perform common duties while attaching to interface list
*/
void
fddi_ifattach(ifp, lla, bpf)
struct ifnet *ifp;
const u_int8_t *lla;
int bpf;
{
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
ifp->if_type = IFT_FDDI;
ifp->if_addrlen = FDDI_ADDR_LEN;
ifp->if_hdrlen = 21;
if_attach(ifp); /* Must be called before additional assignments */
ifp->if_mtu = FDDIMTU;
ifp->if_output = fddi_output;
ifp->if_input = fddi_input;
ifp->if_resolvemulti = fddi_resolvemulti;
ifp->if_broadcastaddr = fddibroadcastaddr;
ifp->if_baudrate = 100000000;
#ifdef IFF_NOTRAILERS
ifp->if_flags |= IFF_NOTRAILERS;
#endif
ifa = ifp->if_addr;
KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
sdl->sdl_type = IFT_FDDI;
sdl->sdl_alen = ifp->if_addrlen;
bcopy(lla, LLADDR(sdl), ifp->if_addrlen);
if (bpf)
bpfattach(ifp, DLT_FDDI, FDDI_HDR_LEN);
return;
}
void
fddi_ifdetach(ifp, bpf)
struct ifnet *ifp;
int bpf;
{
if (bpf)
bpfdetach(ifp);
if_detach(ifp);
return;
}
int
fddi_ioctl (ifp, command, data)
struct ifnet *ifp;
u_long command;
caddr_t data;
{
struct ifaddr *ifa;
struct ifreq *ifr;
int error;
ifa = (struct ifaddr *) data;
ifr = (struct ifreq *) data;
error = 0;
switch (command) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET: /* before arpwhohas */
ifp->if_init(ifp->if_softc);
arp_ifinit(ifp, ifa);
break;
#endif
default:
ifp->if_init(ifp->if_softc);
break;
}
break;
case SIOCGIFADDR:
bcopy(IF_LLADDR(ifp), &ifr->ifr_addr.sa_data[0],
FDDI_ADDR_LEN);
break;
case SIOCSIFMTU:
/*
* Set the interface MTU.
*/
if (ifr->ifr_mtu > FDDIMTU) {
error = EINVAL;
} else {
ifp->if_mtu = ifr->ifr_mtu;
}
break;
default:
error = EINVAL;
break;
}
return (error);
}
static int
fddi_resolvemulti(ifp, llsa, sa)
struct ifnet *ifp;
struct sockaddr **llsa;
struct sockaddr *sa;
{
struct sockaddr_dl *sdl;
#ifdef INET
struct sockaddr_in *sin;
#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
u_char *e_addr;
switch(sa->sa_family) {
case AF_LINK:
/*
* No mapping needed. Just check that it's a valid MC address.
*/
sdl = (struct sockaddr_dl *)sa;
e_addr = LLADDR(sdl);
if ((e_addr[0] & 1) != 1)
return (EADDRNOTAVAIL);
*llsa = NULL;
return (0);
#ifdef INET
case AF_INET:
sin = (struct sockaddr_in *)sa;
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
return (EADDRNOTAVAIL);
sdl = link_init_sdl(ifp, *llsa, IFT_FDDI);
sdl->sdl_nlen = 0;
sdl->sdl_alen = FDDI_ADDR_LEN;
sdl->sdl_slen = 0;
e_addr = LLADDR(sdl);
ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
*llsa = (struct sockaddr *)sdl;
return (0);
#endif
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)sa;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/*
* An IP6 address of 0 means listen to all
* of the Ethernet multicast address used for IP6.
* (This is used for multicast routers.)
*/
ifp->if_flags |= IFF_ALLMULTI;
*llsa = NULL;
return (0);
}
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return (EADDRNOTAVAIL);
sdl = link_init_sdl(ifp, *llsa, IFT_FDDI);
sdl->sdl_nlen = 0;
sdl->sdl_alen = FDDI_ADDR_LEN;
sdl->sdl_slen = 0;
e_addr = LLADDR(sdl);
ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
*llsa = (struct sockaddr *)sdl;
return (0);
#endif
default:
/*
* Well, the text isn't quite right, but it's the name
* that counts...
*/
return (EAFNOSUPPORT);
}
return (0);
}
static moduledata_t fddi_mod = {
"fddi", /* module name */
NULL, /* event handler */
0 /* extra data */
};
DECLARE_MODULE(fddi, fddi_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
MODULE_VERSION(fddi, 1);

View File

@@ -440,7 +440,7 @@ ipsec_if_input(struct mbuf *m, struct secasvar *sav, uint32_t af)
m->m_pkthdr.rcvif = ifp;
IPSEC_SC_RUNLOCK();
/* m_clrprotoflags(m); */
m_clrprotoflags(m);
M_SETFIB(m, ifp->if_fib);
BPF_MTAP2(ifp, &af, sizeof(af), m);
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);

View File

@@ -75,6 +75,18 @@ __FBSDID("$FreeBSD$");
#include <net/if_lagg.h>
#include <net/ieee8023ad_lacp.h>
#define LAGG_RLOCK() epoch_enter_preempt(net_epoch_preempt)
#define LAGG_RUNLOCK() epoch_exit_preempt(net_epoch_preempt)
#define LAGG_RLOCK_ASSERT() MPASS(in_epoch())
#define LAGG_UNLOCK_ASSERT() MPASS(!in_epoch())
#define LAGG_SX_INIT(_sc) sx_init(&(_sc)->sc_sx, "if_lagg sx")
#define LAGG_SX_DESTROY(_sc) sx_destroy(&(_sc)->sc_sx)
#define LAGG_XLOCK(_sc) sx_xlock(&(_sc)->sc_sx)
#define LAGG_XUNLOCK(_sc) sx_xunlock(&(_sc)->sc_sx)
#define LAGG_SXLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_LOCKED)
#define LAGG_XLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_XLOCKED)
/* Special flags we should propagate to the lagg ports. */
static struct {
int flag;
@@ -336,14 +348,11 @@ lagg_proto_detach(struct lagg_softc *sc)
lagg_proto pr;
LAGG_XLOCK_ASSERT(sc);
LAGG_WLOCK_ASSERT(sc);
pr = sc->sc_proto;
sc->sc_proto = LAGG_PROTO_NONE;
if (lagg_protos[pr].pr_detach != NULL)
lagg_protos[pr].pr_detach(sc);
else
LAGG_WUNLOCK(sc);
}
static int
@@ -439,10 +448,10 @@ lagg_register_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag)
if (ifp->if_softc != arg) /* Not our event */
return;
LAGG_SLOCK(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vtag);
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
}
/*
@@ -458,10 +467,10 @@ lagg_unregister_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag)
if (ifp->if_softc != arg) /* Not our event */
return;
LAGG_SLOCK(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp, vtag);
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
}
static int
@@ -477,7 +486,6 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
free(sc, M_DEVBUF);
return (ENOSPC);
}
LAGG_LOCK_INIT(sc);
LAGG_SX_INIT(sc);
LAGG_XLOCK(sc);
@@ -490,7 +498,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
lagg_proto_attach(sc, LAGG_PROTO_DEFAULT);
SLIST_INIT(&sc->sc_ports);
CK_SLIST_INIT(&sc->sc_ports);
/* Initialise pseudo media types */
ifmedia_init(&sc->sc_media, 0, lagg_media_change,
@@ -548,13 +556,11 @@ lagg_clone_destroy(struct ifnet *ifp)
EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
/* Shutdown and remove lagg ports */
while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
while ((lp = CK_SLIST_FIRST(&sc->sc_ports)) != NULL)
lagg_port_destroy(lp, 1);
/* Unhook the aggregation protocol */
LAGG_WLOCK(sc);
lagg_proto_detach(sc);
LAGG_UNLOCK_ASSERT(sc);
LAGG_XUNLOCK(sc);
ifmedia_removeall(&sc->sc_media);
@@ -566,7 +572,6 @@ lagg_clone_destroy(struct ifnet *ifp)
LAGG_LIST_UNLOCK();
LAGG_SX_DESTROY(sc);
LAGG_LOCK_DESTROY(sc);
free(sc, M_DEVBUF);
}
@@ -582,7 +587,7 @@ lagg_capabilities(struct lagg_softc *sc)
/* Get common enabled capabilities for the lagg ports */
ena = ~0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
ena &= lp->lp_ifp->if_capenable;
ena = (ena == ~0 ? 0 : ena);
@@ -592,7 +597,7 @@ lagg_capabilities(struct lagg_softc *sc)
*/
do {
pena = ena;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
lagg_setcaps(lp, ena);
ena &= lp->lp_ifp->if_capenable;
}
@@ -602,7 +607,7 @@ lagg_capabilities(struct lagg_softc *sc)
cap = ~0;
hwa = ~(uint64_t)0;
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
cap &= lp->lp_ifp->if_capabilities;
hwa &= lp->lp_ifp->if_hwassist;
if_hw_tsomax_common(lp->lp_ifp, &hw_tsomax);
@@ -653,7 +658,7 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
return (EPROTONOSUPPORT);
/* Allow the first Ethernet member to define the MTU */
if (SLIST_EMPTY(&sc->sc_ports))
if (CK_SLIST_EMPTY(&sc->sc_ports))
sc->sc_ifp->if_mtu = ifp->if_mtu;
else if (sc->sc_ifp->if_mtu != ifp->if_mtu) {
if_printf(sc->sc_ifp, "invalid MTU for %s\n",
@@ -690,19 +695,16 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN);
lp->lp_ifcapenable = ifp->if_capenable;
if (SLIST_EMPTY(&sc->sc_ports)) {
LAGG_WLOCK(sc);
if (CK_SLIST_EMPTY(&sc->sc_ports)) {
bcopy(IF_LLADDR(ifp), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
lagg_proto_lladdr(sc);
LAGG_WUNLOCK(sc);
EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp);
} else {
if_setlladdr(ifp, IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
}
lagg_setflags(lp, 1);
LAGG_WLOCK(sc);
if (SLIST_EMPTY(&sc->sc_ports))
if (CK_SLIST_EMPTY(&sc->sc_ports))
sc->sc_primary = lp;
/* Change the interface type */
@@ -725,28 +727,27 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
* is predictable and `ifconfig laggN create ...` command
* will lead to the same result each time.
*/
SLIST_FOREACH(tlp, &sc->sc_ports, lp_entries) {
LAGG_RLOCK();
CK_SLIST_FOREACH(tlp, &sc->sc_ports, lp_entries) {
if (tlp->lp_ifp->if_index < ifp->if_index && (
SLIST_NEXT(tlp, lp_entries) == NULL ||
SLIST_NEXT(tlp, lp_entries)->lp_ifp->if_index >
CK_SLIST_NEXT(tlp, lp_entries) == NULL ||
((struct lagg_port*)CK_SLIST_NEXT(tlp, lp_entries))->lp_ifp->if_index >
ifp->if_index))
break;
}
LAGG_RUNLOCK();
if (tlp != NULL)
SLIST_INSERT_AFTER(tlp, lp, lp_entries);
CK_SLIST_INSERT_AFTER(tlp, lp, lp_entries);
else
SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries);
CK_SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries);
sc->sc_count++;
lagg_setmulti(lp);
LAGG_WUNLOCK(sc);
if ((error = lagg_proto_addport(sc, lp)) != 0) {
/* Remove the port, without calling pr_delport. */
LAGG_WLOCK(sc);
lagg_port_destroy(lp, 0);
LAGG_UNLOCK_ASSERT(sc);
return (error);
}
@@ -766,7 +767,7 @@ lagg_port_checkstacking(struct lagg_softc *sc)
int m = 0;
LAGG_SXLOCK_ASSERT(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (lp->lp_flags & LAGG_PORT_STACK) {
sc_ptr = (struct lagg_softc *)lp->lp_ifp->if_softc;
m = MAX(m, lagg_port_checkstacking(sc_ptr));
@@ -777,6 +778,19 @@ lagg_port_checkstacking(struct lagg_softc *sc)
}
#endif
static void
lagg_port_destroy_cb(epoch_context_t ec)
{
struct lagg_port *lp;
struct ifnet *ifp;
lp = __containerof(ec, struct lagg_port, lp_epoch_ctx);
ifp = lp->lp_ifp;
if_rele(ifp);
free(lp, M_DEVBUF);
}
static int
lagg_port_destroy(struct lagg_port *lp, int rundelport)
{
@@ -788,11 +802,8 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport)
LAGG_XLOCK_ASSERT(sc);
if (rundelport) {
LAGG_WLOCK(sc);
if (rundelport)
lagg_proto_delport(sc, lp);
} else
LAGG_WLOCK_ASSERT(sc);
if (lp->lp_detaching == 0)
lagg_clrmulti(lp);
@@ -811,14 +822,14 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport)
}
/* Finally, remove the port from the lagg */
SLIST_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entries);
CK_SLIST_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entries);
sc->sc_count--;
/* Update the primary interface */
if (lp == sc->sc_primary) {
uint8_t lladdr[ETHER_ADDR_LEN];
if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL)
if ((lp0 = CK_SLIST_FIRST(&sc->sc_ports)) == NULL)
bzero(&lladdr, ETHER_ADDR_LEN);
else
bcopy(lp0->lp_lladdr, lladdr, ETHER_ADDR_LEN);
@@ -826,19 +837,16 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport)
if (sc->sc_destroying == 0) {
bcopy(lladdr, IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
lagg_proto_lladdr(sc);
LAGG_WUNLOCK(sc);
EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp);
} else
LAGG_WUNLOCK(sc);
}
/*
* Update lladdr for each port (new primary needs update
* as well, to switch from old lladdr to its 'real' one)
*/
SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries)
CK_SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries)
if_setlladdr(lp_ptr->lp_ifp, lladdr, ETHER_ADDR_LEN);
} else
LAGG_WUNLOCK(sc);
}
if (lp->lp_ifflags)
if_printf(ifp, "%s: lp_ifflags unclean\n", __func__);
@@ -849,9 +857,11 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport)
if_setlladdr(ifp, lp->lp_lladdr, ETHER_ADDR_LEN);
}
if_rele(ifp);
free(lp, M_DEVBUF);
/*
* free port and release it's ifnet reference after a grace period has
* elapsed.
*/
epoch_call(net_epoch_preempt, &lp->lp_epoch_ctx, lagg_port_destroy_cb);
/* Update lagg capabilities */
lagg_capabilities(sc);
lagg_linkstate(sc);
@@ -880,15 +890,15 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
LAGG_SLOCK(sc);
LAGG_RLOCK();
if ((lp = ifp->if_lagg) == NULL || lp->lp_softc != sc) {
error = ENOENT;
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
break;
}
lagg_port2req(lp, rp);
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
break;
case SIOCSIFCAP:
@@ -944,17 +954,16 @@ lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
struct lagg_softc *sc;
struct lagg_port *lp;
struct ifnet *lpifp;
struct rm_priotracker tracker;
uint64_t newval, oldval, vsum;
/* Revise this when we've got non-generic counters. */
KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
sc = (struct lagg_softc *)ifp->if_softc;
LAGG_RLOCK(sc, &tracker);
vsum = 0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
/* Saved attached value */
oldval = lp->port_counters.val[cnt];
/* current value */
@@ -963,6 +972,7 @@ lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
/* Calculate diff and save new */
vsum += newval - oldval;
}
LAGG_RUNLOCK();
/*
* Add counter data which might be added by upper
@@ -975,7 +985,6 @@ lagg_get_counter(struct ifnet *ifp, ift_counter cnt)
*/
vsum += sc->detached_counters.val[cnt];
LAGG_RUNLOCK(sc, &tracker);
return (vsum);
}
@@ -1081,7 +1090,7 @@ lagg_init(void *xsc)
* This might be if_setlladdr() notification
* that lladdr has been changed.
*/
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (memcmp(IF_LLADDR(ifp), IF_LLADDR(lp->lp_ifp),
ETHER_ADDR_LEN) != 0)
if_setlladdr(lp->lp_ifp, IF_LLADDR(ifp), ETHER_ADDR_LEN);
@@ -1126,7 +1135,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
switch (cmd) {
case SIOCGLAGG:
LAGG_SLOCK(sc);
LAGG_XLOCK(sc);
buflen = sc->sc_count * sizeof(struct lagg_reqport);
outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
ra->ra_proto = sc->sc_proto;
@@ -1134,7 +1143,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
count = 0;
buf = outbuf;
len = min(ra->ra_size, buflen);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (len < sizeof(rpbuf))
break;
@@ -1144,7 +1153,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
buf += sizeof(rpbuf);
len -= sizeof(rpbuf);
}
LAGG_SUNLOCK(sc);
LAGG_XUNLOCK(sc);
ra->ra_ports = count;
ra->ra_size = count * sizeof(rpbuf);
error = copyout(outbuf, ra->ra_port, ra->ra_size);
@@ -1160,14 +1169,13 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
LAGG_XLOCK(sc);
LAGG_WLOCK(sc);
lagg_proto_detach(sc);
LAGG_UNLOCK_ASSERT(sc);
LAGG_UNLOCK_ASSERT();
lagg_proto_attach(sc, ra->ra_proto);
LAGG_XUNLOCK(sc);
break;
case SIOCGLAGGOPTS:
LAGG_SLOCK(sc);
LAGG_XLOCK(sc);
ro->ro_opts = sc->sc_opts;
if (sc->sc_proto == LAGG_PROTO_LACP) {
struct lacp_softc *lsc;
@@ -1185,13 +1193,13 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ro->ro_active = sc->sc_active;
} else {
ro->ro_active = 0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
ro->ro_active += LAGG_PORTACTIVE(lp);
}
ro->ro_bkt = sc->sc_bkt;
ro->ro_flapping = sc->sc_flapping;
ro->ro_flowid_shift = sc->flowid_shift;
LAGG_SUNLOCK(sc);
LAGG_XUNLOCK(sc);
break;
case SIOCSLAGGOPTS:
if (sc->sc_proto == LAGG_PROTO_ROUNDROBIN) {
@@ -1298,14 +1306,14 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCGLAGGFLAGS:
rf->rf_flags = 0;
LAGG_SLOCK(sc);
LAGG_XLOCK(sc);
if (sc->sc_flags & MBUF_HASHFLAG_L2)
rf->rf_flags |= LAGG_F_HASHL2;
if (sc->sc_flags & MBUF_HASHFLAG_L3)
rf->rf_flags |= LAGG_F_HASHL3;
if (sc->sc_flags & MBUF_HASHFLAG_L4)
rf->rf_flags |= LAGG_F_HASHL4;
LAGG_SUNLOCK(sc);
LAGG_XUNLOCK(sc);
break;
case SIOCSLAGGHASH:
error = priv_check(td, PRIV_NET_LAGG);
@@ -1332,17 +1340,17 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
LAGG_SLOCK(sc);
LAGG_RLOCK();
if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL ||
lp->lp_softc != sc) {
error = ENOENT;
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
if_rele(tpif);
break;
}
lagg_port2req(lp, rp);
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
if_rele(tpif);
break;
case SIOCSLAGGPORT:
@@ -1407,7 +1415,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
/* Set flags on ports too */
LAGG_XLOCK(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
lagg_setflags(lp, 1);
}
@@ -1432,12 +1440,12 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
LAGG_WLOCK(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
LAGG_XLOCK(sc);
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
lagg_clrmulti(lp);
lagg_setmulti(lp);
}
LAGG_WUNLOCK(sc);
LAGG_XUNLOCK(sc);
error = 0;
break;
case SIOCSIFMEDIA:
@@ -1447,7 +1455,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFCAP:
LAGG_XLOCK(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (lp->lp_ioctl != NULL)
(*lp->lp_ioctl)(lp->lp_ifp, cmd, data);
}
@@ -1525,9 +1533,8 @@ lagg_setmulti(struct lagg_port *lp)
struct ifmultiaddr *ifma;
int error;
LAGG_WLOCK_ASSERT(sc);
IF_ADDR_WLOCK(scifp);
TAILQ_FOREACH(ifma, &scifp->if_multiaddrs, ifma_link) {
CK_STAILQ_FOREACH(ifma, &scifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT);
@@ -1556,7 +1563,7 @@ lagg_clrmulti(struct lagg_port *lp)
{
struct lagg_mc *mc;
LAGG_WLOCK_ASSERT(lp->lp_softc);
LAGG_XLOCK_ASSERT(lp->lp_softc);
while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) {
SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries);
if (mc->mc_ifma && lp->lp_detaching == 0)
@@ -1636,16 +1643,12 @@ static int
lagg_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
int error, len, mcast;
struct rm_priotracker tracker;
int error;
len = m->m_pkthdr.len;
mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0;
LAGG_RLOCK(sc, &tracker);
LAGG_RLOCK();
/* We need a Tx algorithm and at least one port */
if (sc->sc_proto == LAGG_PROTO_NONE || sc->sc_count == 0) {
LAGG_RUNLOCK(sc, &tracker);
LAGG_RUNLOCK();
m_freem(m);
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return (ENXIO);
@@ -1654,7 +1657,7 @@ lagg_transmit(struct ifnet *ifp, struct mbuf *m)
ETHER_BPF_MTAP(ifp, m);
error = lagg_proto_start(sc, m);
LAGG_RUNLOCK(sc, &tracker);
LAGG_RUNLOCK();
if (error != 0)
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
@@ -1676,33 +1679,25 @@ lagg_input(struct ifnet *ifp, struct mbuf *m)
struct lagg_port *lp = ifp->if_lagg;
struct lagg_softc *sc = lp->lp_softc;
struct ifnet *scifp = sc->sc_ifp;
struct rm_priotracker tracker;
LAGG_RLOCK(sc, &tracker);
LAGG_RLOCK();
if ((scifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
(lp->lp_flags & LAGG_PORT_DISABLED) ||
lp->lp_detaching != 0 ||
sc->sc_proto == LAGG_PROTO_NONE) {
LAGG_RUNLOCK(sc, &tracker);
LAGG_RUNLOCK();
m_freem(m);
return (NULL);
}
ETHER_BPF_MTAP(scifp, m);
if (lp->lp_detaching != 0) {
m = lagg_proto_input(sc, lp, m);
if (m != NULL && (scifp->if_flags & IFF_MONITOR) != 0) {
m_freem(m);
m = NULL;
} else
m = lagg_proto_input(sc, lp, m);
if (m != NULL) {
if (scifp->if_flags & IFF_MONITOR) {
m_freem(m);
m = NULL;
}
}
LAGG_RUNLOCK(sc, &tracker);
LAGG_RUNLOCK();
return (m);
}
@@ -1727,12 +1722,12 @@ lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr)
imr->ifm_status = IFM_AVALID;
imr->ifm_active = IFM_ETHER | IFM_AUTO;
LAGG_SLOCK(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (LAGG_PORTACTIVE(lp))
imr->ifm_status |= IFM_ACTIVE;
}
LAGG_SUNLOCK(sc);
LAGG_RUNLOCK();
}
static void
@@ -1745,12 +1740,14 @@ lagg_linkstate(struct lagg_softc *sc)
LAGG_XLOCK_ASSERT(sc);
/* Our link is considered up if at least one of our ports is active */
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (lp->lp_ifp->if_link_state == LINK_STATE_UP) {
new_link = LINK_STATE_UP;
break;
}
}
LAGG_RUNLOCK();
if_link_state_change(sc->sc_ifp, new_link);
/* Update if_baudrate to reflect the max possible speed */
@@ -1763,8 +1760,10 @@ lagg_linkstate(struct lagg_softc *sc)
case LAGG_PROTO_LOADBALANCE:
case LAGG_PROTO_BROADCAST:
speed = 0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
speed += lp->lp_ifp->if_baudrate;
LAGG_RUNLOCK();
sc->sc_ifp->if_baudrate = speed;
break;
case LAGG_PROTO_LACP:
@@ -1805,20 +1804,22 @@ lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp)
rval = lp;
goto found;
}
if ((lp_next = SLIST_NEXT(lp, lp_entries)) != NULL &&
if ((lp_next = CK_SLIST_NEXT(lp, lp_entries)) != NULL &&
LAGG_PORTACTIVE(lp_next)) {
rval = lp_next;
goto found;
}
search:
SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) {
search:
LAGG_RLOCK();
CK_SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) {
if (LAGG_PORTACTIVE(lp_next)) {
LAGG_RUNLOCK();
rval = lp_next;
goto found;
}
}
LAGG_RUNLOCK();
found:
return (rval);
}
@@ -1859,10 +1860,10 @@ lagg_rr_start(struct lagg_softc *sc, struct mbuf *m)
p = atomic_fetchadd_32(&sc->sc_seq, 1);
p %= sc->sc_count;
lp = SLIST_FIRST(&sc->sc_ports);
lp = CK_SLIST_FIRST(&sc->sc_ports);
while (p--)
lp = SLIST_NEXT(lp, lp_entries);
lp = CK_SLIST_NEXT(lp, lp_entries);
/*
* Check the port's link state. This will return the next active
@@ -1900,7 +1901,8 @@ lagg_bcast_start(struct lagg_softc *sc, struct mbuf *m)
struct lagg_port *lp, *last = NULL;
struct mbuf *m0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
LAGG_RLOCK();
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (!LAGG_PORTACTIVE(lp))
continue;
@@ -1920,6 +1922,8 @@ lagg_bcast_start(struct lagg_softc *sc, struct mbuf *m)
}
last = lp;
}
LAGG_RUNLOCK();
if (last == NULL) {
m_freem(m);
return (ENOENT);
@@ -2003,11 +2007,12 @@ lagg_lb_attach(struct lagg_softc *sc)
struct lagg_port *lp;
struct lagg_lb *lb;
LAGG_XLOCK_ASSERT(sc);
lb = malloc(sizeof(struct lagg_lb), M_DEVBUF, M_WAITOK | M_ZERO);
lb->lb_key = m_ether_tcpip_hash_init();
sc->sc_psc = lb;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
lagg_lb_port_create(lp);
}
@@ -2017,7 +2022,6 @@ lagg_lb_detach(struct lagg_softc *sc)
struct lagg_lb *lb;
lb = (struct lagg_lb *)sc->sc_psc;
LAGG_WUNLOCK(sc);
if (lb != NULL)
free(lb, M_DEVBUF);
}
@@ -2030,7 +2034,8 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_port *lp)
int i = 0;
bzero(&lb->lb_ports, sizeof(lb->lb_ports));
SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) {
LAGG_RLOCK();
CK_SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) {
if (lp_next == lp)
continue;
if (i >= LAGG_MAX_PORTS)
@@ -2040,6 +2045,7 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_port *lp)
sc->sc_ifname, lp_next->lp_ifp->if_xname, i);
lb->lb_ports[i++] = lp_next;
}
LAGG_RUNLOCK();
return (0);
}
@@ -2106,7 +2112,8 @@ lagg_lacp_attach(struct lagg_softc *sc)
struct lagg_port *lp;
lacp_attach(sc);
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
LAGG_XLOCK_ASSERT(sc);
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
lacp_port_create(lp);
}
@@ -2116,13 +2123,12 @@ lagg_lacp_detach(struct lagg_softc *sc)
struct lagg_port *lp;
void *psc;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
LAGG_XLOCK_ASSERT(sc);
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
lacp_port_destroy(lp);
psc = sc->sc_psc;
sc->sc_psc = NULL;
LAGG_WUNLOCK(sc);
lacp_detach(psc);
}
@@ -2134,11 +2140,11 @@ lagg_lacp_lladdr(struct lagg_softc *sc)
LAGG_SXLOCK_ASSERT(sc);
/* purge all the lacp ports */
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
lacp_port_destroy(lp);
/* add them back in */
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
lacp_port_create(lp);
}

View File

@@ -42,9 +42,8 @@
#define LAGG_PORT_ACTIVE 0x00000004 /* port is active */
#define LAGG_PORT_COLLECTING 0x00000008 /* port is receiving frames */
#define LAGG_PORT_DISTRIBUTING 0x00000010 /* port is sending frames */
#define LAGG_PORT_DISABLED 0x00000020 /* port is disabled */
#define LAGG_PORT_BITS "\20\01MASTER\02STACK\03ACTIVE\04COLLECTING" \
"\05DISTRIBUTING\06DISABLED"
"\05DISTRIBUTING"
/* Supported lagg PROTOs */
typedef enum {
@@ -218,7 +217,7 @@ struct lagg_softc {
uint32_t sc_flags;
int sc_destroying; /* destroying lagg */
SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */
CK_SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */
SLIST_ENTRY(lagg_softc) sc_entries;
eventhandler_tag vlan_attach;
@@ -252,29 +251,10 @@ struct lagg_port {
const struct sockaddr *, struct route *);
struct lagg_counters port_counters; /* ifp counters copy */
SLIST_ENTRY(lagg_port) lp_entries;
CK_SLIST_ENTRY(lagg_port) lp_entries;
struct epoch_context lp_epoch_ctx;
};
#define LAGG_LOCK_INIT(_sc) rm_init(&(_sc)->sc_mtx, "if_lagg rmlock")
#define LAGG_LOCK_DESTROY(_sc) rm_destroy(&(_sc)->sc_mtx)
#define LAGG_RLOCK(_sc, _p) rm_rlock(&(_sc)->sc_mtx, (_p))
#define LAGG_WLOCK(_sc) rm_wlock(&(_sc)->sc_mtx)
#define LAGG_RUNLOCK(_sc, _p) rm_runlock(&(_sc)->sc_mtx, (_p))
#define LAGG_WUNLOCK(_sc) rm_wunlock(&(_sc)->sc_mtx)
#define LAGG_RLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_RLOCKED)
#define LAGG_WLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_WLOCKED)
#define LAGG_UNLOCK_ASSERT(_sc) rm_assert(&(_sc)->sc_mtx, RA_UNLOCKED)
#define LAGG_SX_INIT(_sc) sx_init(&(_sc)->sc_sx, "if_lagg sx")
#define LAGG_SX_DESTROY(_sc) sx_destroy(&(_sc)->sc_sx)
#define LAGG_SLOCK(_sc) sx_slock(&(_sc)->sc_sx)
#define LAGG_XLOCK(_sc) sx_xlock(&(_sc)->sc_sx)
#define LAGG_SUNLOCK(_sc) sx_sunlock(&(_sc)->sc_sx)
#define LAGG_XUNLOCK(_sc) sx_xunlock(&(_sc)->sc_sx)
#define LAGG_SXLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_LOCKED)
#define LAGG_SLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_SLOCKED)
#define LAGG_XLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SA_XLOCKED)
extern struct mbuf *(*lagg_input_p)(struct ifnet *, struct mbuf *);
extern void (*lagg_linkstate_p)(struct ifnet *, int );

View File

@@ -148,7 +148,7 @@ htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
error = 0;
for (i = 0; i < llt->llt_hsize; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
CK_LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
error = f(llt, lle, farg);
if (error != 0)
break;
@@ -175,7 +175,7 @@ htable_link_entry(struct lltable *llt, struct llentry *lle)
lle->lle_tbl = llt;
lle->lle_head = lleh;
lle->la_flags |= LLE_LINKED;
LIST_INSERT_HEAD(lleh, lle, lle_next);
CK_LIST_INSERT_HEAD(lleh, lle, lle_next);
}
static void
@@ -184,7 +184,7 @@ htable_unlink_entry(struct llentry *lle)
if ((lle->la_flags & LLE_LINKED) != 0) {
IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
LIST_REMOVE(lle, lle_next);
CK_LIST_REMOVE(lle, lle_next);
lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
#if 0
lle->lle_tbl = NULL;
@@ -209,7 +209,7 @@ htable_prefix_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
if (llt->llt_match_prefix(pmd->addr, pmd->mask, pmd->flags, lle)) {
LLE_WLOCK(lle);
LIST_INSERT_HEAD(&pmd->dchain, lle, lle_chain);
CK_LIST_INSERT_HEAD(&pmd->dchain, lle, lle_chain);
}
return (0);
@@ -226,7 +226,7 @@ htable_prefix_free(struct lltable *llt, const struct sockaddr *addr,
pmd.addr = addr;
pmd.mask = mask;
pmd.flags = flags;
LIST_INIT(&pmd.dchain);
CK_LIST_INIT(&pmd.dchain);
IF_AFDATA_WLOCK(llt->llt_ifp);
/* Push matching lles to chain */
@@ -235,7 +235,7 @@ htable_prefix_free(struct lltable *llt, const struct sockaddr *addr,
llentries_unlink(llt, &pmd.dchain);
IF_AFDATA_WUNLOCK(llt->llt_ifp);
LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next)
CK_LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next)
lltable_free_entry(llt, lle);
}
@@ -252,7 +252,7 @@ llentries_unlink(struct lltable *llt, struct llentries *head)
{
struct llentry *lle, *next;
LIST_FOREACH_SAFE(lle, head, lle_chain, next)
CK_LIST_FOREACH_SAFE(lle, head, lle_chain, next)
llt->llt_unlink_entry(lle);
}
@@ -498,7 +498,7 @@ lltable_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
dchain = (struct llentries *)farg;
LLE_WLOCK(lle);
LIST_INSERT_HEAD(dchain, lle, lle_chain);
CK_LIST_INSERT_HEAD(dchain, lle, lle_chain);
return (0);
}
@@ -516,14 +516,14 @@ lltable_free(struct lltable *llt)
lltable_unlink(llt);
LIST_INIT(&dchain);
CK_LIST_INIT(&dchain);
IF_AFDATA_WLOCK(llt->llt_ifp);
/* Push all lles to @dchain */
lltable_foreach_lle(llt, lltable_free_cb, &dchain);
llentries_unlink(llt, &dchain);
IF_AFDATA_WUNLOCK(llt->llt_ifp);
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
CK_LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
if (callout_stop(&lle->lle_timer) > 0)
LLE_REMREF(lle);
llentry_free(lle);
@@ -546,7 +546,7 @@ lltable_drain(int af)
continue;
for (i=0; i < llt->llt_hsize; i++) {
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
CK_LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
LLE_WLOCK(lle);
if (lle->la_hold) {
m_freem(lle->la_hold);
@@ -622,7 +622,7 @@ lltable_allocate_htbl(uint32_t hsize)
M_LLTABLE, M_WAITOK | M_ZERO);
for (i = 0; i < llt->llt_hsize; i++)
LIST_INIT(&llt->lle_head[i]);
CK_LIST_INIT(&llt->lle_head[i]);
/* Set some default callbacks */
llt->llt_link_entry = htable_link_entry;
@@ -848,7 +848,7 @@ llatbl_lle_show(struct llentry_sa *la)
lle = &la->base;
db_printf("lle=%p\n", lle);
db_printf(" lle_next=%p\n", lle->lle_next.le_next);
db_printf(" lle_next=%p\n", lle->lle_next.cle_next);
db_printf(" lle_lock=%p\n", &lle->lle_lock);
db_printf(" lle_tbl=%p\n", lle->lle_tbl);
db_printf(" lle_head=%p\n", lle->lle_head);
@@ -919,7 +919,7 @@ llatbl_llt_show(struct lltable *llt)
llt, llt->llt_af, llt->llt_ifp);
for (i = 0; i < llt->llt_hsize; i++) {
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
CK_LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
llatbl_lle_show((struct llentry_sa *)lle);
if (db_pager_quit)

View File

@@ -34,13 +34,15 @@ __FBSDID("$FreeBSD$");
#include <sys/_rwlock.h>
#include <netinet/in.h>
#include <sys/epoch.h>
#include <sys/ck.h>
struct ifnet;
struct sysctl_req;
struct rt_msghdr;
struct rt_addrinfo;
struct llentry;
LIST_HEAD(llentries, llentry);
CK_LIST_HEAD(llentries, llentry);
#define LLE_MAX_LINKHDR 24 /* Full IB header */
/*
@@ -48,7 +50,7 @@ LIST_HEAD(llentries, llentry);
* a shared lock
*/
struct llentry {
LIST_ENTRY(llentry) lle_next;
CK_LIST_ENTRY(llentry) lle_next;
union {
struct in_addr addr4;
struct in6_addr addr6;
@@ -76,10 +78,11 @@ struct llentry {
int lle_refcnt;
char *ll_addr; /* link-layer address */
LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
CK_LIST_ENTRY(llentry) lle_chain; /* chain of deleted items */
struct callout lle_timer;
struct rwlock lle_lock;
struct mtx req_mtx;
struct epoch_context lle_epoch_ctx;
};
#define LLE_WLOCK(lle) rw_wlock(&(lle)->lle_lock)

View File

@@ -138,7 +138,7 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
ifp->if_output = looutput;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_capabilities = ifp->if_capenable =
IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6;
IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 | IFCAP_LINKSTATE;
ifp->if_hwassist = LO_CSUM_FEATURES | LO_CSUM_FEATURES6;
if_attach(ifp);
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
@@ -415,6 +415,8 @@ loioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSIFFLAGS:
if_link_state_change(ifp, (ifp->if_flags & IFF_UP) ?
LINK_STATE_UP: LINK_STATE_DOWN);
break;
case SIOCSIFCAP:

View File

@@ -401,18 +401,6 @@ struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
struct ifmedia_description ifm_subtype_tokenring_descriptions[] =
IFM_SUBTYPE_TOKENRING_DESCRIPTIONS;
struct ifmedia_description ifm_subtype_tokenring_option_descriptions[] =
IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS;
struct ifmedia_description ifm_subtype_fddi_descriptions[] =
IFM_SUBTYPE_FDDI_DESCRIPTIONS;
struct ifmedia_description ifm_subtype_fddi_option_descriptions[] =
IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS;
struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
@@ -447,16 +435,6 @@ struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
&ifm_subtype_ethernet_option_descriptions[0],
NULL,
},
{
&ifm_subtype_tokenring_descriptions[0],
&ifm_subtype_tokenring_option_descriptions[0],
NULL,
},
{
&ifm_subtype_fddi_descriptions[0],
&ifm_subtype_fddi_option_descriptions[0],
NULL,
},
{
&ifm_subtype_ieee80211_descriptions[0],
&ifm_subtype_ieee80211_option_descriptions[0],

View File

@@ -216,32 +216,6 @@ uint64_t ifmedia_baudrate(int);
#define IFM_ETH_XTYPE 0x00007800 /* extended media variants */
#define IFM_ETH_XSHIFT 6 /* shift XTYPE next to TMASK */
/*
* Token ring
*/
#define IFM_TOKEN 0x00000040
#define IFM_TOK_STP4 3 /* Shielded twisted pair 4m - DB9 */
#define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */
#define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */
#define IFM_TOK_UTP16 6 /* Unshielded twisted pair 16m - RJ45 */
#define IFM_TOK_STP100 7 /* Shielded twisted pair 100m - DB9 */
#define IFM_TOK_UTP100 8 /* Unshielded twisted pair 100m - RJ45 */
#define IFM_TOK_ETR 0x00000200 /* Early token release */
#define IFM_TOK_SRCRT 0x00000400 /* Enable source routing features */
#define IFM_TOK_ALLR 0x00000800 /* All routes / Single route bcast */
#define IFM_TOK_DTR 0x00002000 /* Dedicated token ring */
#define IFM_TOK_CLASSIC 0x00004000 /* Classic token ring */
#define IFM_TOK_AUTO 0x00008000 /* Automatic Dedicate/Classic token ring */
/*
* FDDI
*/
#define IFM_FDDI 0x00000060
#define IFM_FDDI_SMF 3 /* Single-mode fiber */
#define IFM_FDDI_MMF 4 /* Multi-mode fiber */
#define IFM_FDDI_UTP 5 /* CDDI / UTP */
#define IFM_FDDI_DA 0x00000100 /* Dual attach / single attach */
/*
* IEEE 802.11 Wireless
*/
@@ -393,8 +367,6 @@ struct ifmedia_description {
#define IFM_TYPE_DESCRIPTIONS { \
{ IFM_ETHER, "Ethernet" }, \
{ IFM_TOKEN, "Token ring" }, \
{ IFM_FDDI, "FDDI" }, \
{ IFM_IEEE80211, "IEEE 802.11 Wireless Ethernet" }, \
{ IFM_ATM, "ATM" }, \
{ 0, NULL }, \
@@ -511,55 +483,6 @@ struct ifmedia_description {
{ 0, NULL }, \
}
#define IFM_SUBTYPE_TOKENRING_DESCRIPTIONS { \
{ IFM_TOK_STP4, "DB9/4Mbit" }, \
{ IFM_TOK_STP16, "DB9/16Mbit" }, \
{ IFM_TOK_UTP4, "UTP/4Mbit" }, \
{ IFM_TOK_UTP16, "UTP/16Mbit" }, \
{ IFM_TOK_STP100, "STP/100Mbit" }, \
{ IFM_TOK_UTP100, "UTP/100Mbit" }, \
{ 0, NULL }, \
}
#define IFM_SUBTYPE_TOKENRING_ALIASES { \
{ IFM_TOK_STP4, "4STP" }, \
{ IFM_TOK_STP16, "16STP" }, \
{ IFM_TOK_UTP4, "4UTP" }, \
{ IFM_TOK_UTP16, "16UTP" }, \
{ IFM_TOK_STP100, "100STP" }, \
{ IFM_TOK_UTP100, "100UTP" }, \
{ 0, NULL }, \
}
#define IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS { \
{ IFM_TOK_ETR, "EarlyTokenRelease" }, \
{ IFM_TOK_SRCRT, "SourceRouting" }, \
{ IFM_TOK_ALLR, "AllRoutes" }, \
{ IFM_TOK_DTR, "Dedicated" }, \
{ IFM_TOK_CLASSIC,"Classic" }, \
{ IFM_TOK_AUTO, " " }, \
{ 0, NULL }, \
}
#define IFM_SUBTYPE_FDDI_DESCRIPTIONS { \
{ IFM_FDDI_SMF, "Single-mode" }, \
{ IFM_FDDI_MMF, "Multi-mode" }, \
{ IFM_FDDI_UTP, "UTP" }, \
{ 0, NULL }, \
}
#define IFM_SUBTYPE_FDDI_ALIASES { \
{ IFM_FDDI_SMF, "SMF" }, \
{ IFM_FDDI_MMF, "MMF" }, \
{ IFM_FDDI_UTP, "CDDI" }, \
{ 0, NULL }, \
}
#define IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS { \
{ IFM_FDDI_DA, "Dual-attach" }, \
{ 0, NULL }, \
}
#define IFM_SUBTYPE_IEEE80211_DESCRIPTIONS { \
{ IFM_IEEE80211_FH1, "FH/1Mbps" }, \
{ IFM_IEEE80211_FH2, "FH/2Mbps" }, \
@@ -797,15 +720,6 @@ struct ifmedia_baudrate {
{ IFM_ETHER | IFM_25G_ACC, IF_Gbps(25ULL) }, \
{ IFM_ETHER | IFM_25G_AOC, IF_Gbps(25ULL) }, \
\
{ IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \
{ IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \
{ IFM_TOKEN | IFM_TOK_UTP4, IF_Mbps(4) }, \
{ IFM_TOKEN | IFM_TOK_UTP16, IF_Mbps(16) }, \
\
{ IFM_FDDI | IFM_FDDI_SMF, IF_Mbps(100) }, \
{ IFM_FDDI | IFM_FDDI_MMF, IF_Mbps(100) }, \
{ IFM_FDDI | IFM_FDDI_UTP, IF_Mbps(100) }, \
\
{ IFM_IEEE80211 | IFM_IEEE80211_FH1, IF_Mbps(1) }, \
{ IFM_IEEE80211 | IFM_IEEE80211_FH2, IF_Mbps(2) }, \
{ IFM_IEEE80211 | IFM_IEEE80211_DS2, IF_Mbps(2) }, \
@@ -842,10 +756,6 @@ struct ifmedia_status_description {
#define IFM_STATUS_DESCRIPTIONS { \
{ IFM_ETHER, IFM_AVALID, IFM_ACTIVE, \
{ "no carrier", "active" } }, \
{ IFM_FDDI, IFM_AVALID, IFM_ACTIVE, \
{ "no ring", "inserted" } }, \
{ IFM_TOKEN, IFM_AVALID, IFM_ACTIVE, \
{ "no ring", "inserted" } }, \
{ IFM_IEEE80211, IFM_AVALID, IFM_ACTIVE, \
{ "no network", "active" } }, \
{ IFM_ATM, IFM_AVALID, IFM_ACTIVE, \

View File

@@ -4839,7 +4839,7 @@ sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask)
*/
si = NULL;
if_addr_rlock(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (ifa->ifa_addr->sa_family == AF_INET) {
si = (struct sockaddr_in *)ifa->ifa_addr;
sm = (struct sockaddr_in *)ifa->ifa_netmask;
@@ -4881,7 +4881,7 @@ sppp_set_ip_addr(struct sppp *sp, u_long src)
*/
si = NULL;
if_addr_rlock(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == AF_INET) {
si = (struct sockaddr_in *)ifa->ifa_addr;
if (si != NULL) {
@@ -4943,7 +4943,7 @@ sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, struct in6_addr *dst,
*/
si = NULL;
if_addr_rlock(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (ifa->ifa_addr->sa_family == AF_INET6) {
si = (struct sockaddr_in6 *)ifa->ifa_addr;
sm = (struct sockaddr_in6 *)ifa->ifa_netmask;
@@ -4998,7 +4998,7 @@ sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src)
sin6 = NULL;
if_addr_rlock(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
if (sin6 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {

View File

@@ -278,7 +278,7 @@ static int
stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp)
{
struct stf_softc *sc = ifp->if_softc;
int err;
int err __unused;
err = encap_detach(sc->encap_cookie);
KASSERT(err == 0, ("Unexpected error detaching encap_cookie"));
@@ -386,7 +386,7 @@ stf_getsrcifa6(struct ifnet *ifp, struct in6_addr *addr, struct in6_addr *mask)
struct in_addr in;
if_addr_rlock(ifp);
TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
if (ia->ifa_addr->sa_family != AF_INET6)
continue;
sin6 = (struct sockaddr_in6 *)ia->ifa_addr;
@@ -563,7 +563,7 @@ stf_checkaddr4(struct stf_softc *sc, struct in_addr *in, struct ifnet *inifp)
* reject packets with broadcast
*/
IN_IFADDR_RLOCK(&in_ifa_tracker);
TAILQ_FOREACH(ia4, &V_in_ifaddrhead, ia_link) {
CK_STAILQ_FOREACH(ia4, &V_in_ifaddrhead, ia_link) {
if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
continue;
if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr) {

View File

@@ -39,7 +39,6 @@
* $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
*/
#include <rtems/bsd/local/opt_compat.h>
#include <rtems/bsd/local/opt_inet.h>
#include <sys/param.h>
@@ -80,7 +79,6 @@
#include <net/if_tapvar.h>
#include <net/if_tap.h>
#define CDEV_NAME "tap"
#define TAPDEBUG if (tapdebug) printf
@@ -551,7 +549,7 @@ tapclose(struct cdev *dev, int foo, int bar, struct thread *td)
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
mtx_unlock(&tp->tap_mtx);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
rtinit(ifa, (int)RTM_DELETE, 0);
}
if_purgeaddrs(ifp);

View File

@@ -476,7 +476,7 @@ tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
mtx_unlock(&tp->tun_mtx);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
/* deal w/IPv4 PtP destination; unlocked read */
if (ifa->ifa_addr->sa_family == AF_INET) {
rtinit(ifa, (int)RTM_DELETE,
@@ -518,7 +518,7 @@ tuninit(struct ifnet *ifp)
#ifdef INET
if_addr_rlock(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *si;

View File

@@ -70,27 +70,29 @@ struct route; /* if_output */
struct vnet;
struct ifmedia;
struct netmap_adapter;
struct netdump_methods;
#ifdef _KERNEL
#include <sys/mbuf.h> /* ifqueue only? */
#include <sys/buf_ring.h>
#include <net/vnet.h>
#endif /* _KERNEL */
#include <sys/ck.h>
#include <sys/counter.h>
#include <sys/epoch.h>
#include <sys/lock.h> /* XXX */
#include <sys/mutex.h> /* struct ifqueue */
#include <sys/rwlock.h> /* XXX */
#include <sys/sx.h> /* XXX */
#include <sys/_task.h> /* if_link_task */
#define IF_DUNIT_NONE -1
#include <net/altq/if_altq.h>
TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */
TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */
TAILQ_HEAD(ifmultihead, ifmultiaddr);
TAILQ_HEAD(ifgrouphead, ifg_group);
CK_STAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */
CK_STAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */
CK_STAILQ_HEAD(ifmultihead, ifmultiaddr);
CK_STAILQ_HEAD(ifgrouphead, ifg_group);
#ifdef _KERNEL
VNET_DECLARE(struct pfil_head, link_pfil_hook); /* packet filter hooks */
@@ -103,6 +105,15 @@ VNET_DECLARE(struct hhook_head *, ipsec_hhh_in[HHOOK_IPSEC_COUNT]);
VNET_DECLARE(struct hhook_head *, ipsec_hhh_out[HHOOK_IPSEC_COUNT]);
#define V_ipsec_hhh_in VNET(ipsec_hhh_in)
#define V_ipsec_hhh_out VNET(ipsec_hhh_out)
#ifndef __rtems__
extern epoch_t net_epoch_preempt;
extern epoch_t net_epoch;
#else /* __rtems__ */
extern struct epoch _bsd_net_epoch_preempt;
#define net_epoch_preempt &_bsd_net_epoch_preempt
extern struct epoch _bsd_net_epoch;
#define net_epoch &_bsd_net_epoch
#endif /* __rtems__ */
#endif /* _KERNEL */
typedef enum {
@@ -234,9 +245,9 @@ typedef void (if_snd_tag_free_t)(struct m_snd_tag *);
*/
struct ifnet {
/* General book keeping of interface lists. */
TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */
CK_STAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained (CK_) */
LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */
TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
CK_STAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if (CK_) */
/* protected by if_addr_lock */
u_char if_alloctype; /* if_type at time of allocation */
@@ -276,7 +287,7 @@ struct ifnet {
struct task if_linktask; /* task for link change events */
/* Addresses of different protocol families assigned to this if. */
struct rwlock if_addr_lock; /* lock to protect address lists */
struct mtx if_addr_lock; /* lock to protect address lists */
/*
* if_addrhead is the list of all addresses associated to
* an interface.
@@ -293,7 +304,7 @@ struct ifnet {
struct ifaddr *if_addr; /* pointer to link-level address */
void *if_hw_addr; /* hardware link-level address */
const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
struct rwlock if_afdata_lock;
struct mtx if_afdata_lock;
void *if_afdata[AF_MAX];
int if_afdata_initialized;
@@ -317,6 +328,10 @@ struct ifnet {
struct route *);
void (*if_input) /* input routine (from h/w driver) */
(struct ifnet *, struct mbuf *);
struct mbuf *(*if_bridge_input)(struct ifnet *, struct mbuf *);
int (*if_bridge_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
void (*if_bridge_linkstate)(struct ifnet *ifp);
if_start_fn_t if_start; /* initiate output routine */
if_ioctl_fn_t if_ioctl; /* ioctl routine */
if_init_fn_t if_init; /* Init routine */
@@ -368,6 +383,14 @@ struct ifnet {
/* Ethernet PCP */
uint8_t if_pcp;
#ifndef __rtems__
/*
* Netdump hooks to be called while dumping.
*/
struct netdump_methods *if_netdump_methods;
#endif /* __rtems__ */
struct epoch_context if_epoch_ctx;
#ifndef __rtems__
/*
* Spare fields to be added before branching a stable branch, so
@@ -396,14 +419,18 @@ struct rtems_ifinputreq {
/*
* Locks for address lists on the network interface.
*/
#define IF_ADDR_LOCK_INIT(if) rw_init(&(if)->if_addr_lock, "if_addr_lock")
#define IF_ADDR_LOCK_DESTROY(if) rw_destroy(&(if)->if_addr_lock)
#define IF_ADDR_WLOCK(if) rw_wlock(&(if)->if_addr_lock)
#define IF_ADDR_WUNLOCK(if) rw_wunlock(&(if)->if_addr_lock)
#define IF_ADDR_RLOCK(if) rw_rlock(&(if)->if_addr_lock)
#define IF_ADDR_RUNLOCK(if) rw_runlock(&(if)->if_addr_lock)
#define IF_ADDR_LOCK_ASSERT(if) rw_assert(&(if)->if_addr_lock, RA_LOCKED)
#define IF_ADDR_WLOCK_ASSERT(if) rw_assert(&(if)->if_addr_lock, RA_WLOCKED)
#define IF_ADDR_LOCK_INIT(if) mtx_init(&(if)->if_addr_lock, "if_addr_lock", NULL, MTX_DEF)
#define IF_ADDR_LOCK_DESTROY(if) mtx_destroy(&(if)->if_addr_lock)
#define IF_ADDR_RLOCK(if) epoch_enter_preempt(net_epoch_preempt);
#define IF_ADDR_RUNLOCK(if) epoch_exit_preempt(net_epoch_preempt);
#define IF_ADDR_WLOCK(if) mtx_lock(&(if)->if_addr_lock)
#define IF_ADDR_WUNLOCK(if) mtx_unlock(&(if)->if_addr_lock)
#define IF_ADDR_LOCK_ASSERT(if) MPASS(in_epoch() || mtx_owned(&(if)->if_addr_lock))
#define IF_ADDR_WLOCK_ASSERT(if) mtx_assert(&(if)->if_addr_lock, MA_OWNED)
#define NET_EPOCH_ENTER() epoch_enter_preempt(net_epoch_preempt)
#define NET_EPOCH_EXIT() epoch_exit_preempt(net_epoch_preempt)
/*
* Function variations on locking macros intended to be used by loadable
@@ -435,6 +462,8 @@ EVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
/* Interface up/down event */
#define IFNET_EVENT_UP 0
#define IFNET_EVENT_DOWN 1
#define IFNET_EVENT_PCP 2 /* priority code point, PCP */
typedef void (*ifnet_event_fn)(void *, struct ifnet *ifp, int event);
EVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn);
#endif /* _SYS_EVENTHANDLER_H_ */
@@ -446,18 +475,18 @@ struct ifg_group {
char ifg_group[IFNAMSIZ];
u_int ifg_refcnt;
void *ifg_pf_kif;
TAILQ_HEAD(, ifg_member) ifg_members;
TAILQ_ENTRY(ifg_group) ifg_next;
CK_STAILQ_HEAD(, ifg_member) ifg_members; /* (CK_) */
CK_STAILQ_ENTRY(ifg_group) ifg_next; /* (CK_) */
};
struct ifg_member {
TAILQ_ENTRY(ifg_member) ifgm_next;
CK_STAILQ_ENTRY(ifg_member) ifgm_next; /* (CK_) */
struct ifnet *ifgm_ifp;
};
struct ifg_list {
struct ifg_group *ifgl_group;
TAILQ_ENTRY(ifg_list) ifgl_next;
CK_STAILQ_ENTRY(ifg_list) ifgl_next; /* (CK_) */
};
#ifdef _SYS_EVENTHANDLER_H_
@@ -473,21 +502,21 @@ EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
#endif /* _SYS_EVENTHANDLER_H_ */
#define IF_AFDATA_LOCK_INIT(ifp) \
rw_init(&(ifp)->if_afdata_lock, "if_afdata")
mtx_init(&(ifp)->if_afdata_lock, "if_afdata", NULL, MTX_DEF)
#define IF_AFDATA_WLOCK(ifp) rw_wlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_RLOCK(ifp) rw_rlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_WUNLOCK(ifp) rw_wunlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_RUNLOCK(ifp) rw_runlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_WLOCK(ifp) mtx_lock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_RLOCK(ifp) epoch_enter_preempt(net_epoch_preempt)
#define IF_AFDATA_WUNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_RUNLOCK(ifp) epoch_exit_preempt(net_epoch_preempt)
#define IF_AFDATA_LOCK(ifp) IF_AFDATA_WLOCK(ifp)
#define IF_AFDATA_UNLOCK(ifp) IF_AFDATA_WUNLOCK(ifp)
#define IF_AFDATA_TRYLOCK(ifp) rw_try_wlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_DESTROY(ifp) rw_destroy(&(ifp)->if_afdata_lock)
#define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_lock)
#define IF_AFDATA_LOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
#define IF_AFDATA_RLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_RLOCKED)
#define IF_AFDATA_WLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_WLOCKED)
#define IF_AFDATA_UNLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
#define IF_AFDATA_LOCK_ASSERT(ifp) MPASS(in_epoch() || mtx_owned(&(ifp)->if_afdata_lock))
#define IF_AFDATA_RLOCK_ASSERT(ifp) MPASS(in_epoch());
#define IF_AFDATA_WLOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_lock, MA_OWNED)
#define IF_AFDATA_UNLOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_lock, MA_NOTOWNED)
/*
* 72 was chosen below because it is the size of a TCP/IP
@@ -515,7 +544,7 @@ struct ifaddr {
struct sockaddr *ifa_netmask; /* used to determine subnet */
struct ifnet *ifa_ifp; /* back-pointer to interface */
struct carp_softc *ifa_carp; /* pointer to CARP data */
TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */
CK_STAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */
void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */
(int, struct rtentry *, struct rt_addrinfo *);
u_short ifa_flags; /* mostly rt_flags for cloning */
@@ -527,6 +556,7 @@ struct ifaddr {
counter_u64_t ifa_opackets;
counter_u64_t ifa_ibytes;
counter_u64_t ifa_obytes;
struct epoch_context ifa_epoch_ctx;
};
struct ifaddr * ifa_alloc(size_t size, int flags);
@@ -538,13 +568,14 @@ void ifa_ref(struct ifaddr *ifa);
* structure except that it keeps track of multicast addresses.
*/
struct ifmultiaddr {
TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
CK_STAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
struct sockaddr *ifma_addr; /* address this membership is for */
struct sockaddr *ifma_lladdr; /* link-layer translation, if any */
struct ifnet *ifma_ifp; /* back-pointer to interface */
u_int ifma_refcount; /* reference count */
void *ifma_protospec; /* protocol-specific state, if any */
struct ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
struct epoch_context ifma_epoch_ctx;
};
extern struct rwlock ifnet_rwlock;
@@ -565,16 +596,16 @@ extern struct sx ifnet_sxlock;
* write, but also whether it was acquired with sleep support or not.
*/
#define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED)
#define IFNET_RLOCK_NOSLEEP_ASSERT() rw_assert(&ifnet_rwlock, RA_RLOCKED)
#define IFNET_RLOCK_NOSLEEP_ASSERT() MPASS(in_epoch())
#define IFNET_WLOCK_ASSERT() do { \
sx_assert(&ifnet_sxlock, SA_XLOCKED); \
rw_assert(&ifnet_rwlock, RA_WLOCKED); \
} while (0)
#define IFNET_RLOCK() sx_slock(&ifnet_sxlock)
#define IFNET_RLOCK_NOSLEEP() rw_rlock(&ifnet_rwlock)
#define IFNET_RLOCK_NOSLEEP() epoch_enter_preempt(net_epoch_preempt)
#define IFNET_RUNLOCK() sx_sunlock(&ifnet_sxlock)
#define IFNET_RUNLOCK_NOSLEEP() rw_runlock(&ifnet_rwlock)
#define IFNET_RUNLOCK_NOSLEEP() epoch_exit_preempt(net_epoch_preempt)
/*
* Look up an ifnet given its index; the _ref variant also acquires a
@@ -602,6 +633,12 @@ VNET_DECLARE(struct ifnet *, loif); /* first loopback interface */
#define V_if_index VNET(if_index)
#define V_loif VNET(loif)
#ifdef MCAST_VERBOSE
#define MCDPRINTF printf
#else
#define MCDPRINTF(...)
#endif
int if_addgroup(struct ifnet *, const char *);
int if_delgroup(struct ifnet *, const char *);
int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
@@ -611,12 +648,14 @@ void if_attach(struct ifnet *);
void if_dead(struct ifnet *);
int if_delmulti(struct ifnet *, struct sockaddr *);
void if_delmulti_ifma(struct ifmultiaddr *);
void if_delmulti_ifma_flags(struct ifmultiaddr *, int flags);
void if_detach(struct ifnet *);
void if_purgeaddrs(struct ifnet *);
void if_delallmulti(struct ifnet *);
void if_down(struct ifnet *);
struct ifmultiaddr *
if_findmulti(struct ifnet *, const struct sockaddr *);
void if_freemulti(struct ifmultiaddr *ifma);
void if_free(struct ifnet *);
void if_initname(struct ifnet *, const char *, int);
void if_link_state_change(struct ifnet *, int);

View File

@@ -611,7 +611,7 @@ vlan_setmulti(struct ifnet *ifp)
/* Now program new ones. */
IF_ADDR_WLOCK(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
mc = malloc(sizeof(struct vlan_mc_entry), M_VLAN, M_NOWAIT);
@@ -1949,6 +1949,8 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
ifv->ifv_pcp = ifr->ifr_vlan_pcp;
vlan_tag_recalculate(ifv);
/* broadcast event about PCP change */
EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_PCP);
break;
case SIOCSIFCAP:

View File

@@ -36,6 +36,8 @@
#include <sys/nv.h>
#include <sys/gtaskqueue.h>
struct if_clone;
/*
* The value type for indexing, limits max descriptors
* to 65535 can be conditionally redefined to uint32_t
@@ -57,6 +59,8 @@ struct if_shared_ctx;
typedef struct if_shared_ctx *if_shared_ctx_t;
struct if_int_delay_info;
typedef struct if_int_delay_info *if_int_delay_info_t;
struct if_pseudo;
typedef struct if_pseudo *if_pseudo_t;
/*
* File organization:
@@ -194,6 +198,9 @@ typedef struct if_softc_ctx {
int isc_vectors;
int isc_nrxqsets;
int isc_ntxqsets;
uint8_t isc_min_tx_latency; /* disable doorbell update batching */
uint8_t isc_rx_mvec_enable; /* generate mvecs on rx */
uint32_t isc_txrx_budget_bytes_max;
int isc_msix_bar; /* can be model specific - initialize in attach_pre */
int isc_tx_nsegments; /* can be model specific - initialize in attach_pre */
int isc_ntxd[8];
@@ -214,6 +221,7 @@ typedef struct if_softc_ctx {
int isc_rss_table_mask;
int isc_nrxqsets_max;
int isc_ntxqsets_max;
uint32_t isc_tx_qdepth;
iflib_intr_mode_t isc_intr;
uint16_t isc_max_frame_size; /* set at init time by driver */
@@ -259,6 +267,7 @@ struct if_shared_ctx {
int isc_rx_process_limit;
int isc_tx_reclaim_thresh;
int isc_flags;
const char *isc_name;
};
typedef struct iflib_dma_info {
@@ -320,7 +329,39 @@ typedef enum {
* Driver needs frames padded to some minimum length
*/
#define IFLIB_NEED_ETHER_PAD 0x100
/*
* Packets can be freed immediately after encap
*/
#define IFLIB_TXD_ENCAP_PIO 0x00200
/*
* Use RX completion handler
*/
#define IFLIB_RX_COMPLETION 0x00400
/*
* Skip refilling cluster free lists
*/
#define IFLIB_SKIP_CLREFILL 0x00800
/*
* Don't reset on hang
*/
#define IFLIB_NO_HANG_RESET 0x01000
/*
* Don't need/want most of the niceties of
* queue management
*/
#define IFLIB_PSEUDO 0x02000
/*
* No DMA support needed / wanted
*/
#define IFLIB_VIRTUAL 0x04000
/*
* autogenerate a MAC address
*/
#define IFLIB_GEN_MAC 0x08000
/*
* Interface needs admin task to ignore interface up/down status
*/
#define IFLIB_ADMIN_ALWAYS_RUN 0x10000
/*
@@ -363,18 +404,18 @@ int iflib_device_deregister(if_ctx_t);
int iflib_irq_alloc(if_ctx_t, if_irq_t, int, driver_filter_t, void *filter_arg, driver_intr_t, void *arg, char *name);
int iflib_irq_alloc(if_ctx_t, if_irq_t, int, driver_filter_t, void *filter_arg, driver_intr_t, void *arg, const char *name);
int iflib_irq_alloc_generic(if_ctx_t ctx, if_irq_t irq, int rid,
iflib_intr_type_t type, driver_filter_t *filter,
void *filter_arg, int qid, char *name);
void iflib_softirq_alloc_generic(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type, void *arg, int qid, char *name);
iflib_intr_type_t type, driver_filter_t *filter,
void *filter_arg, int qid, const char *name);
void iflib_softirq_alloc_generic(if_ctx_t ctx, if_irq_t irq, iflib_intr_type_t type, void *arg, int qid, const char *name);
void iflib_irq_free(if_ctx_t ctx, if_irq_t irq);
void iflib_io_tqg_attach(struct grouptask *gt, void *uniq, int cpu, char *name);
void iflib_config_gtask_init(if_ctx_t ctx, struct grouptask *gtask,
gtask_fn_t *fn, char *name);
void iflib_config_gtask_init(void *ctx, struct grouptask *gtask,
gtask_fn_t *fn, const char *name);
void iflib_config_gtask_deinit(struct grouptask *gtask);
@@ -396,7 +437,7 @@ int iflib_dma_alloc_multi(if_ctx_t ctx, int *sizes, iflib_dma_info_t *dmalist, i
void iflib_dma_free_multi(iflib_dma_info_t *dmalist, int count);
struct mtx *iflib_ctx_lock_get(if_ctx_t);
struct sx *iflib_ctx_lock_get(if_ctx_t);
struct mtx *iflib_qset_lock_get(if_ctx_t, uint16_t);
void iflib_led_create(if_ctx_t ctx);
@@ -404,4 +445,9 @@ void iflib_led_create(if_ctx_t ctx);
void iflib_add_int_delay_sysctl(if_ctx_t, const char *, const char *,
if_int_delay_info_t, int, int);
/*
* Pseudo device support
*/
if_pseudo_t iflib_clone_register(if_shared_ctx_t);
void iflib_clone_deregister(if_pseudo_t);
#endif /* __IFLIB_H_ */

View File

@@ -38,8 +38,11 @@
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/counter.h>
#include <sys/cpuset.h>
#include <sys/malloc.h>
#include <sys/refcount.h>
#include <sys/lock.h>
#include <sys/rmlock.h>
#include <sys/tree.h>
#include <vm/uma.h>
@@ -147,14 +150,15 @@ extern struct mtx pf_unlnkdrules_mtx;
#define PF_UNLNKDRULES_LOCK() mtx_lock(&pf_unlnkdrules_mtx)
#define PF_UNLNKDRULES_UNLOCK() mtx_unlock(&pf_unlnkdrules_mtx)
extern struct rwlock pf_rules_lock;
#define PF_RULES_RLOCK() rw_rlock(&pf_rules_lock)
#define PF_RULES_RUNLOCK() rw_runlock(&pf_rules_lock)
#define PF_RULES_WLOCK() rw_wlock(&pf_rules_lock)
#define PF_RULES_WUNLOCK() rw_wunlock(&pf_rules_lock)
#define PF_RULES_ASSERT() rw_assert(&pf_rules_lock, RA_LOCKED)
#define PF_RULES_RASSERT() rw_assert(&pf_rules_lock, RA_RLOCKED)
#define PF_RULES_WASSERT() rw_assert(&pf_rules_lock, RA_WLOCKED)
extern struct rmlock pf_rules_lock;
#define PF_RULES_RLOCK_TRACKER struct rm_priotracker _pf_rules_tracker
#define PF_RULES_RLOCK() rm_rlock(&pf_rules_lock, &_pf_rules_tracker)
#define PF_RULES_RUNLOCK() rm_runlock(&pf_rules_lock, &_pf_rules_tracker)
#define PF_RULES_WLOCK() rm_wlock(&pf_rules_lock)
#define PF_RULES_WUNLOCK() rm_wunlock(&pf_rules_lock)
#define PF_RULES_ASSERT() rm_assert(&pf_rules_lock, RA_LOCKED)
#define PF_RULES_RASSERT() rm_assert(&pf_rules_lock, RA_RLOCKED)
#define PF_RULES_WASSERT() rm_assert(&pf_rules_lock, RA_WLOCKED)
extern struct sx pf_end_lock;
@@ -1638,6 +1642,7 @@ void pfr_detach_table(struct pfr_ktable *);
int pfr_clr_tables(struct pfr_table *, int *, int);
int pfr_add_tables(struct pfr_table *, int, int *, int);
int pfr_del_tables(struct pfr_table *, int, int *, int);
int pfr_table_count(struct pfr_table *, int);
int pfr_get_tables(struct pfr_table *, struct pfr_table *, int *, int);
int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int);
int pfr_clr_tstats(struct pfr_table *, int, int *, int);

View File

@@ -238,7 +238,7 @@ route_init(void)
if (rt_numfibs == 0)
rt_numfibs = 1;
}
SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);
SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, NULL);
static int
rtentry_zinit(void *mem, int size, int how)
@@ -626,12 +626,12 @@ rtredirect_fib(struct sockaddr *dst,
struct rib_head *rnh;
ifa = NULL;
NET_EPOCH_ENTER();
rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
if (rnh == NULL) {
error = EAFNOSUPPORT;
goto out;
}
/* verify the gateway is directly reachable */
if ((ifa = ifa_ifwithnet(gateway, 0, fibnum)) == NULL) {
error = ENETUNREACH;
@@ -685,6 +685,7 @@ rtredirect_fib(struct sockaddr *dst,
info.rti_info[RTAX_DST] = dst;
info.rti_info[RTAX_GATEWAY] = gateway;
info.rti_info[RTAX_NETMASK] = netmask;
ifa_ref(ifa);
info.rti_ifa = ifa;
info.rti_flags = flags;
error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
@@ -719,7 +720,8 @@ rtredirect_fib(struct sockaddr *dst,
done:
if (rt)
RTFREE_LOCKED(rt);
out:
out:
NET_EPOCH_EXIT();
if (error)
V_rtstat.rts_badredirect++;
else if (stat != NULL)
@@ -730,8 +732,6 @@ out:
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_info[RTAX_AUTHOR] = src;
rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum);
if (ifa != NULL)
ifa_free(ifa);
}
/*
@@ -762,6 +762,7 @@ ifa_ifwithroute(int flags, const struct sockaddr *dst, struct sockaddr *gateway,
struct ifaddr *ifa;
int not_found = 0;
MPASS(in_epoch());
if ((flags & RTF_GATEWAY) == 0) {
/*
* If we are adding a route to an interface,
@@ -790,7 +791,7 @@ ifa_ifwithroute(int flags, const struct sockaddr *dst, struct sockaddr *gateway,
rt = rtalloc1_fib(gateway, 0, flags, fibnum);
if (rt == NULL)
return (NULL);
goto out;
/*
* dismiss a gateway that is reachable only
* through the default router
@@ -809,21 +810,19 @@ ifa_ifwithroute(int flags, const struct sockaddr *dst, struct sockaddr *gateway,
}
if (!not_found && rt->rt_ifa != NULL) {
ifa = rt->rt_ifa;
ifa_ref(ifa);
}
RT_REMREF(rt);
RT_UNLOCK(rt);
if (not_found || ifa == NULL)
return (NULL);
goto out;
}
if (ifa->ifa_addr->sa_family != dst->sa_family) {
struct ifaddr *oifa = ifa;
ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
if (ifa == NULL)
ifa = oifa;
else
ifa_free(oifa);
}
out:
return (ifa);
}
@@ -933,7 +932,7 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
info->rti_flags = rt->rt_flags;
info->rti_ifp = rt->rt_ifp;
info->rti_ifa = rt->rt_ifa;
ifa_ref(info->rti_ifa);
if (flags & NHR_REF) {
/* Do 'traditional' refcouting */
if_ref(info->rti_ifp);
@@ -1309,17 +1308,19 @@ int
rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
{
struct ifaddr *ifa;
int error = 0;
int needref, error;
/*
* ifp may be specified by sockaddr_dl
* when protocol address is ambiguous.
*/
error = 0;
needref = (info->rti_ifa == NULL);
NET_EPOCH_ENTER();
if (info->rti_ifp == NULL && ifpaddr != NULL &&
ifpaddr->sa_family == AF_LINK &&
(ifa = ifa_ifwithnet(ifpaddr, 0, fibnum)) != NULL) {
info->rti_ifp = ifa->ifa_ifp;
ifa_free(ifa);
}
if (info->rti_ifa == NULL && ifaaddr != NULL)
info->rti_ifa = ifa_ifwithaddr(ifaaddr);
@@ -1337,11 +1338,13 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
info->rti_ifa = ifa_ifwithroute(flags, sa, sa,
fibnum);
}
if ((ifa = info->rti_ifa) != NULL) {
if (needref && info->rti_ifa != NULL) {
if (info->rti_ifp == NULL)
info->rti_ifp = ifa->ifa_ifp;
info->rti_ifp = info->rti_ifa->ifa_ifp;
ifa_ref(info->rti_ifa);
} else
error = ENETUNREACH;
NET_EPOCH_EXIT();
return (error);
}
@@ -1618,12 +1621,9 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
error = rt_getifa_fib(info, fibnum);
if (error)
return (error);
} else
ifa_ref(info->rti_ifa);
ifa = info->rti_ifa;
}
rt = uma_zalloc(V_rtzone, M_NOWAIT);
if (rt == NULL) {
ifa_free(ifa);
return (ENOBUFS);
}
rt->rt_flags = RTF_UP | flags;
@@ -1632,7 +1632,6 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
* Add the gateway. Possibly re-malloc-ing the storage for it.
*/
if ((error = rt_setgate(rt, dst, gateway)) != 0) {
ifa_free(ifa);
uma_zfree(V_rtzone, rt);
return (error);
}
@@ -1655,6 +1654,8 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
* This moved from below so that rnh->rnh_addaddr() can
* examine the ifa and ifa->ifa_ifp if it so desires.
*/
ifa = info->rti_ifa;
ifa_ref(ifa);
rt->rt_ifa = ifa;
rt->rt_ifp = ifa->ifa_ifp;
rt->rt_weight = 1;
@@ -1819,6 +1820,7 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
if (rt->rt_ifa->ifa_rtrequest != NULL)
rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, info);
ifa_free(rt->rt_ifa);
rt->rt_ifa = NULL;
}
/* Update gateway address */
if (info->rti_info[RTAX_GATEWAY] != NULL) {
@@ -1870,8 +1872,10 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_addrinfo *info,
}
bad:
RT_UNLOCK(rt);
if (free_ifa != 0)
if (free_ifa != 0) {
ifa_free(info->rti_ifa);
info->rti_ifa = NULL;
}
return (error);
}
@@ -2090,6 +2094,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
* Do the actual request
*/
bzero((caddr_t)&info, sizeof(info));
ifa_ref(ifa);
info.rti_ifa = ifa;
info.rti_flags = flags |
(ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;

View File

@@ -33,7 +33,6 @@
* @(#)rtsock.c 8.7 (Berkeley) 10/12/95
* $FreeBSD$
*/
#include <rtems/bsd/local/opt_compat.h>
#include <rtems/bsd/local/opt_mpath.h>
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
@@ -467,7 +466,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
* that belongs to the jail.
*/
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct sockaddr *sa;
sa = ifa->ifa_addr;
if (sa->sa_family != AF_INET)
@@ -509,7 +508,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
* that belongs to the jail.
*/
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct sockaddr *sa;
sa = ifa->ifa_addr;
if (sa->sa_family != AF_INET6)
@@ -797,12 +796,14 @@ route_output(struct mbuf *m, struct socket *so, ...)
rt->rt_ifp->if_type == IFT_PROPVIRTUAL) {
struct ifaddr *ifa;
NET_EPOCH_ENTER();
ifa = ifa_ifwithnet(info.rti_info[RTAX_DST], 1,
RT_ALL_FIBS);
if (ifa != NULL)
rt_maskedcopy(ifa->ifa_addr,
&laddr,
ifa->ifa_netmask);
NET_EPOCH_EXIT();
} else
rt_maskedcopy(rt->rt_ifa->ifa_addr,
&laddr,
@@ -1424,7 +1425,10 @@ rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
bzero((caddr_t)&info, sizeof(info));
info.rti_info[RTAX_IFA] = ifma->ifma_addr;
info.rti_info[RTAX_IFP] = ifp ? ifp->if_addr->ifa_addr : NULL;
if (ifp && ifp->if_addr)
info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
else
info.rti_info[RTAX_IFP] = NULL;
/*
* If a link-layer address is present, present it as a ``gateway''
* (similarly to how ARP entries, e.g., are presented).
@@ -1746,7 +1750,7 @@ sysctl_iflist(int af, struct walkarg *w)
bzero((caddr_t)&info, sizeof(info));
bzero(&ifd, sizeof(ifd));
IFNET_RLOCK_NOSLEEP();
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (w->w_arg && w->w_arg != ifp->if_index)
continue;
if_data_copy(ifp, &ifd);
@@ -1767,7 +1771,7 @@ sysctl_iflist(int af, struct walkarg *w)
if (error)
goto done;
}
while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != NULL) {
while ((ifa = CK_STAILQ_NEXT(ifa, ifa_link)) != NULL) {
if (af && af != ifa->ifa_addr->sa_family)
continue;
if (prison_if(w->w_req->td->td_ucred,
@@ -1816,13 +1820,13 @@ sysctl_ifmalist(int af, struct walkarg *w)
bzero((caddr_t)&info, sizeof(info));
IFNET_RLOCK_NOSLEEP();
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (w->w_arg && w->w_arg != ifp->if_index)
continue;
ifa = ifp->if_addr;
info.rti_info[RTAX_IFP] = ifa ? ifa->ifa_addr : NULL;
IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (af && af != ifma->ifma_addr->sa_family)
continue;
if (prison_if(w->w_req->td->td_ucred,