Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_vlan.c
Show All 40 Lines | |||||
* ether_output() sends to us via if_transmit(), rewrite them for | * ether_output() sends to us via if_transmit(), rewrite them for | ||||
* use by the real outgoing interface, and ask it to send them. | * use by the real outgoing interface, and ask it to send them. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_inet.h" | #include "opt_inet.h" | ||||
#include "opt_kern_tls.h" | |||||
#include "opt_vlan.h" | #include "opt_vlan.h" | ||||
#include "opt_ratelimit.h" | #include "opt_ratelimit.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/eventhandler.h> | #include <sys/eventhandler.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
struct ifvlanhead *hash; /* dynamic hash-list table */ | struct ifvlanhead *hash; /* dynamic hash-list table */ | ||||
uint16_t hmask; | uint16_t hmask; | ||||
uint16_t hwidth; | uint16_t hwidth; | ||||
#endif | #endif | ||||
int refcnt; | int refcnt; | ||||
}; | }; | ||||
#ifdef RATELIMIT | #if defined(KERN_TLS) || defined(RATELIMIT) | ||||
struct vlan_snd_tag { | struct vlan_snd_tag { | ||||
struct m_snd_tag com; | struct m_snd_tag com; | ||||
struct m_snd_tag *tag; | struct m_snd_tag *tag; | ||||
}; | }; | ||||
static inline struct vlan_snd_tag * | static inline struct vlan_snd_tag * | ||||
mst_to_vst(struct m_snd_tag *mst) | mst_to_vst(struct m_snd_tag *mst) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Lines | |||||
static __inline struct ifvlan * vlan_gethash(struct ifvlantrunk *trunk, | static __inline struct ifvlan * vlan_gethash(struct ifvlantrunk *trunk, | ||||
uint16_t vid); | uint16_t vid); | ||||
#endif | #endif | ||||
static void trunk_destroy(struct ifvlantrunk *trunk); | static void trunk_destroy(struct ifvlantrunk *trunk); | ||||
static void vlan_init(void *foo); | static void vlan_init(void *foo); | ||||
static void vlan_input(struct ifnet *ifp, struct mbuf *m); | static void vlan_input(struct ifnet *ifp, struct mbuf *m); | ||||
static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); | static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); | ||||
#ifdef RATELIMIT | #if defined(KERN_TLS) || defined(RATELIMIT) | ||||
static int vlan_snd_tag_alloc(struct ifnet *, | static int vlan_snd_tag_alloc(struct ifnet *, | ||||
union if_snd_tag_alloc_params *, struct m_snd_tag **); | union if_snd_tag_alloc_params *, struct m_snd_tag **); | ||||
static int vlan_snd_tag_modify(struct m_snd_tag *, | static int vlan_snd_tag_modify(struct m_snd_tag *, | ||||
union if_snd_tag_modify_params *); | union if_snd_tag_modify_params *); | ||||
static int vlan_snd_tag_query(struct m_snd_tag *, | static int vlan_snd_tag_query(struct m_snd_tag *, | ||||
union if_snd_tag_query_params *); | union if_snd_tag_query_params *); | ||||
static void vlan_snd_tag_free(struct m_snd_tag *); | static void vlan_snd_tag_free(struct m_snd_tag *); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 769 Lines • ▼ Show 20 Lines | vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) | ||||
strlcpy(ifp->if_xname, name, IFNAMSIZ); | strlcpy(ifp->if_xname, name, IFNAMSIZ); | ||||
ifp->if_dname = vlanname; | ifp->if_dname = vlanname; | ||||
ifp->if_dunit = unit; | ifp->if_dunit = unit; | ||||
ifp->if_init = vlan_init; | ifp->if_init = vlan_init; | ||||
ifp->if_transmit = vlan_transmit; | ifp->if_transmit = vlan_transmit; | ||||
ifp->if_qflush = vlan_qflush; | ifp->if_qflush = vlan_qflush; | ||||
ifp->if_ioctl = vlan_ioctl; | ifp->if_ioctl = vlan_ioctl; | ||||
#ifdef RATELIMIT | #if defined(KERN_TLS) || defined(RATELIMIT) | ||||
ifp->if_snd_tag_alloc = vlan_snd_tag_alloc; | ifp->if_snd_tag_alloc = vlan_snd_tag_alloc; | ||||
ifp->if_snd_tag_modify = vlan_snd_tag_modify; | ifp->if_snd_tag_modify = vlan_snd_tag_modify; | ||||
ifp->if_snd_tag_query = vlan_snd_tag_query; | ifp->if_snd_tag_query = vlan_snd_tag_query; | ||||
ifp->if_snd_tag_free = vlan_snd_tag_free; | ifp->if_snd_tag_free = vlan_snd_tag_free; | ||||
#endif | #endif | ||||
ifp->if_flags = VLAN_IFFLAGS; | ifp->if_flags = VLAN_IFFLAGS; | ||||
ether_ifattach(ifp, eaddr); | ether_ifattach(ifp, eaddr); | ||||
/* Now undo some of the damage... */ | /* Now undo some of the damage... */ | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | if (TRUNK(ifv) == NULL) { | ||||
return (ENETDOWN); | return (ENETDOWN); | ||||
} | } | ||||
p = PARENT(ifv); | p = PARENT(ifv); | ||||
len = m->m_pkthdr.len; | len = m->m_pkthdr.len; | ||||
mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0; | mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0; | ||||
BPF_MTAP(ifp, m); | BPF_MTAP(ifp, m); | ||||
#ifdef RATELIMIT | #if defined(KERN_TLS) || defined(RATELIMIT) | ||||
if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) { | if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) { | ||||
struct vlan_snd_tag *vst; | struct vlan_snd_tag *vst; | ||||
struct m_snd_tag *mst; | struct m_snd_tag *mst; | ||||
MPASS(m->m_pkthdr.snd_tag->ifp == ifp); | MPASS(m->m_pkthdr.snd_tag->ifp == ifp); | ||||
mst = m->m_pkthdr.snd_tag; | mst = m->m_pkthdr.snd_tag; | ||||
vst = mst_to_vst(mst); | vst = mst_to_vst(mst); | ||||
if (vst->tag->ifp != p) { | if (vst->tag->ifp != p) { | ||||
▲ Show 20 Lines • Show All 567 Lines • ▼ Show 20 Lines | #endif | ||||
* the VLAN interface. Note that this should be fine even for | * the VLAN interface. Note that this should be fine even for | ||||
* interfaces that don't support hardware tagging as headers | * interfaces that don't support hardware tagging as headers | ||||
* are prepended in normal mbufs to unmapped mbufs holding | * are prepended in normal mbufs to unmapped mbufs holding | ||||
* payload data. | * payload data. | ||||
*/ | */ | ||||
cap |= (p->if_capabilities & IFCAP_NOMAP); | cap |= (p->if_capabilities & IFCAP_NOMAP); | ||||
ena |= (mena & IFCAP_NOMAP); | ena |= (mena & IFCAP_NOMAP); | ||||
/* | |||||
* If the parent interface can offload encryption and segmentation | |||||
* of TLS records over TCP, propagate it's capability to the VLAN | |||||
* interface. | |||||
* | |||||
* All TLS drivers in the tree today can deal with VLANs. If | |||||
* this ever changes, then a new IFCAP_VLAN_TXTLS can be | |||||
* defined. | |||||
*/ | |||||
if (p->if_capabilities & IFCAP_TXTLS) | |||||
cap |= p->if_capabilities & IFCAP_TXTLS; | |||||
if (p->if_capenable & IFCAP_TXTLS) | |||||
ena |= mena & IFCAP_TXTLS; | |||||
ifp->if_capabilities = cap; | ifp->if_capabilities = cap; | ||||
ifp->if_capenable = ena; | ifp->if_capenable = ena; | ||||
ifp->if_hwassist = hwa; | ifp->if_hwassist = hwa; | ||||
} | } | ||||
static void | static void | ||||
vlan_trunk_capabilities(struct ifnet *ifp) | vlan_trunk_capabilities(struct ifnet *ifp) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | #endif | ||||
default: | default: | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef RATELIMIT | #if defined(KERN_TLS) || defined(RATELIMIT) | ||||
static int | static int | ||||
vlan_snd_tag_alloc(struct ifnet *ifp, | vlan_snd_tag_alloc(struct ifnet *ifp, | ||||
union if_snd_tag_alloc_params *params, | union if_snd_tag_alloc_params *params, | ||||
struct m_snd_tag **ppmt) | struct m_snd_tag **ppmt) | ||||
{ | { | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
struct vlan_snd_tag *vst; | struct vlan_snd_tag *vst; | ||||
struct ifvlan *ifv; | struct ifvlan *ifv; | ||||
▲ Show 20 Lines • Show All 65 Lines • Show Last 20 Lines |