Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_ethersubr.c
Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#ifdef CTASSERT | #ifdef CTASSERT | ||||
CTASSERT(sizeof (struct ether_header) == ETHER_ADDR_LEN * 2 + 2); | CTASSERT(sizeof (struct ether_header) == ETHER_ADDR_LEN * 2 + 2); | ||||
CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN); | CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN); | ||||
#endif | #endif | ||||
VNET_DEFINE(struct pfil_head, link_pfil_hook); /* Packet filter hooks */ | VNET_DEFINE(pfil_head_t, link_pfil_head); /* Packet filter hooks */ | ||||
/* netgraph node hooks for ng_ether(4) */ | /* netgraph node hooks for ng_ether(4) */ | ||||
void (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp); | void (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp); | ||||
void (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m); | void (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m); | ||||
int (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp); | int (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp); | ||||
void (*ng_ether_attach_p)(struct ifnet *ifp); | void (*ng_ether_attach_p)(struct ifnet *ifp); | ||||
void (*ng_ether_detach_p)(struct ifnet *ifp); | void (*ng_ether_detach_p)(struct ifnet *ifp); | ||||
▲ Show 20 Lines • Show All 350 Lines • ▼ Show 20 Lines | |||||
* Ethernet link layer output routine to send a raw frame to the device. | * Ethernet link layer output routine to send a raw frame to the device. | ||||
* | * | ||||
* This assumes that the 14 byte Ethernet header is present and contiguous | * This assumes that the 14 byte Ethernet header is present and contiguous | ||||
* in the first mbuf (if BRIDGE'ing). | * in the first mbuf (if BRIDGE'ing). | ||||
*/ | */ | ||||
int | int | ||||
ether_output_frame(struct ifnet *ifp, struct mbuf *m) | ether_output_frame(struct ifnet *ifp, struct mbuf *m) | ||||
{ | { | ||||
int error; | |||||
uint8_t pcp; | uint8_t pcp; | ||||
pcp = ifp->if_pcp; | pcp = ifp->if_pcp; | ||||
if (pcp != IFNET_PCP_NONE && ifp->if_type != IFT_L2VLAN && | if (pcp != IFNET_PCP_NONE && ifp->if_type != IFT_L2VLAN && | ||||
!ether_set_pcp(&m, ifp, pcp)) | !ether_set_pcp(&m, ifp, pcp)) | ||||
return (0); | return (0); | ||||
if (PFIL_HOOKED(&V_link_pfil_hook)) { | if (PFIL_HOOKED_OUT(V_link_pfil_head)) | ||||
error = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, | switch (pfil_run_hooks(V_link_pfil_head, &m, ifp, PFIL_OUT, | ||||
PFIL_OUT, 0, NULL); | NULL)) { | ||||
if (error != 0) | case PFIL_DROPPED: | ||||
return (EACCES); | return (EACCES); | ||||
case PFIL_CONSUMED: | |||||
if (m == NULL) | |||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef EXPERIMENTAL | #ifdef EXPERIMENTAL | ||||
#if defined(INET6) && defined(INET) | #if defined(INET6) && defined(INET) | ||||
/* draft-ietf-6man-ipv6only-flag */ | /* draft-ietf-6man-ipv6only-flag */ | ||||
/* Catch ETHERTYPE_IP, and ETHERTYPE_ARP if we are v6-only. */ | /* Catch ETHERTYPE_IP, and ETHERTYPE_ARP if we are v6-only. */ | ||||
if ((ND_IFINFO(ifp)->flags & ND6_IFF_IPV6_ONLY) != 0) { | if ((ND_IFINFO(ifp)->flags & ND6_IFF_IPV6_ONLY) != 0) { | ||||
struct ether_header *eh; | struct ether_header *eh; | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | ether_init(__unused void *arg) | ||||
netisr_register(ðer_nh); | netisr_register(ðer_nh); | ||||
} | } | ||||
SYSINIT(ether, SI_SUB_INIT_IF, SI_ORDER_ANY, ether_init, NULL); | SYSINIT(ether, SI_SUB_INIT_IF, SI_ORDER_ANY, ether_init, NULL); | ||||
static void | static void | ||||
vnet_ether_init(__unused void *arg) | vnet_ether_init(__unused void *arg) | ||||
{ | { | ||||
int i; | struct pfil_head_args args; | ||||
/* Initialize packet filter hooks. */ | args.pa_version = PFIL_VERSION; | ||||
V_link_pfil_hook.ph_type = PFIL_TYPE_AF; | args.pa_flags = PFIL_IN | PFIL_OUT; | ||||
V_link_pfil_hook.ph_af = AF_LINK; | args.pa_type = PFIL_TYPE_ETHERNET; | ||||
if ((i = pfil_head_register(&V_link_pfil_hook)) != 0) | args.pa_headname = PFIL_ETHER_NAME; | ||||
printf("%s: WARNING: unable to register pfil link hook, " | V_link_pfil_head = pfil_head_register(&args); | ||||
"error %d\n", __func__, i); | |||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
netisr_register_vnet(ðer_nh); | netisr_register_vnet(ðer_nh); | ||||
#endif | #endif | ||||
} | } | ||||
VNET_SYSINIT(vnet_ether_init, SI_SUB_PROTO_IF, SI_ORDER_ANY, | VNET_SYSINIT(vnet_ether_init, SI_SUB_PROTO_IF, SI_ORDER_ANY, | ||||
vnet_ether_init, NULL); | vnet_ether_init, NULL); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
static void | static void | ||||
vnet_ether_pfil_destroy(__unused void *arg) | vnet_ether_pfil_destroy(__unused void *arg) | ||||
{ | { | ||||
int i; | |||||
if ((i = pfil_head_unregister(&V_link_pfil_hook)) != 0) | pfil_head_unregister(V_link_pfil_head); | ||||
printf("%s: WARNING: unable to unregister pfil link hook, " | |||||
"error %d\n", __func__, i); | |||||
} | } | ||||
VNET_SYSUNINIT(vnet_ether_pfil_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_ANY, | VNET_SYSUNINIT(vnet_ether_pfil_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_ANY, | ||||
vnet_ether_pfil_destroy, NULL); | vnet_ether_pfil_destroy, NULL); | ||||
static void | static void | ||||
vnet_ether_destroy(__unused void *arg) | vnet_ether_destroy(__unused void *arg) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct ether_header *eh; | struct ether_header *eh; | ||||
int i, isr; | int i, isr; | ||||
u_short ether_type; | u_short ether_type; | ||||
KASSERT(ifp != NULL, ("%s: NULL interface pointer", __func__)); | KASSERT(ifp != NULL, ("%s: NULL interface pointer", __func__)); | ||||
/* Do not grab PROMISC frames in case we are re-entered. */ | /* Do not grab PROMISC frames in case we are re-entered. */ | ||||
if (PFIL_HOOKED(&V_link_pfil_hook) && !(m->m_flags & M_PROMISC)) { | if (PFIL_HOOKED_IN(V_link_pfil_head) && !(m->m_flags & M_PROMISC)) { | ||||
i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_IN, 0, | i = pfil_run_hooks(V_link_pfil_head, &m, ifp, PFIL_IN, NULL); | ||||
NULL); | |||||
if (i != 0 || m == NULL) | if (i != 0 || m == NULL) | ||||
return; | return; | ||||
} | } | ||||
eh = mtod(m, struct ether_header *); | eh = mtod(m, struct ether_header *); | ||||
ether_type = ntohs(eh->ether_type); | ether_type = ntohs(eh->ether_type); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 560 Lines • Show Last 20 Lines |