diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-21 09:39:55 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:40 +0200 |
commit | 2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783 (patch) | |
tree | bd7bad558534db4a1f400bc38a2c9aa7ea4f411e /freebsd/sys/net | |
parent | Update to FreeBSD head 2018-02-01 (diff) | |
download | rtems-libbsd-2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783.tar.bz2 |
Update to FreeBSD head 2018-04-01
Git mirror commit 8dfb1ccc26d1cea7e2529303003ff61f9f1784c4.
Update #3472.
Diffstat (limited to 'freebsd/sys/net')
-rw-r--r-- | freebsd/sys/net/bpf.c | 95 | ||||
-rw-r--r-- | freebsd/sys/net/bpfdesc.h | 15 | ||||
-rw-r--r-- | freebsd/sys/net/ethernet.h | 17 | ||||
-rw-r--r-- | freebsd/sys/net/if.c | 148 | ||||
-rw-r--r-- | freebsd/sys/net/if_arcsubr.c | 7 | ||||
-rw-r--r-- | freebsd/sys/net/if_bridge.c | 15 | ||||
-rw-r--r-- | freebsd/sys/net/if_enc.c | 2 | ||||
-rw-r--r-- | freebsd/sys/net/if_ethersubr.c | 144 | ||||
-rw-r--r-- | freebsd/sys/net/if_fddisubr.c | 11 | ||||
-rw-r--r-- | freebsd/sys/net/if_fwsubr.c | 9 | ||||
-rw-r--r-- | freebsd/sys/net/if_gif.c | 6 | ||||
-rw-r--r-- | freebsd/sys/net/if_gre.c | 10 | ||||
-rw-r--r-- | freebsd/sys/net/if_ipsec.c | 4 | ||||
-rw-r--r-- | freebsd/sys/net/if_iso88025subr.c | 701 | ||||
-rw-r--r-- | freebsd/sys/net/if_llatbl.h | 15 | ||||
-rw-r--r-- | freebsd/sys/net/if_media.h | 2 | ||||
-rw-r--r-- | freebsd/sys/net/if_spppsubr.c | 10 | ||||
-rw-r--r-- | freebsd/sys/net/if_var.h | 6 | ||||
-rw-r--r-- | freebsd/sys/net/if_vlan.c | 91 | ||||
-rw-r--r-- | freebsd/sys/net/if_vlan_var.h | 18 | ||||
-rw-r--r-- | freebsd/sys/net/iflib.h | 2 | ||||
-rw-r--r-- | freebsd/sys/net/iso88025.h | 176 | ||||
-rw-r--r-- | freebsd/sys/net/pfil.c | 59 | ||||
-rw-r--r-- | freebsd/sys/net/pfil.h | 14 | ||||
-rw-r--r-- | freebsd/sys/net/pfvar.h | 5 | ||||
-rw-r--r-- | freebsd/sys/net/rtsock.c | 9 |
26 files changed, 483 insertions, 1108 deletions
diff --git a/freebsd/sys/net/bpf.c b/freebsd/sys/net/bpf.c index e6ad9e25..24927e8b 100644 --- a/freebsd/sys/net/bpf.c +++ b/freebsd/sys/net/bpf.c @@ -292,7 +292,7 @@ bpf_append_bytes(struct bpf_d *d, caddr_t buf, u_int offset, void *src, #ifndef __rtems__ case BPF_BUFMODE_ZBUF: - d->bd_zcopy++; + counter_u64_add(d->bd_zcopy, 1); return (bpf_zerocopy_append_bytes(d, buf, offset, src, len)); #endif /* __rtems__ */ @@ -314,7 +314,7 @@ bpf_append_mbuf(struct bpf_d *d, caddr_t buf, u_int offset, void *src, #ifndef __rtems__ case BPF_BUFMODE_ZBUF: - d->bd_zcopy++; + counter_u64_add(d->bd_zcopy, 1); return (bpf_zerocopy_append_mbuf(d, buf, offset, src, len)); #endif /* __rtems__ */ @@ -936,6 +936,15 @@ bpfopen(struct cdev *dev, int flags, int fmt, struct thread *td) } #endif /* __rtems__ */ + /* Setup counters */ + d->bd_rcount = counter_u64_alloc(M_WAITOK); + d->bd_dcount = counter_u64_alloc(M_WAITOK); + d->bd_fcount = counter_u64_alloc(M_WAITOK); + d->bd_wcount = counter_u64_alloc(M_WAITOK); + d->bd_wfcount = counter_u64_alloc(M_WAITOK); + d->bd_wdcount = counter_u64_alloc(M_WAITOK); + d->bd_zcopy = counter_u64_alloc(M_WAITOK); + /* * For historical reasons, perform a one-time initialization call to * the buffer routines, even though we're not yet committed to a @@ -1179,22 +1188,22 @@ bpfwrite(struct bpf_d *d, struct uio *uio, int ioflag) return (error); BPF_PID_REFRESH_CUR(d); - d->bd_wcount++; + counter_u64_add(d->bd_wcount, 1); /* XXX: locking required */ if (d->bd_bif == NULL) { - d->bd_wdcount++; + counter_u64_add(d->bd_wdcount, 1); return (ENXIO); } ifp = d->bd_bif->bif_ifp; if ((ifp->if_flags & IFF_UP) == 0) { - d->bd_wdcount++; + counter_u64_add(d->bd_wdcount, 1); return (ENETDOWN); } if (uio->uio_resid == 0) { - d->bd_wdcount++; + counter_u64_add(d->bd_wdcount, 1); return (0); } @@ -1205,10 +1214,10 @@ bpfwrite(struct bpf_d *d, struct uio *uio, int ioflag) error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp, &m, &dst, &hlen, d); if (error) { - d->bd_wdcount++; + counter_u64_add(d->bd_wdcount, 1); return (error); } - d->bd_wfcount++; + counter_u64_add(d->bd_wfcount, 1); if (d->bd_hdrcmplt) dst.sa_family = pseudo_AF_HDRCMPLT; @@ -1244,7 +1253,7 @@ bpfwrite(struct bpf_d *d, struct uio *uio, int ioflag) error = (*ifp->if_output)(ifp, m, &dst, &ro); if (error) - d->bd_wdcount++; + counter_u64_add(d->bd_wdcount, 1); if (mc != NULL) { if (error == 0) @@ -1283,13 +1292,13 @@ reset_d(struct bpf_d *d) } if (bpf_canwritebuf(d)) d->bd_slen = 0; - d->bd_rcount = 0; - d->bd_dcount = 0; - d->bd_fcount = 0; - d->bd_wcount = 0; - d->bd_wfcount = 0; - d->bd_wdcount = 0; - d->bd_zcopy = 0; + counter_u64_zero(d->bd_rcount); + counter_u64_zero(d->bd_dcount); + counter_u64_zero(d->bd_fcount); + counter_u64_zero(d->bd_wcount); + counter_u64_zero(d->bd_wfcount); + counter_u64_zero(d->bd_wdcount); + counter_u64_zero(d->bd_zcopy); } /* @@ -1667,8 +1676,8 @@ bpfioctl(struct bpf_d *d, u_long cmd, caddr_t addr, int flags, struct bpf_stat *bs = (struct bpf_stat *)addr; /* XXXCSJP overflow */ - bs->bs_recv = d->bd_rcount; - bs->bs_drop = d->bd_dcount; + bs->bs_recv = (u_int)counter_u64_fetch(d->bd_rcount); + bs->bs_drop = (u_int)counter_u64_fetch(d->bd_dcount); break; } @@ -2242,8 +2251,7 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen) * write lock, too */ - /* XXX: Do not protect counter for the sake of performance. */ - ++d->bd_rcount; + counter_u64_add(d->bd_rcount, 1); /* * NB: We dont call BPF_CHECK_DIRECTION() here since there is no * way for the caller to indiciate to us whether this packet @@ -2263,7 +2271,7 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen) */ BPFD_LOCK(d); - d->bd_fcount++; + counter_u64_add(d->bd_fcount, 1); if (gottime < bpf_ts_quality(d->bd_tstamp)) gottime = bpf_gettime(&bt, d->bd_tstamp, NULL); #ifdef MAC @@ -2310,7 +2318,7 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m) LIST_FOREACH(d, &bp->bif_dlist, bd_next) { if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp)) continue; - ++d->bd_rcount; + counter_u64_add(d->bd_rcount, 1); #ifdef BPF_JITTER bf = bpf_jitter_enable != 0 ? d->bd_bfilter : NULL; /* XXX We cannot handle multiple mbufs. */ @@ -2322,7 +2330,7 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m) if (slen != 0) { BPFD_LOCK(d); - d->bd_fcount++; + counter_u64_add(d->bd_fcount, 1); if (gottime < bpf_ts_quality(d->bd_tstamp)) gottime = bpf_gettime(&bt, d->bd_tstamp, m); #ifdef MAC @@ -2373,12 +2381,12 @@ bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m) LIST_FOREACH(d, &bp->bif_dlist, bd_next) { if (BPF_CHECK_DIRECTION(d, m->m_pkthdr.rcvif, bp->bif_ifp)) continue; - ++d->bd_rcount; + counter_u64_add(d->bd_rcount, 1); slen = bpf_filter(d->bd_rfilter, (u_char *)&mb, pktlen, 0); if (slen != 0) { BPFD_LOCK(d); - d->bd_fcount++; + counter_u64_add(d->bd_fcount, 1); if (gottime < bpf_ts_quality(d->bd_tstamp)) gottime = bpf_gettime(&bt, d->bd_tstamp, m); #ifdef MAC @@ -2530,7 +2538,7 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen, * buffer model. */ bpf_buffull(d); - ++d->bd_dcount; + counter_u64_add(d->bd_dcount, 1); return; } KASSERT(!d->bd_hbuf_in_use, ("hold buffer is in use")); @@ -2630,6 +2638,15 @@ bpf_freed(struct bpf_d *d) if (d->bd_wfilter != NULL) free((caddr_t)d->bd_wfilter, M_BPF); mtx_destroy(&d->bd_lock); + + counter_u64_free(d->bd_rcount); + counter_u64_free(d->bd_dcount); + counter_u64_free(d->bd_fcount); + counter_u64_free(d->bd_wcount); + counter_u64_free(d->bd_wfcount); + counter_u64_free(d->bd_wdcount); + counter_u64_free(d->bd_zcopy); + } /* @@ -3110,12 +3127,12 @@ bpf_zero_counters(void) BPFIF_RLOCK(bp); LIST_FOREACH(bd, &bp->bif_dlist, bd_next) { BPFD_LOCK(bd); - bd->bd_rcount = 0; - bd->bd_dcount = 0; - bd->bd_fcount = 0; - bd->bd_wcount = 0; - bd->bd_wfcount = 0; - bd->bd_zcopy = 0; + counter_u64_zero(bd->bd_rcount); + counter_u64_zero(bd->bd_dcount); + counter_u64_zero(bd->bd_fcount); + counter_u64_zero(bd->bd_wcount); + counter_u64_zero(bd->bd_wfcount); + counter_u64_zero(bd->bd_zcopy); BPFD_UNLOCK(bd); } BPFIF_RUNLOCK(bp); @@ -3142,9 +3159,9 @@ bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) #ifndef __rtems__ d->bd_async = bd->bd_async; #endif /* __rtems__ */ - d->bd_rcount = bd->bd_rcount; - d->bd_dcount = bd->bd_dcount; - d->bd_fcount = bd->bd_fcount; + d->bd_rcount = counter_u64_fetch(bd->bd_rcount); + d->bd_dcount = counter_u64_fetch(bd->bd_dcount); + d->bd_fcount = counter_u64_fetch(bd->bd_fcount); d->bd_sig = bd->bd_sig; d->bd_slen = bd->bd_slen; d->bd_hlen = bd->bd_hlen; @@ -3153,10 +3170,10 @@ bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) strlcpy(d->bd_ifname, bd->bd_bif->bif_ifp->if_xname, IFNAMSIZ); d->bd_locked = bd->bd_locked; - d->bd_wcount = bd->bd_wcount; - d->bd_wdcount = bd->bd_wdcount; - d->bd_wfcount = bd->bd_wfcount; - d->bd_zcopy = bd->bd_zcopy; + d->bd_wcount = counter_u64_fetch(bd->bd_wcount); + d->bd_wdcount = counter_u64_fetch(bd->bd_wdcount); + d->bd_wfcount = counter_u64_fetch(bd->bd_wfcount); + d->bd_zcopy = counter_u64_fetch(bd->bd_zcopy); d->bd_bufmode = bd->bd_bufmode; } diff --git a/freebsd/sys/net/bpfdesc.h b/freebsd/sys/net/bpfdesc.h index 3d8e69ce..695d3d40 100644 --- a/freebsd/sys/net/bpfdesc.h +++ b/freebsd/sys/net/bpfdesc.h @@ -45,6 +45,7 @@ #include <sys/selinfo.h> #include <sys/queue.h> #include <sys/conf.h> +#include <sys/counter.h> #include <net/if.h> /* @@ -76,8 +77,8 @@ struct bpf_d { struct bpf_insn *bd_rfilter; /* read filter code */ struct bpf_insn *bd_wfilter; /* write filter code */ void *bd_bfilter; /* binary filter code */ - u_int64_t bd_rcount; /* number of packets received */ - u_int64_t bd_dcount; /* number of packets dropped */ + counter_u64_t bd_rcount; /* number of packets received */ + counter_u64_t bd_dcount; /* number of packets dropped */ u_char bd_promisc; /* true if listening promiscuously */ u_char bd_state; /* idle, waiting, or timed out */ @@ -96,14 +97,14 @@ struct bpf_d { struct mtx bd_lock; /* per-descriptor lock */ struct callout bd_callout; /* for BPF timeouts with select */ struct label *bd_label; /* MAC label for descriptor */ - u_int64_t bd_fcount; /* number of packets which matched filter */ + counter_u64_t bd_fcount; /* number of packets which matched filter */ pid_t bd_pid; /* PID which created descriptor */ int bd_locked; /* true if descriptor is locked */ u_int bd_bufmode; /* Current buffer mode. */ - u_int64_t bd_wcount; /* number of packets written */ - u_int64_t bd_wfcount; /* number of packets that matched write filter */ - u_int64_t bd_wdcount; /* number of packets dropped during a write */ - u_int64_t bd_zcopy; /* number of zero copy operations */ + counter_u64_t bd_wcount; /* number of packets written */ + counter_u64_t bd_wfcount; /* number of packets that matched write filter */ + counter_u64_t bd_wdcount; /* number of packets dropped during a write */ + counter_u64_t bd_zcopy; /* number of zero copy operations */ u_char bd_compat32; /* 32-bit stream on LP64 system */ }; diff --git a/freebsd/sys/net/ethernet.h b/freebsd/sys/net/ethernet.h index 5cd1dc50..fa75c1df 100644 --- a/freebsd/sys/net/ethernet.h +++ b/freebsd/sys/net/ethernet.h @@ -344,6 +344,7 @@ struct ether_vlan_header { #define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ #define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */ #define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#define ETHERTYPE_QINQ 0x88A8 /* 802.1ad VLAN stacking */ #define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */ #define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */ #define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */ @@ -384,6 +385,20 @@ struct ether_vlan_header { } \ } while (0) +/* + * Names for 802.1q priorities ("802.1p"). Notice that in this scheme, + * (0 < 1), allowing default 0-tagged traffic to take priority over background + * tagged traffic. + */ +#define IEEE8021Q_PCP_BK 1 /* Background (lowest) */ +#define IEEE8021Q_PCP_BE 0 /* Best effort (default) */ +#define IEEE8021Q_PCP_EE 2 /* Excellent effort */ +#define IEEE8021Q_PCP_CA 3 /* Critical applications */ +#define IEEE8021Q_PCP_VI 4 /* Video, < 100ms latency */ +#define IEEE8021Q_PCP_VO 5 /* Video, < 10ms latency */ +#define IEEE8021Q_PCP_IC 6 /* Internetwork control */ +#define IEEE8021Q_PCP_NC 7 /* Network control (highest) */ + #ifdef _KERNEL struct ifnet; @@ -405,6 +420,8 @@ extern char *ether_sprintf(const u_int8_t *); void ether_vlan_mtap(struct bpf_if *, struct mbuf *, void *, u_int); struct mbuf *ether_vlanencap(struct mbuf *, uint16_t); +bool ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p, + uint16_t vid, uint8_t pcp); #ifdef _SYS_EVENTHANDLER_H_ /* new ethernet interface attached event */ diff --git a/freebsd/sys/net/if.c b/freebsd/sys/net/if.c index 67252bd4..bbf2ddd0 100644 --- a/freebsd/sys/net/if.c +++ b/freebsd/sys/net/if.c @@ -59,6 +59,7 @@ #include <sys/sockio.h> #include <sys/syslog.h> #include <sys/sysctl.h> +#include <sys/sysent.h> #include <sys/taskqueue.h> #include <sys/domain.h> #include <sys/jail.h> @@ -98,10 +99,59 @@ #include <security/mac/mac_framework.h> +/* + * Consumers of struct ifreq such as tcpdump assume no pad between ifr_name + * and ifr_ifru when it is used in SIOCGIFCONF. + */ +_Static_assert(sizeof(((struct ifreq *)0)->ifr_name) == + offsetof(struct ifreq, ifr_ifru), "gap between ifr_name and ifr_ifru"); + #ifdef COMPAT_FREEBSD32 #include <sys/mount.h> #include <compat/freebsd32/freebsd32.h> + +struct ifreq_buffer32 { + uint32_t length; /* (size_t) */ + uint32_t buffer; /* (void *) */ +}; + +/* + * Interface request structure used for socket + * ioctl's. All interface ioctl's must have parameter + * definitions which begin with ifr_name. The + * remainder may be interface specific. + */ +struct ifreq32 { + char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_dstaddr; + struct sockaddr ifru_broadaddr; + struct ifreq_buffer32 ifru_buffer; + short ifru_flags[2]; + short ifru_index; + int ifru_jid; + int ifru_metric; + int ifru_mtu; + int ifru_phys; + int ifru_media; + uint32_t ifru_data; + int ifru_cap[2]; + u_int ifru_fib; + u_char ifru_vlan_pcp; + } ifr_ifru; +}; +CTASSERT(sizeof(struct ifreq) == sizeof(struct ifreq32)); +CTASSERT(__offsetof(struct ifreq, ifr_ifru) == + __offsetof(struct ifreq32, ifr_ifru)); +#endif + +union ifreq_union { + struct ifreq ifr; +#ifdef COMPAT_FREEBSD32 + struct ifreq32 ifr32; #endif +}; SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); @@ -487,6 +537,7 @@ if_alloc(u_char type) for (int i = 0; i < IFCOUNTERS; i++) ifp->if_counters[i] = counter_u64_alloc(M_WAITOK); ifp->if_get_counter = if_get_counter_default; + ifp->if_pcp = IFNET_PCP_NONE; ifnet_setbyindex(ifp->if_index, ifp); return (ifp); } @@ -2306,6 +2357,75 @@ ifunit(const char *name) return (ifp); } +static void * +ifr_buffer_get_buffer(struct thread *td, void *data) +{ + union ifreq_union *ifrup; + + ifrup = data; +#ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) + return ((void *)(uintptr_t) + ifrup->ifr32.ifr_ifru.ifru_buffer.buffer); +#endif + return (ifrup->ifr.ifr_ifru.ifru_buffer.buffer); +} + +static void +ifr_buffer_set_buffer_null(struct thread *td, void *data) +{ + union ifreq_union *ifrup; + + ifrup = data; +#ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) + ifrup->ifr32.ifr_ifru.ifru_buffer.buffer = 0; + else +#endif + ifrup->ifr.ifr_ifru.ifru_buffer.buffer = NULL; +} + +static size_t +ifr_buffer_get_length(struct thread *td, void *data) +{ + union ifreq_union *ifrup; + + ifrup = data; +#ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) + return (ifrup->ifr32.ifr_ifru.ifru_buffer.length); +#endif + return (ifrup->ifr.ifr_ifru.ifru_buffer.length); +} + +static void +ifr_buffer_set_length(struct thread *td, void *data, size_t len) +{ + union ifreq_union *ifrup; + + ifrup = data; +#ifdef COMPAT_FREEBSD32 + if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) + ifrup->ifr32.ifr_ifru.ifru_buffer.length = len; + else +#endif + ifrup->ifr.ifr_ifru.ifru_buffer.length = len; +} + +void * +ifr_data_get_ptr(void *ifrp) +{ + union ifreq_union *ifrup; + + ifrup = ifrp; +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) + return ((void *)(uintptr_t) + ifrup->ifr32.ifr_ifru.ifru_data); +#endif + return (ifrup->ifr.ifr_ifru.ifru_data); +} + /* * Hardware specific interface ioctls. */ @@ -2366,12 +2486,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) else { /* space for terminating nul */ descrlen = strlen(ifp->if_description) + 1; - if (ifr->ifr_buffer.length < descrlen) - ifr->ifr_buffer.buffer = NULL; + if (ifr_buffer_get_length(td, ifr) < descrlen) + ifr_buffer_set_buffer_null(td, ifr); else error = copyout(ifp->if_description, - ifr->ifr_buffer.buffer, descrlen); - ifr->ifr_buffer.length = descrlen; + ifr_buffer_get_buffer(td, ifr), descrlen); + ifr_buffer_set_length(td, ifr, descrlen); } sx_sunlock(&ifdescr_sx); break; @@ -2387,15 +2507,15 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) * length parameter is supposed to count the * terminating nul in. */ - if (ifr->ifr_buffer.length > ifdescr_maxlen) + if (ifr_buffer_get_length(td, ifr) > ifdescr_maxlen) return (ENAMETOOLONG); - else if (ifr->ifr_buffer.length == 0) + else if (ifr_buffer_get_length(td, ifr) == 0) descrbuf = NULL; else { - descrbuf = malloc(ifr->ifr_buffer.length, M_IFDESCR, - M_WAITOK | M_ZERO); - error = copyin(ifr->ifr_buffer.buffer, descrbuf, - ifr->ifr_buffer.length - 1); + descrbuf = malloc(ifr_buffer_get_length(td, ifr), + M_IFDESCR, M_WAITOK | M_ZERO); + error = copyin(ifr_buffer_get_buffer(td, ifr), descrbuf, + ifr_buffer_get_length(td, ifr) - 1); if (error) { free(descrbuf, M_IFDESCR); break; @@ -2487,7 +2607,8 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) error = priv_check(td, PRIV_NET_SETIFNAME); if (error) return (error); - error = copyinstr(ifr->ifr_data, new_name, IFNAMSIZ, NULL); + error = copyinstr(ifr_data_get_ptr(ifr), new_name, IFNAMSIZ, + NULL); if (error != 0) return (error); if (new_name[0] == '\0') @@ -2814,8 +2935,8 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td) error = priv_check(td, PRIV_NET_IFCREATE); if (error == 0) error = if_clone_create(ifr->ifr_name, - sizeof(ifr->ifr_name), - cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL); + sizeof(ifr->ifr_name), cmd == SIOCIFCREATE2 ? + ifr_data_get_ptr(ifr) : NULL); CURVNET_RESTORE(); return (error); case SIOCIFDESTROY: @@ -3545,7 +3666,6 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len) case IFT_ETHER: case IFT_FDDI: case IFT_XETHER: - case IFT_ISO88025: case IFT_L2VLAN: case IFT_BRIDGE: case IFT_ARCNET: diff --git a/freebsd/sys/net/if_arcsubr.c b/freebsd/sys/net/if_arcsubr.c index 171085ec..9f0a03d5 100644 --- a/freebsd/sys/net/if_arcsubr.c +++ b/freebsd/sys/net/if_arcsubr.c @@ -683,12 +683,7 @@ arc_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; case SIOCGIFADDR: - { - struct sockaddr *sa; - - sa = (struct sockaddr *) &ifr->ifr_data; - *(u_int8_t *)sa->sa_data = ARC_LLADDR(ifp); - } + ifr->ifr_addr.sa_data[0] = ARC_LLADDR(ifp); break; case SIOCADDMULTI: diff --git a/freebsd/sys/net/if_bridge.c b/freebsd/sys/net/if_bridge.c index d345c0f1..248cd45a 100644 --- a/freebsd/sys/net/if_bridge.c +++ b/freebsd/sys/net/if_bridge.c @@ -3178,7 +3178,8 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) if (PFIL_HOOKED(&V_link_pfil_hook) && V_pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) { - error = pfil_run_hooks(&V_link_pfil_hook, mp, ifp, dir, NULL); + error = pfil_run_hooks(&V_link_pfil_hook, mp, ifp, dir, 0, + NULL); if (*mp == NULL || error != 0) /* packet consumed by filter */ return (error); @@ -3230,21 +3231,21 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) */ if (V_pfil_bridge && dir == PFIL_OUT && bifp != NULL) error = pfil_run_hooks(&V_inet_pfil_hook, mp, bifp, - dir, NULL); + dir, 0, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (V_pfil_member && ifp != NULL) error = pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, - dir, NULL); + dir, 0, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (V_pfil_bridge && dir == PFIL_IN && bifp != NULL) error = pfil_run_hooks(&V_inet_pfil_hook, mp, bifp, - dir, NULL); + dir, 0, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; @@ -3284,21 +3285,21 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) case ETHERTYPE_IPV6: if (V_pfil_bridge && dir == PFIL_OUT && bifp != NULL) error = pfil_run_hooks(&V_inet6_pfil_hook, mp, bifp, - dir, NULL); + dir, 0, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (V_pfil_member && ifp != NULL) error = pfil_run_hooks(&V_inet6_pfil_hook, mp, ifp, - dir, NULL); + dir, 0, NULL); if (*mp == NULL || error != 0) /* filter may consume */ break; if (V_pfil_bridge && dir == PFIL_IN && bifp != NULL) error = pfil_run_hooks(&V_inet6_pfil_hook, mp, bifp, - dir, NULL); + dir, 0, NULL); break; #endif default: diff --git a/freebsd/sys/net/if_enc.c b/freebsd/sys/net/if_enc.c index 34022795..8ca8aa4d 100644 --- a/freebsd/sys/net/if_enc.c +++ b/freebsd/sys/net/if_enc.c @@ -303,7 +303,7 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, void *udata, void *ctx_data, /* Make a packet looks like it was received on enc(4) */ rcvif = (*ctx->mp)->m_pkthdr.rcvif; (*ctx->mp)->m_pkthdr.rcvif = ifp; - if (pfil_run_hooks(ph, ctx->mp, ifp, pdir, ctx->inp) != 0 || + if (pfil_run_hooks(ph, ctx->mp, ifp, pdir, 0, ctx->inp) != 0 || *ctx->mp == NULL) { *ctx->mp = NULL; /* consumed by filter */ return (EACCES); diff --git a/freebsd/sys/net/if_ethersubr.c b/freebsd/sys/net/if_ethersubr.c index 24f11436..78ff2385 100644 --- a/freebsd/sys/net/if_ethersubr.c +++ b/freebsd/sys/net/if_ethersubr.c @@ -49,6 +49,7 @@ #include <sys/malloc.h> #include <sys/module.h> #include <sys/mbuf.h> +#include <sys/priv.h> #include <sys/random.h> #include <sys/socket.h> #include <sys/sockio.h> @@ -313,7 +314,13 @@ ether_output(struct ifnet *ifp, struct mbuf *m, if (lle == NULL) { /* if we lookup, keep cache */ addref = 1; - } + } else + /* + * Notify LLE code that + * the entry was used + * by datapath. + */ + llentry_mark_used(lle); } if (lle != NULL) { phdr = lle->r_linkdata; @@ -433,6 +440,19 @@ bad: if (m != NULL) return ether_output_frame(ifp, m); } +static bool +ether_set_pcp(struct mbuf **mp, struct ifnet *ifp, uint8_t pcp) +{ + struct ether_header *eh; + + eh = mtod(*mp, struct ether_header *); + if (ntohs(eh->ether_type) == ETHERTYPE_VLAN || + ether_8021q_frame(mp, ifp, ifp, 0, pcp)) + return (true); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + return (false); +} + /* * Ethernet link layer output routine to send a raw frame to the device. * @@ -442,12 +462,17 @@ bad: if (m != NULL) int ether_output_frame(struct ifnet *ifp, struct mbuf *m) { - int i; + int error; + uint8_t pcp; - if (PFIL_HOOKED(&V_link_pfil_hook)) { - i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_OUT, NULL); + pcp = ifp->if_pcp; + if (pcp != IFNET_PCP_NONE && !ether_set_pcp(&m, ifp, pcp)) + return (0); - if (i != 0) + if (PFIL_HOOKED(&V_link_pfil_hook)) { + error = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, + PFIL_OUT, 0, NULL); + if (error != 0) return (EACCES); if (m == NULL) @@ -778,7 +803,8 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) /* Do not grab PROMISC frames in case we are re-entered. */ if (PFIL_HOOKED(&V_link_pfil_hook) && !(m->m_flags & M_PROMISC)) { - i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_IN, NULL); + i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_IN, 0, + NULL); if (i != 0 || m == NULL) return; @@ -1084,13 +1110,8 @@ ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; case SIOCGIFADDR: - { - struct sockaddr *sa; - - sa = (struct sockaddr *) & ifr->ifr_data; - bcopy(IF_LLADDR(ifp), - (caddr_t) sa->sa_data, ETHER_ADDR_LEN); - } + bcopy(IF_LLADDR(ifp), &ifr->ifr_addr.sa_data[0], + ETHER_ADDR_LEN); break; case SIOCSIFMTU: @@ -1103,6 +1124,22 @@ ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_mtu = ifr->ifr_mtu; } break; + + case SIOCSLANPCP: + error = priv_check(curthread, PRIV_NET_SETLANPCP); + if (error != 0) + break; + if (ifr->ifr_lan_pcp > 7 && + ifr->ifr_lan_pcp != IFNET_PCP_NONE) + error = EINVAL; + else + ifp->if_pcp = ifr->ifr_lan_pcp; + break; + + case SIOCGLANPCP: + ifr->ifr_lan_pcp = ifp->if_pcp; + break; + default: error = EINVAL; /* XXX netbsd has ENOTTY??? */ break; @@ -1251,5 +1288,86 @@ ether_vlanencap(struct mbuf *m, uint16_t tag) return (m); } +static SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW, 0, + "IEEE 802.1Q VLAN"); +static SYSCTL_NODE(_net_link_vlan, PF_LINK, link, CTLFLAG_RW, 0, + "for consistency"); + +static VNET_DEFINE(int, soft_pad); +#define V_soft_pad VNET(soft_pad) +SYSCTL_INT(_net_link_vlan, OID_AUTO, soft_pad, CTLFLAG_RW | CTLFLAG_VNET, + &VNET_NAME(soft_pad), 0, + "pad short frames before tagging"); + +/* + * For now, make preserving PCP via an mbuf tag optional, as it increases + * per-packet memory allocations and frees. In the future, it would be + * preferable to reuse ether_vtag for this, or similar. + */ +int vlan_mtag_pcp = 0; +SYSCTL_INT(_net_link_vlan, OID_AUTO, mtag_pcp, CTLFLAG_RW, + &vlan_mtag_pcp, 0, + "Retain VLAN PCP information as packets are passed up the stack"); + +bool +ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p, + uint16_t vid, uint8_t pcp) +{ + struct m_tag *mtag; + int n; + uint16_t tag; + static const char pad[8]; /* just zeros */ + + /* + * Pad the frame to the minimum size allowed if told to. + * This option is in accord with IEEE Std 802.1Q, 2003 Ed., + * paragraph C.4.4.3.b. It can help to work around buggy + * bridges that violate paragraph C.4.4.3.a from the same + * document, i.e., fail to pad short frames after untagging. + * E.g., a tagged frame 66 bytes long (incl. FCS) is OK, but + * untagging it will produce a 62-byte frame, which is a runt + * and requires padding. There are VLAN-enabled network + * devices that just discard such runts instead or mishandle + * them somehow. + */ + if (V_soft_pad && p->if_type == IFT_ETHER) { + for (n = ETHERMIN + ETHER_HDR_LEN - (*mp)->m_pkthdr.len; + n > 0; n -= sizeof(pad)) { + if (!m_append(*mp, min(n, sizeof(pad)), pad)) + break; + } + if (n > 0) { + m_freem(*mp); + *mp = NULL; + if_printf(ife, "cannot pad short frame"); + return (false); + } + } + + /* + * If underlying interface can do VLAN tag insertion itself, + * just pass the packet along. However, we need some way to + * tell the interface where the packet came from so that it + * knows how to find the VLAN tag to use, so we attach a + * packet tag that holds it. + */ + if (vlan_mtag_pcp && (mtag = m_tag_locate(*mp, MTAG_8021Q, + MTAG_8021Q_PCP_OUT, NULL)) != NULL) + tag = EVL_MAKETAG(vid, *(uint8_t *)(mtag + 1), 0); + else + tag = EVL_MAKETAG(vid, pcp, 0); + if (p->if_capenable & IFCAP_VLAN_HWTAGGING) { + (*mp)->m_pkthdr.ether_vtag = tag; + (*mp)->m_flags |= M_VLANTAG; + } else { + *mp = ether_vlanencap(*mp, tag); + if (*mp == NULL) { + if_printf(ife, "unable to prepend 802.1Q header"); + return (false); + } + } + return (true); +} + DECLARE_MODULE(ether, ether_mod, SI_SUB_INIT_IF, SI_ORDER_ANY); MODULE_VERSION(ether, 1); diff --git a/freebsd/sys/net/if_fddisubr.c b/freebsd/sys/net/if_fddisubr.c index 3c159a22..c011346e 100644 --- a/freebsd/sys/net/if_fddisubr.c +++ b/freebsd/sys/net/if_fddisubr.c @@ -560,14 +560,9 @@ fddi_ioctl (ifp, command, data) break; } break; - case SIOCGIFADDR: { - struct sockaddr *sa; - - sa = (struct sockaddr *) & ifr->ifr_data; - bcopy(IF_LLADDR(ifp), - (caddr_t) sa->sa_data, FDDI_ADDR_LEN); - - } + case SIOCGIFADDR: + bcopy(IF_LLADDR(ifp), &ifr->ifr_addr.sa_data[0], + FDDI_ADDR_LEN); break; case SIOCSIFMTU: /* diff --git a/freebsd/sys/net/if_fwsubr.c b/freebsd/sys/net/if_fwsubr.c index f9552838..3b39b841 100644 --- a/freebsd/sys/net/if_fwsubr.c +++ b/freebsd/sys/net/if_fwsubr.c @@ -664,13 +664,8 @@ firewire_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; case SIOCGIFADDR: - { - struct sockaddr *sa; - - sa = (struct sockaddr *) & ifr->ifr_data; - bcopy(&IFP2FWC(ifp)->fc_hwaddr, - (caddr_t) sa->sa_data, sizeof(struct fw_hwaddr)); - } + bcopy(&IFP2FWC(ifp)->fc_hwaddr, &ifr->ifr_addr.sa_data[0], + sizeof(struct fw_hwaddr)); break; case SIOCSIFMTU: diff --git a/freebsd/sys/net/if_gif.c b/freebsd/sys/net/if_gif.c index bd33ab75..6a90538a 100644 --- a/freebsd/sys/net/if_gif.c +++ b/freebsd/sys/net/if_gif.c @@ -904,12 +904,14 @@ gif_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; case GIFGOPTS: options = sc->gif_options; - error = copyout(&options, ifr->ifr_data, sizeof(options)); + error = copyout(&options, ifr_data_get_ptr(ifr), + sizeof(options)); break; case GIFSOPTS: if ((error = priv_check(curthread, PRIV_NET_GIF)) != 0) break; - error = copyin(ifr->ifr_data, &options, sizeof(options)); + error = copyin(ifr_data_get_ptr(ifr), &options, + sizeof(options)); if (error) break; if (options & ~GIF_OPTMASK) diff --git a/freebsd/sys/net/if_gre.c b/freebsd/sys/net/if_gre.c index dd9ba8f3..0bff9bc9 100644 --- a/freebsd/sys/net/if_gre.c +++ b/freebsd/sys/net/if_gre.c @@ -461,7 +461,8 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case GRESKEY: if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0) break; - if ((error = copyin(ifr->ifr_data, &opt, sizeof(opt))) != 0) + if ((error = copyin(ifr_data_get_ptr(ifr), &opt, + sizeof(opt))) != 0) break; if (sc->gre_key != opt) { GRE_WLOCK(sc); @@ -471,13 +472,14 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } break; case GREGKEY: - error = copyout(&sc->gre_key, ifr->ifr_data, + error = copyout(&sc->gre_key, ifr_data_get_ptr(ifr), sizeof(sc->gre_key)); break; case GRESOPTS: if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0) break; - if ((error = copyin(ifr->ifr_data, &opt, sizeof(opt))) != 0) + if ((error = copyin(ifr_data_get_ptr(ifr), &opt, + sizeof(opt))) != 0) break; if (opt & ~GRE_OPTMASK) error = EINVAL; @@ -492,7 +494,7 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; case GREGOPTS: - error = copyout(&sc->gre_options, ifr->ifr_data, + error = copyout(&sc->gre_options, ifr_data_get_ptr(ifr), sizeof(sc->gre_options)); break; default: diff --git a/freebsd/sys/net/if_ipsec.c b/freebsd/sys/net/if_ipsec.c index 13d3f44b..91afe2ab 100644 --- a/freebsd/sys/net/if_ipsec.c +++ b/freebsd/sys/net/if_ipsec.c @@ -694,12 +694,12 @@ ipsec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; case IPSECGREQID: reqid = sc->reqid; - error = copyout(&reqid, ifr->ifr_data, sizeof(reqid)); + error = copyout(&reqid, ifr_data_get_ptr(ifr), sizeof(reqid)); break; case IPSECSREQID: if ((error = priv_check(curthread, PRIV_NET_SETIFCAP)) != 0) break; - error = copyin(ifr->ifr_data, &reqid, sizeof(reqid)); + error = copyin(ifr_data_get_ptr(ifr), &reqid, sizeof(reqid)); if (error != 0) break; error = ipsec_set_reqid(ifp, reqid); diff --git a/freebsd/sys/net/if_iso88025subr.c b/freebsd/sys/net/if_iso88025subr.c deleted file mode 100644 index cba09bf5..00000000 --- a/freebsd/sys/net/if_iso88025subr.c +++ /dev/null @@ -1,701 +0,0 @@ -#include <machine/rtems-bsd-kernel-space.h> - -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998, Larry Lile - * All rights reserved. - * - * For latest sources and information on this driver, please - * go to http://anarchy.stdio.com. - * - * Questions, comments or suggestions should be directed to - * Larry Lile <lile@stdio.com>. - * - * 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 unmodified, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - * - */ - -/* - * - * General ISO 802.5 (Token Ring) support routines - * - */ - -#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_arp.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/iso88025.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 - -#include <security/mac/mac_framework.h> - -static const u_char iso88025_broadcastaddr[ISO88025_ADDR_LEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -static int iso88025_resolvemulti (struct ifnet *, struct sockaddr **, - struct sockaddr *); - -#define senderr(e) do { error = (e); goto bad; } while (0) - -/* - * Perform common duties while attaching to interface list - */ -void -iso88025_ifattach(struct ifnet *ifp, const u_int8_t *lla, int bpf) -{ - struct ifaddr *ifa; - struct sockaddr_dl *sdl; - - ifa = NULL; - - ifp->if_type = IFT_ISO88025; - ifp->if_addrlen = ISO88025_ADDR_LEN; - ifp->if_hdrlen = ISO88025_HDR_LEN; - - if_attach(ifp); /* Must be called before additional assignments */ - - ifp->if_output = iso88025_output; - ifp->if_input = iso88025_input; - ifp->if_resolvemulti = iso88025_resolvemulti; - ifp->if_broadcastaddr = iso88025_broadcastaddr; - - if (ifp->if_baudrate == 0) - ifp->if_baudrate = TR_16MBPS; /* 16Mbit should be a safe default */ - if (ifp->if_mtu == 0) - ifp->if_mtu = ISO88025_DEFAULT_MTU; - - ifa = ifp->if_addr; - KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); - - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - sdl->sdl_type = IFT_ISO88025; - sdl->sdl_alen = ifp->if_addrlen; - bcopy(lla, LLADDR(sdl), ifp->if_addrlen); - - if (bpf) - bpfattach(ifp, DLT_IEEE802, ISO88025_HDR_LEN); - - return; -} - -/* - * Perform common duties while detaching a Token Ring interface - */ -void -iso88025_ifdetach(ifp, bpf) - struct ifnet *ifp; - int bpf; -{ - - if (bpf) - bpfdetach(ifp); - - if_detach(ifp); - - return; -} - -int -iso88025_ioctl(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: - ifp->if_init(ifp->if_softc); /* before arpwhohas */ - arp_ifinit(ifp, ifa); - break; -#endif /* INET */ - default: - ifp->if_init(ifp->if_softc); - break; - } - break; - - case SIOCGIFADDR: { - struct sockaddr *sa; - - sa = (struct sockaddr *) & ifr->ifr_data; - bcopy(IF_LLADDR(ifp), - (caddr_t) sa->sa_data, ISO88025_ADDR_LEN); - } - break; - - case SIOCSIFMTU: - /* - * Set the interface MTU. - */ - if (ifr->ifr_mtu > ISO88025_MAX_MTU) { - error = EINVAL; - } else { - ifp->if_mtu = ifr->ifr_mtu; - } - break; - default: - error = EINVAL; /* XXX netbsd has ENOTTY??? */ - break; - } - - return (error); -} - -/* - * ISO88025 encapsulation - */ -int -iso88025_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, - struct route *ro) -{ - u_int16_t snap_type = 0; - int loop_copy = 0, error = 0, rif_len = 0; - u_char edst[ISO88025_ADDR_LEN]; - struct iso88025_header *th; - struct iso88025_header gen_th; - struct sockaddr_dl *sdl = NULL; - struct rtentry *rt0 = NULL; - int is_gw = 0; - - if (ro != NULL) - is_gw = (ro->ro_flags & RT_HAS_GW) != 0; -#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); - - /* Calculate routing info length based on arp table entry */ - /* XXX any better way to do this ? */ - - if (rt0 && (sdl = (struct sockaddr_dl *)rt0->rt_gateway)) - if (SDL_ISO88025(sdl)->trld_rcf != 0) - rif_len = TR_RCF_RIFLEN(SDL_ISO88025(sdl)->trld_rcf); - - /* Generate a generic 802.5 header for the packet */ - gen_th.ac = TR_AC; - gen_th.fc = TR_LLC_FRAME; - (void)memcpy((caddr_t)gen_th.iso88025_shost, IF_LLADDR(ifp), - ISO88025_ADDR_LEN); - if (rif_len) { - gen_th.iso88025_shost[0] |= TR_RII; - if (rif_len > 2) { - gen_th.rcf = SDL_ISO88025(sdl)->trld_rcf; - (void)memcpy((caddr_t)gen_th.rd, - (caddr_t)SDL_ISO88025(sdl)->trld_route, - rif_len - 2); - } - } - - 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); - snap_type = ETHERTYPE_IP; - break; - case AF_ARP: - { - struct arphdr *ah; - ah = mtod(m, struct arphdr *); - ah->ar_hrd = htons(ARPHRD_IEEE802); - - loop_copy = -1; /* if this is for us, don't do it */ - - switch(ntohs(ah->ar_op)) { - case ARPOP_REVREQUEST: - case ARPOP_REVREPLY: - snap_type = ETHERTYPE_REVARP; - break; - case ARPOP_REQUEST: - case ARPOP_REPLY: - default: - snap_type = ETHERTYPE_ARP; - break; - } - - if (m->m_flags & M_BCAST) - bcopy(ifp->if_broadcastaddr, edst, ISO88025_ADDR_LEN); - else - bcopy(ar_tha(ah), edst, ISO88025_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); - snap_type = ETHERTYPE_IPV6; - break; -#endif /* INET6 */ - case AF_UNSPEC: - { - const struct iso88025_sockaddr_data *sd; - /* - * For AF_UNSPEC sockaddr.sa_data must contain all of the - * mac information needed to send the packet. This allows - * full mac, llc, and source routing function to be controlled. - * llc and source routing information must already be in the - * mbuf provided, ac/fc are set in sa_data. sockaddr.sa_data - * should be an iso88025_sockaddr_data structure see iso88025.h - */ - loop_copy = -1; - sd = (const struct iso88025_sockaddr_data *)dst->sa_data; - gen_th.ac = sd->ac; - gen_th.fc = sd->fc; - (void)memcpy(edst, sd->ether_dhost, ISO88025_ADDR_LEN); - (void)memcpy(gen_th.iso88025_shost, sd->ether_shost, - ISO88025_ADDR_LEN); - rif_len = 0; - break; - } - default: - if_printf(ifp, "can't handle af%d\n", dst->sa_family); - senderr(EAFNOSUPPORT); - break; - } - - /* - * Add LLC header. - */ - if (snap_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(snap_type); - } - - /* - * Add local net header. If no space in first mbuf, - * allocate another. - */ - M_PREPEND(m, ISO88025_HDR_LEN + rif_len, M_NOWAIT); - if (m == NULL) - senderr(ENOBUFS); - th = mtod(m, struct iso88025_header *); - bcopy((caddr_t)edst, (caddr_t)&gen_th.iso88025_dhost, ISO88025_ADDR_LEN); - - /* Copy as much of the generic header as is needed into the mbuf */ - memcpy(th, &gen_th, ISO88025_HDR_LEN + rif_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, - ISO88025_HDR_LEN); - } else if (bcmp(th->iso88025_dhost, th->iso88025_shost, - ETHER_ADDR_LEN) == 0) { - (void) if_simloop(ifp, m, dst->sa_family, - ISO88025_HDR_LEN); - return(0); /* XXX */ - } - } - - IFQ_HANDOFF_ADJ(ifp, m, ISO88025_HDR_LEN + LLC_SNAPFRAMELEN, error); - if (error) { - printf("iso88025_output: packet dropped QFULL.\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - } - return (error); - -bad: - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - if (m) - m_freem(m); - return (error); -} - -/* - * ISO 88025 de-encapsulation - */ -void -iso88025_input(ifp, m) - struct ifnet *ifp; - struct mbuf *m; -{ - struct iso88025_header *th; - struct llc *l; - int isr; - int mac_hdr_len; - - /* - * 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, ISO88025_HDR_LEN); - if (m == NULL) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); - goto dropanyway; - } - th = mtod(m, struct iso88025_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) && - ((th->iso88025_dhost[0] & 1) == 0) && - (bcmp(IF_LLADDR(ifp), (caddr_t) th->iso88025_dhost, - ISO88025_ADDR_LEN) != 0)) - goto dropanyway; - - /* - * Set mbuf flags for bcast/mcast. - */ - if (th->iso88025_dhost[0] & 1) { - if (bcmp(iso88025_broadcastaddr, th->iso88025_dhost, - ISO88025_ADDR_LEN) == 0) - m->m_flags |= M_BCAST; - else - m->m_flags |= M_MCAST; - if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1); - } - - mac_hdr_len = ISO88025_HDR_LEN; - /* Check for source routing info */ - if (th->iso88025_shost[0] & TR_RII) - mac_hdr_len += TR_RCF_RIFLEN(th->rcf); - - /* Strip off ISO88025 header. */ - m_adj(m, mac_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: - th->iso88025_shost[0] &= ~(TR_RII); - isr = NETISR_IP; - break; - - case ETHERTYPE_ARP: - if (ifp->if_flags & IFF_NOARP) - goto dropanyway; - isr = NETISR_ARP; - break; -#endif /* INET */ -#ifdef INET6 - case ETHERTYPE_IPV6: - th->iso88025_shost[0] &= ~(TR_RII); - isr = NETISR_IPV6; - break; -#endif /* INET6 */ - default: - printf("iso88025_input: unexpected llc_snap ether_type 0x%02x\n", type); - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); - goto dropanyway; - } - break; - } -#ifdef ISO - case LLC_ISO_LSAP: - switch (l->llc_control) { - case LLC_UI: - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); - goto dropanyway; - break; - case LLC_XID: - case LLC_XID_P: - if(m->m_len < ISO88025_ADDR_LEN) - goto dropanyway; - l->llc_window = 0; - l->llc_fid = 9; - l->llc_class = 1; - l->llc_dsap = l->llc_ssap = 0; - /* Fall through to */ - case LLC_TEST: - case LLC_TEST_P: - { - struct sockaddr sa; - struct iso88025_sockaddr_data *th2; - int i; - u_char c; - - c = l->llc_dsap; - - if (th->iso88025_shost[0] & TR_RII) { /* XXX */ - printf("iso88025_input: dropping source routed LLC_TEST\n"); - goto dropanyway; - } - l->llc_dsap = l->llc_ssap; - l->llc_ssap = c; - if (m->m_flags & (M_BCAST | M_MCAST)) - bcopy((caddr_t)IF_LLADDR(ifp), - (caddr_t)th->iso88025_dhost, - ISO88025_ADDR_LEN); - sa.sa_family = AF_UNSPEC; - sa.sa_len = sizeof(sa); - th2 = (struct iso88025_sockaddr_data *)sa.sa_data; - for (i = 0; i < ISO88025_ADDR_LEN; i++) { - th2->ether_shost[i] = c = th->iso88025_dhost[i]; - th2->ether_dhost[i] = th->iso88025_dhost[i] = - th->iso88025_shost[i]; - th->iso88025_shost[i] = c; - } - th2->ac = TR_AC; - th2->fc = TR_LLC_FRAME; - ifp->if_output(ifp, m, &sa, NULL); - return; - } - default: - printf("iso88025_input: unexpected llc control 0x%02x\n", l->llc_control); - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); - goto dropanyway; - break; - } - break; -#endif /* ISO */ - default: - printf("iso88025_input: unknown dsap 0x%x\n", l->llc_dsap); - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); - goto dropanyway; - break; - } - - 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; -} - -static int -iso88025_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_ISO88025); - sdl->sdl_alen = ISO88025_ADDR_LEN; - 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_ISO88025); - sdl->sdl_alen = ISO88025_ADDR_LEN; - 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 iso88025_mod = { - .name = "iso88025", -}; - -DECLARE_MODULE(iso88025, iso88025_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); -MODULE_VERSION(iso88025, 1); diff --git a/freebsd/sys/net/if_llatbl.h b/freebsd/sys/net/if_llatbl.h index fcf93883..9cec4ac7 100644 --- a/freebsd/sys/net/if_llatbl.h +++ b/freebsd/sys/net/if_llatbl.h @@ -149,6 +149,7 @@ typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *); typedef void (llt_free_tbl_t)(struct lltable *); typedef void (llt_link_entry_t)(struct lltable *, struct llentry *); typedef void (llt_unlink_entry_t)(struct llentry *); +typedef void (llt_mark_used_t)(struct llentry *); typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *); typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *); @@ -173,6 +174,7 @@ struct lltable { llt_unlink_entry_t *llt_unlink_entry; llt_fill_sa_entry_t *llt_fill_sa_entry; llt_free_tbl_t *llt_free_tbl; + llt_mark_used_t *llt_mark_used; }; MALLOC_DECLARE(M_LLTABLE); @@ -247,6 +249,19 @@ lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr) return (llt->llt_lookup(llt, flags, l3addr)); } +/* + * Notify the LLE code that the entry was used by datapath. + */ +static __inline void +llentry_mark_used(struct llentry *lle) +{ + + if (lle->r_skip_req == 0) + return; + if ((lle->r_flags & RLLE_VALID) != 0) + lle->lle_tbl->llt_mark_used(lle); +} + int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *); #include <sys/eventhandler.h> diff --git a/freebsd/sys/net/if_media.h b/freebsd/sys/net/if_media.h index 13621a10..ecc2b418 100644 --- a/freebsd/sys/net/if_media.h +++ b/freebsd/sys/net/if_media.h @@ -270,7 +270,7 @@ uint64_t ifmedia_baudrate(int); #define IFM_IEEE80211_OFDM27 23 /* OFDM 27Mbps */ /* NB: not enough bits to express MCS fully */ #define IFM_IEEE80211_MCS 24 /* HT MCS rate */ -#define IFM_IEEE80211_VHT 25 /* HT MCS rate */ +#define IFM_IEEE80211_VHT 25 /* VHT MCS rate */ #define IFM_IEEE80211_ADHOC 0x00000100 /* Operate in Adhoc mode */ #define IFM_IEEE80211_HOSTAP 0x00000200 /* Operate in Host AP mode */ diff --git a/freebsd/sys/net/if_spppsubr.c b/freebsd/sys/net/if_spppsubr.c index 306b7e2f..1f85c00f 100644 --- a/freebsd/sys/net/if_spppsubr.c +++ b/freebsd/sys/net/if_spppsubr.c @@ -5060,17 +5060,17 @@ sppp_params(struct sppp *sp, u_long cmd, void *data) if ((spr = malloc(sizeof(struct spppreq), M_TEMP, M_NOWAIT)) == NULL) return (EAGAIN); /* - * ifr->ifr_data is supposed to point to a struct spppreq. + * ifr_data_get_ptr(ifr) is supposed to point to a struct spppreq. * Check the cmd word first before attempting to fetch all the * data. */ - rv = fueword(ifr->ifr_data, &subcmd); + rv = fueword(ifr_data_get_ptr(ifr), &subcmd); if (rv == -1) { rv = EFAULT; goto quit; } - if (copyin((caddr_t)ifr->ifr_data, spr, sizeof(struct spppreq)) != 0) { + if (copyin(ifr_data_get_ptr(ifr), spr, sizeof(struct spppreq)) != 0) { rv = EFAULT; goto quit; } @@ -5107,8 +5107,8 @@ sppp_params(struct sppp *sp, u_long cmd, void *data) * setting it. */ spr->defs.lcp.timeout = sp->lcp.timeout * 1000 / hz; - rv = copyout(spr, (caddr_t)ifr->ifr_data, - sizeof(struct spppreq)); + rv = copyout(spr, ifr_data_get_ptr(ifr), + sizeof(struct spppreq)); break; case (u_long)SPPPIOSDEFS: diff --git a/freebsd/sys/net/if_var.h b/freebsd/sys/net/if_var.h index e22beea7..a131c496 100644 --- a/freebsd/sys/net/if_var.h +++ b/freebsd/sys/net/if_var.h @@ -365,6 +365,9 @@ struct ifnet { if_snd_tag_query_t *if_snd_tag_query; if_snd_tag_free_t *if_snd_tag_free; + /* Ethernet PCP */ + uint8_t if_pcp; + #ifndef __rtems__ /* * Spare fields to be added before branching a stable branch, so @@ -730,6 +733,9 @@ int drbr_enqueue_drv(if_t ifp, struct buf_ring *br, struct mbuf *m); void if_hw_tsomax_common(if_t ifp, struct ifnet_hw_tsomax *); int if_hw_tsomax_update(if_t ifp, struct ifnet_hw_tsomax *); +/* accessors for struct ifreq */ +void *ifr_data_get_ptr(void *ifrp); + #ifdef DEVICE_POLLING enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS }; diff --git a/freebsd/sys/net/if_vlan.c b/freebsd/sys/net/if_vlan.c index 872b07ad..79294427 100644 --- a/freebsd/sys/net/if_vlan.c +++ b/freebsd/sys/net/if_vlan.c @@ -198,25 +198,7 @@ static struct { {0, NULL} }; -SYSCTL_DECL(_net_link); -static SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW, 0, - "IEEE 802.1Q VLAN"); -static SYSCTL_NODE(_net_link_vlan, PF_LINK, link, CTLFLAG_RW, 0, - "for consistency"); - -static VNET_DEFINE(int, soft_pad); -#define V_soft_pad VNET(soft_pad) -SYSCTL_INT(_net_link_vlan, OID_AUTO, soft_pad, CTLFLAG_RW | CTLFLAG_VNET, - &VNET_NAME(soft_pad), 0, "pad short frames before tagging"); - -/* - * For now, make preserving PCP via an mbuf tag optional, as it increases - * per-packet memory allocations and frees. In the future, it would be - * preferable to reuse ether_vtag for this, or similar. - */ -static int vlan_mtag_pcp = 0; -SYSCTL_INT(_net_link_vlan, OID_AUTO, mtag_pcp, CTLFLAG_RW, &vlan_mtag_pcp, 0, - "Retain VLAN PCP information as packets are passed up the stack"); +extern int vlan_mtag_pcp; static const char vlanname[] = "vlan"; static MALLOC_DEFINE(M_VLAN, vlanname, "802.1Q Virtual LAN Interface"); @@ -1173,8 +1155,6 @@ vlan_transmit(struct ifnet *ifp, struct mbuf *m) { struct ifvlan *ifv; struct ifnet *p; - struct m_tag *mtag; - uint16_t tag; int error, len, mcast; VLAN_LOCK_READER; @@ -1203,59 +1183,10 @@ vlan_transmit(struct ifnet *ifp, struct mbuf *m) return (ENETDOWN); } - /* - * Pad the frame to the minimum size allowed if told to. - * This option is in accord with IEEE Std 802.1Q, 2003 Ed., - * paragraph C.4.4.3.b. It can help to work around buggy - * bridges that violate paragraph C.4.4.3.a from the same - * document, i.e., fail to pad short frames after untagging. - * E.g., a tagged frame 66 bytes long (incl. FCS) is OK, but - * untagging it will produce a 62-byte frame, which is a runt - * and requires padding. There are VLAN-enabled network - * devices that just discard such runts instead or mishandle - * them somehow. - */ - if (V_soft_pad && p->if_type == IFT_ETHER) { - static char pad[8]; /* just zeros */ - int n; - - for (n = ETHERMIN + ETHER_HDR_LEN - m->m_pkthdr.len; - n > 0; n -= sizeof(pad)) - if (!m_append(m, min(n, sizeof(pad)), pad)) - break; - - if (n > 0) { - if_printf(ifp, "cannot pad short frame\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - VLAN_RUNLOCK(); - m_freem(m); - return (0); - } - } - - /* - * If underlying interface can do VLAN tag insertion itself, - * just pass the packet along. However, we need some way to - * tell the interface where the packet came from so that it - * knows how to find the VLAN tag to use, so we attach a - * packet tag that holds it. - */ - if (vlan_mtag_pcp && (mtag = m_tag_locate(m, MTAG_8021Q, - MTAG_8021Q_PCP_OUT, NULL)) != NULL) - tag = EVL_MAKETAG(ifv->ifv_vid, *(uint8_t *)(mtag + 1), 0); - else - tag = ifv->ifv_tag; - if (p->if_capenable & IFCAP_VLAN_HWTAGGING) { - m->m_pkthdr.ether_vtag = tag; - m->m_flags |= M_VLANTAG; - } else { - m = ether_vlanencap(m, tag); - if (m == NULL) { - if_printf(ifp, "unable to prepend VLAN header\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - VLAN_RUNLOCK(); - return (0); - } + if (!ether_8021q_frame(&m, ifp, p, ifv->ifv_vid, ifv->ifv_pcp)) { + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + VLAN_RUNLOCK(); + return (0); } /* @@ -1861,12 +1792,8 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) #endif break; case SIOCGIFADDR: - { - struct sockaddr *sa; - - sa = (struct sockaddr *)&ifr->ifr_data; - bcopy(IF_LLADDR(ifp), sa->sa_data, ifp->if_addrlen); - } + bcopy(IF_LLADDR(ifp), &ifr->ifr_addr.sa_data[0], + ifp->if_addrlen); break; case SIOCGIFMEDIA: VLAN_SLOCK(); @@ -1932,7 +1859,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } #endif - error = copyin(ifr->ifr_data, &vlr, sizeof(vlr)); + error = copyin(ifr_data_get_ptr(ifr), &vlr, sizeof(vlr)); if (error) break; if (vlr.vlr_parent[0] == '\0') { @@ -1963,7 +1890,7 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) vlr.vlr_tag = ifv->ifv_vid; } VLAN_SUNLOCK(); - error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); + error = copyout(&vlr, ifr_data_get_ptr(ifr), sizeof(vlr)); break; case SIOCSIFFLAGS: diff --git a/freebsd/sys/net/if_vlan_var.h b/freebsd/sys/net/if_vlan_var.h index d27e5104..b926df80 100644 --- a/freebsd/sys/net/if_vlan_var.h +++ b/freebsd/sys/net/if_vlan_var.h @@ -73,22 +73,8 @@ struct vlanreq { #define SIOCSETVLAN SIOCSIFGENERIC #define SIOCGETVLAN SIOCGIFGENERIC -#define SIOCGVLANPCP _IOWR('i', 152, struct ifreq) /* Get VLAN PCP */ -#define SIOCSVLANPCP _IOW('i', 153, struct ifreq) /* Set VLAN PCP */ - -/* - * Names for 802.1q priorities ("802.1p"). Notice that in this scheme, - * (0 < 1), allowing default 0-tagged traffic to take priority over background - * tagged traffic. - */ -#define IEEE8021Q_PCP_BK 1 /* Background (lowest) */ -#define IEEE8021Q_PCP_BE 0 /* Best effort (default) */ -#define IEEE8021Q_PCP_EE 2 /* Excellent effort */ -#define IEEE8021Q_PCP_CA 3 /* Critical applications */ -#define IEEE8021Q_PCP_VI 4 /* Video, < 100ms latency */ -#define IEEE8021Q_PCP_VO 5 /* Video, < 10ms latency */ -#define IEEE8021Q_PCP_IC 6 /* Internetwork control */ -#define IEEE8021Q_PCP_NC 7 /* Network control (highest) */ +#define SIOCGVLANPCP SIOCGLANPCP /* Get VLAN PCP */ +#define SIOCSVLANPCP SIOCSLANPCP /* Set VLAN PCP */ #ifdef _KERNEL /* diff --git a/freebsd/sys/net/iflib.h b/freebsd/sys/net/iflib.h index 3730f0ea..02319322 100644 --- a/freebsd/sys/net/iflib.h +++ b/freebsd/sys/net/iflib.h @@ -229,7 +229,7 @@ typedef struct if_softc_ctx { * Initialization values for device */ struct if_shared_ctx { - int isc_magic; + unsigned isc_magic; driver_t *isc_driver; bus_size_t isc_q_align; bus_size_t isc_tx_maxsize; diff --git a/freebsd/sys/net/iso88025.h b/freebsd/sys/net/iso88025.h deleted file mode 100644 index 78b2737f..00000000 --- a/freebsd/sys/net/iso88025.h +++ /dev/null @@ -1,176 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998, Larry Lile - * All rights reserved. - * - * For latest sources and information on this driver, please - * go to http://anarchy.stdio.com. - * - * Questions, comments or suggestions should be directed to - * Larry Lile <lile@stdio.com>. - * - * 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 unmodified, 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - * - * Information gathered from tokenring@freebsd, /sys/net/ethernet.h and - * the Mach token ring driver. - */ - -/* - * Fundamental constants relating to iso 802.5 - */ - -#ifndef _NET_ISO88025_H_ -#define _NET_ISO88025_H_ - -/* - * General ISO 802.5 definitions - */ -#define ISO88025_ADDR_LEN 6 -#define ISO88025_CF_LEN 2 -#define ISO88025_HDR_LEN (ISO88025_CF_LEN + (ISO88025_ADDR_LEN * 2)) -#define RCF_LEN 2 -#define RIF_MAX_RD 14 -#define RIF_MAX_LEN 16 - -#define TR_AC 0x10 -#define TR_LLC_FRAME 0x40 - -#define TR_4MBPS 4000000 -#define TR_16MBPS 16000000 -#define TR_100MBPS 100000000 - -/* - * Source routing - */ -#define TR_RII 0x80 -#define TR_RCF_BCST_MASK 0xe000 -#define TR_RCF_LEN_MASK 0x1f00 -#define TR_RCF_DIR 0x0080 -#define TR_RCF_LF_MASK 0x0070 - -#define TR_RCF_RIFLEN(x) ((ntohs(x) & TR_RCF_LEN_MASK) >> 8) - -/* - * Minimum and maximum packet payload lengths. - */ -#define ISO88025_MIN_LEN 0 -#define ISO88025_MAX_LEN_4 4464 -#define ISO88025_MAX_LEN_16 17960 -#define ISO88025_MAX_LEN ISO88025_MAX_LEN_16 - -/* - * A macro to validate a length with - */ -#define ISO88025_IS_VALID_LEN(foo) \ - ((foo) >= ISO88025_MIN_LEN && (foo) <= ISO88025_MAX_LEN) - -/* Access Control field */ -#define AC_PRI_MASK 0xe0 /* Priority bits */ -#define AC_TOKEN 0x10 /* Token bit: 0=Token, 1=Frame */ -#define AC_MONITOR 0x08 /* Monitor */ -#define AC_RESV_MASK 0x07 /* Reservation bits */ - -/* Frame Control field */ -#define FC_FT_MASK 0xc0 /* Frame Type */ -#define FC_FT_MAC 0x00 /* MAC frame */ -#define FC_FT_LLC 0x40 /* LLC frame */ -#define FC_ATTN_MASK 0x0f /* Attention bits */ -#define FC_ATTN_EB 0x01 /* Express buffer */ -#define FC_ATTN_BE 0x02 /* Beacon */ -#define FC_ATTN_CT 0x03 /* Claim token */ -#define FC_ATTN_RP 0x04 /* Ring purge */ -#define FC_ATTN_AMP 0x05 /* Active monitor present */ -#define FC_ATTN_SMP 0x06 /* Standby monitor present */ - -/* Token Ring destination address */ -#define DA_IG 0x80 /* Individual/group address. */ - /* 0=Individual, 1=Group */ -#define DA_UL 0x40 /* Universal/local address. */ - /* 0=Universal, 1=Local */ -/* Token Ring source address */ -#define SA_RII 0x80 /* Routing information indicator */ -#define SA_IG 0x40 /* Individual/group address */ - /* 0=Group, 1=Individual */ - -/* - * ISO 802.5 physical header - */ -struct iso88025_header { - u_int8_t ac; /* access control field */ - u_int8_t fc; /* frame control field */ - u_int8_t iso88025_dhost[ISO88025_ADDR_LEN]; /* destination address */ - u_int8_t iso88025_shost[ISO88025_ADDR_LEN]; /* source address */ - u_int16_t rcf; /* route control field */ - u_int16_t rd[RIF_MAX_RD]; /* routing designators */ -} __packed; - -struct iso88025_rif { - u_int16_t rcf; /* route control field */ - u_int16_t rd[RIF_MAX_RD]; /* routing designators */ -} __packed; - -struct iso88025_sockaddr_data { - u_char ether_dhost[ISO88025_ADDR_LEN]; - u_char ether_shost[ISO88025_ADDR_LEN]; - u_char ac; - u_char fc; -}; - -struct iso88025_sockaddr_dl_data { - u_short trld_rcf; - u_short *trld_route[RIF_MAX_LEN]; -}; - -#define ISO88025_MAX(a, b) (((a)>(b))?(a):(b)) -#define SDL_ISO88025(s) ((struct iso88025_sockaddr_dl_data *) \ - ((s)->sdl_data + \ - ISO88025_MAX((s)->sdl_nlen + (s)->sdl_alen + \ - (s)->sdl_slen, 12))) - -/* - * Structure of a 48-bit iso 802.5 address. - * ( We could also add the 16 bit addresses as a union) - */ -struct iso88025_addr { - u_char octet[ISO88025_ADDR_LEN]; -}; - -#define ISO88025_MAX_MTU 18000 -#define ISO88025_DEFAULT_MTU 1500 - -#define ISO88025_BPF_UNSUPPORTED 0 -#define ISO88025_BPF_SUPPORTED 1 - -#ifdef _KERNEL -void iso88025_ifattach (struct ifnet *, const u_int8_t *, int); -void iso88025_ifdetach (struct ifnet *, int); -int iso88025_ioctl (struct ifnet *, u_long, caddr_t ); -int iso88025_output (struct ifnet *, struct mbuf *, - const struct sockaddr *, struct route *); -void iso88025_input (struct ifnet *, struct mbuf *); -#endif /* _KERNEL */ - -#endif /* !_NET_ISO88025_H_ */ diff --git a/freebsd/sys/net/pfil.c b/freebsd/sys/net/pfil.c index e29cd5e7..65af515f 100644 --- a/freebsd/sys/net/pfil.c +++ b/freebsd/sys/net/pfil.c @@ -59,7 +59,8 @@ MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock", static struct packet_filter_hook *pfil_chain_get(int, struct pfil_head *); static int pfil_chain_add(pfil_chain_t *, struct packet_filter_hook *, int); -static int pfil_chain_remove(pfil_chain_t *, pfil_func_t, void *); +static int pfil_chain_remove(pfil_chain_t *, void *, void *); +static int pfil_add_hook_priv(void *, void *, int, struct pfil_head *, bool); LIST_HEAD(pfilheadhead, pfil_head); VNET_DEFINE(struct pfilheadhead, pfil_head_list); @@ -97,7 +98,7 @@ VNET_DEFINE(struct rmlock, pfil_lock); */ int pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, - int dir, struct inpcb *inp) + int dir, int flags, struct inpcb *inp) { struct rm_priotracker rmpt; struct packet_filter_hook *pfh; @@ -108,6 +109,12 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp, KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0")); for (pfh = pfil_chain_get(dir, ph); pfh != NULL; pfh = TAILQ_NEXT(pfh, pfil_chain)) { + if (pfh->pfil_func_flags != NULL) { + rv = (*pfh->pfil_func_flags)(pfh->pfil_arg, &m, ifp, + dir, flags, inp); + if (rv != 0 || m == NULL) + break; + } if (pfh->pfil_func != NULL) { rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp); @@ -260,6 +267,21 @@ pfil_head_get(int type, u_long val) } /* + * pfil_add_hook_flags() adds a function to the packet filter hook. the + * flags are: + * PFIL_IN call me on incoming packets + * PFIL_OUT call me on outgoing packets + * PFIL_ALL call me on all of the above + * PFIL_WAITOK OK to call malloc with M_WAITOK. + */ +int +pfil_add_hook_flags(pfil_func_flags_t func, void *arg, int flags, + struct pfil_head *ph) +{ + return (pfil_add_hook_priv(func, arg, flags, ph, true)); +} + +/* * pfil_add_hook() adds a function to the packet filter hook. the * flags are: * PFIL_IN call me on incoming packets @@ -270,6 +292,13 @@ pfil_head_get(int type, u_long val) int pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph) { + return (pfil_add_hook_priv(func, arg, flags, ph, false)); +} + +static int +pfil_add_hook_priv(void *func, void *arg, int flags, + struct pfil_head *ph, bool hasflags) +{ struct packet_filter_hook *pfh1 = NULL; struct packet_filter_hook *pfh2 = NULL; int err; @@ -292,7 +321,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph) } PFIL_WLOCK(ph); if (flags & PFIL_IN) { - pfh1->pfil_func = func; + pfh1->pfil_func_flags = hasflags ? func : NULL; + pfh1->pfil_func = hasflags ? NULL : func; pfh1->pfil_arg = arg; err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT); if (err) @@ -300,7 +330,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph) ph->ph_nhooks++; } if (flags & PFIL_OUT) { - pfh2->pfil_func = func; + pfh2->pfil_func_flags = hasflags ? func : NULL; + pfh2->pfil_func = hasflags ? NULL : func; pfh2->pfil_arg = arg; err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN); if (err) { @@ -323,6 +354,17 @@ error: } /* + * pfil_remove_hook_flags removes a specific function from the packet filter hook + * chain. + */ +int +pfil_remove_hook_flags(pfil_func_flags_t func, void *arg, int flags, + struct pfil_head *ph) +{ + return (pfil_remove_hook((pfil_func_t)func, arg, flags, ph)); +} + +/* * pfil_remove_hook removes a specific function from the packet filter hook * chain. */ @@ -358,7 +400,9 @@ pfil_chain_add(pfil_chain_t *chain, struct packet_filter_hook *pfh1, int flags) * First make sure the hook is not already there. */ TAILQ_FOREACH(pfh, chain, pfil_chain) - if (pfh->pfil_func == pfh1->pfil_func && + if (((pfh->pfil_func != NULL && pfh->pfil_func == pfh1->pfil_func) || + (pfh->pfil_func_flags != NULL && + pfh->pfil_func_flags == pfh1->pfil_func_flags)) && pfh->pfil_arg == pfh1->pfil_arg) return (EEXIST); @@ -377,12 +421,13 @@ pfil_chain_add(pfil_chain_t *chain, struct packet_filter_hook *pfh1, int flags) * Internal: Remove a pfil hook from a hook chain. */ static int -pfil_chain_remove(pfil_chain_t *chain, pfil_func_t func, void *arg) +pfil_chain_remove(pfil_chain_t *chain, void *func, void *arg) { struct packet_filter_hook *pfh; TAILQ_FOREACH(pfh, chain, pfil_chain) - if (pfh->pfil_func == func && pfh->pfil_arg == arg) { + if ((pfh->pfil_func == func || pfh->pfil_func_flags == func) && + pfh->pfil_arg == arg) { TAILQ_REMOVE(chain, pfh, pfil_chain); free(pfh, M_IFADDR); return (0); diff --git a/freebsd/sys/net/pfil.h b/freebsd/sys/net/pfil.h index 2243ad83..8fdaf5a6 100644 --- a/freebsd/sys/net/pfil.h +++ b/freebsd/sys/net/pfil.h @@ -48,6 +48,8 @@ struct inpcb; typedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *); +typedef int (*pfil_func_flags_t)(void *, struct mbuf **, struct ifnet *, + int, int, struct inpcb *); /* * The packet filter hooks are designed for anything to call them to @@ -56,13 +58,15 @@ typedef int (*pfil_func_t)(void *, struct mbuf **, struct ifnet *, int, */ struct packet_filter_hook { TAILQ_ENTRY(packet_filter_hook) pfil_chain; - pfil_func_t pfil_func; - void *pfil_arg; + pfil_func_t pfil_func; + pfil_func_flags_t pfil_func_flags; + void *pfil_arg; }; #define PFIL_IN 0x00000001 #define PFIL_OUT 0x00000002 #define PFIL_WAITOK 0x00000004 +#define PFIL_FWD 0x00000008 #define PFIL_ALL (PFIL_IN|PFIL_OUT) typedef TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t; @@ -102,13 +106,15 @@ VNET_DECLARE(struct rmlock, pfil_lock); /* Public functions for pfil hook management by packet filters. */ struct pfil_head *pfil_head_get(int, u_long); +int pfil_add_hook_flags(pfil_func_flags_t, void *, int, struct pfil_head *); int pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *); +int pfil_remove_hook_flags(pfil_func_flags_t, void *, int, struct pfil_head *); int pfil_remove_hook(pfil_func_t, void *, int, struct pfil_head *); #define PFIL_HOOKED(p) ((p)->ph_nhooks > 0) /* Public functions to run the packet inspection by protocols. */ -int pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, - int, struct inpcb *inp); +int pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *, int, + int, struct inpcb *inp); /* Public functions for pfil head management by protocols. */ int pfil_head_register(struct pfil_head *); diff --git a/freebsd/sys/net/pfvar.h b/freebsd/sys/net/pfvar.h index c9b1d1db..dfff0b87 100644 --- a/freebsd/sys/net/pfvar.h +++ b/freebsd/sys/net/pfvar.h @@ -1467,6 +1467,7 @@ struct pf_idhash { extern u_long pf_hashmask; extern u_long pf_srchashmask; #define PF_HASHSIZ (32768) +#define PF_SRCHASHSIZ (PF_HASHSIZ/4) VNET_DECLARE(struct pf_keyhash *, pf_keyhash); VNET_DECLARE(struct pf_idhash *, pf_idhash); #define V_pf_keyhash VNET(pf_keyhash) @@ -1577,13 +1578,13 @@ extern void pf_addrcpy(struct pf_addr *, struct pf_addr *, void pf_free_rule(struct pf_rule *); #ifdef INET -int pf_test(int, struct ifnet *, struct mbuf **, struct inpcb *); +int pf_test(int, int, struct ifnet *, struct mbuf **, struct inpcb *); int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *, struct pf_pdesc *); #endif /* INET */ #ifdef INET6 -int pf_test6(int, struct ifnet *, struct mbuf **, struct inpcb *); +int pf_test6(int, int, struct ifnet *, struct mbuf **, struct inpcb *); int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *, struct pf_pdesc *); void pf_poolmask(struct pf_addr *, struct pf_addr*, diff --git a/freebsd/sys/net/rtsock.c b/freebsd/sys/net/rtsock.c index 851c30c9..900413a0 100644 --- a/freebsd/sys/net/rtsock.c +++ b/freebsd/sys/net/rtsock.c @@ -686,12 +686,15 @@ route_output(struct mbuf *m, struct socket *so, ...) case RTM_ADD: case RTM_CHANGE: - if (info.rti_info[RTAX_GATEWAY] == NULL) - senderr(EINVAL); + if (rtm->rtm_type == RTM_ADD) { + if (info.rti_info[RTAX_GATEWAY] == NULL) + senderr(EINVAL); + } saved_nrt = NULL; /* support for new ARP code */ - if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && + if (info.rti_info[RTAX_GATEWAY] != NULL && + info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && (rtm->rtm_flags & RTF_LLDATA) != 0) { error = lla_rt_output(rtm, &info); #ifdef INET6 |