OAL_STATIC oal_bool_enum_uint8 dmac_11w_check_multicast_mgmt(oal_netbuf_stru *pst_mgmt_buf) { oal_uint8 *puc_da; mac_ieee80211_frame_stru *pst_frame_hdr; pst_frame_hdr = (mac_ieee80211_frame_stru *)OAL_NETBUF_HEADER(pst_mgmt_buf); puc_da = pst_frame_hdr->auc_address1; if (OAL_TRUE != ETHER_IS_MULTICAST(puc_da)) { return OAL_FALSE; } return dmac_11w_robust_frame(pst_mgmt_buf); }
oal_void dmac_11w_set_protectframe(dmac_vap_stru *pst_dmac_vap, wlan_security_txop_params_stru *pst_security, oal_netbuf_stru *pst_netbuf) { oal_bool_enum_uint8 en_MFPC = OAL_FALSE; oal_bool_enum_uint8 en_pmf_active = OAL_FALSE; oal_uint8 auc_addr1[6] = {0}; dmac_user_stru *pst_dmac_user = OAL_PTR_NULL; oal_uint16 us_user_idx; oal_uint8 *puc_frame_hdr = oal_netbuf_header(pst_netbuf); mac_get_address1(puc_frame_hdr, auc_addr1); /* 查找用户:auth帧情况下不会有用户,找不到用户属于正常情况 */ if (OAL_SUCC != mac_vap_find_user_by_macaddr(&pst_dmac_vap->st_vap_base_info, auc_addr1, &us_user_idx)) { return; } pst_dmac_user = (dmac_user_stru *)mac_res_get_dmac_user(us_user_idx); if (OAL_PTR_NULL == pst_dmac_user) { return; } /* 能力检查 */ en_MFPC = mac_mib_get_dot11RSNAMFPC(&(pst_dmac_vap->st_vap_base_info)); en_pmf_active = pst_dmac_user->st_user_base_info.st_cap_info.bit_pmf_active; if ((OAL_FALSE == en_MFPC) || (OAL_FALSE == en_pmf_active) || (OAL_TRUE == ETHER_IS_MULTICAST(auc_addr1))) { return; } if (OAL_TRUE == dmac_11w_robust_frame(pst_netbuf)) { mac_set_protectedframe(puc_frame_hdr); pst_security->en_cipher_key_type = pst_dmac_user->st_user_base_info.st_user_tx_info.st_security.en_cipher_key_type; pst_security->en_cipher_protocol_type = pst_dmac_user->st_user_base_info.st_user_tx_info.st_security.en_cipher_protocol_type; return; } }
static int pci_vtnet_parsemac(char *mac_str, uint8_t *mac_addr) { struct ether_addr *ea; char *tmpstr; char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; tmpstr = strsep(&mac_str,"="); if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { ea = ether_aton(mac_str); if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { fprintf(stderr, "Invalid MAC %s\n", mac_str); return (EINVAL); } else memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); } return (0); }
/* * Process a received Ethernet packet; the packet is in the * mbuf chain m with the ethernet header at the front. */ static void ether_input_internal(struct ifnet *ifp, struct mbuf *m) { struct ether_header *eh; u_short etype; if ((ifp->if_flags & IFF_UP) == 0) { m_freem(m); return; } #ifdef DIAGNOSTIC if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { if_printf(ifp, "discard frame at !IFF_DRV_RUNNING\n"); m_freem(m); return; } #endif /* * 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"); ifp->if_ierrors++; m_freem(m); return; } if (m->m_len < ETHER_HDR_LEN) { /* XXX maybe should pullup? */ if_printf(ifp, "discard frame w/o leading ethernet " "header (len %u pkt len %u)\n", m->m_len, m->m_pkthdr.len); ifp->if_ierrors++; m_freem(m); return; } eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); if (m->m_pkthdr.rcvif == NULL) { if_printf(ifp, "discard frame w/o interface pointer\n"); ifp->if_ierrors++; m_freem(m); return; } #ifdef DIAGNOSTIC if (m->m_pkthdr.rcvif != ifp) { if_printf(ifp, "Warning, frame marked as received on %s\n", m->m_pkthdr.rcvif->if_xname); } #endif CURVNET_SET_QUIET(ifp->if_vnet); if (ETHER_IS_MULTICAST(eh->ether_dhost)) { if (ETHER_IS_BROADCAST(eh->ether_dhost)) m->m_flags |= M_BCAST; else m->m_flags |= M_MCAST; ifp->if_imcasts++; } #ifdef MAC /* * Tag the mbuf with an appropriate MAC label before any other * consumers can get to it. */ mac_ifnet_create_mbuf(ifp, m); #endif /* * Give bpf a chance at the packet. */ ETHER_BPF_MTAP(ifp, m); /* * If the CRC is still on the packet, trim it off. We do this once * and once only in case we are re-entered. Nothing else on the * Ethernet receive path expects to see the FCS. */ if (m->m_flags & M_HASFCS) { m_adj(m, -ETHER_CRC_LEN); m->m_flags &= ~M_HASFCS; } if (!(ifp->if_capenable & IFCAP_HWSTATS)) ifp->if_ibytes += m->m_pkthdr.len; /* Allow monitor mode to claim this frame, after stats are updated. */ if (ifp->if_flags & IFF_MONITOR) { m_freem(m); CURVNET_RESTORE(); return; } /* Handle input from a lagg(4) port */ if (ifp->if_type == IFT_IEEE8023ADLAG) { KASSERT(lagg_input_p != NULL, ("%s: if_lagg not loaded!", __func__)); m = (*lagg_input_p)(ifp, m); if (m != NULL) ifp = m->m_pkthdr.rcvif; else { CURVNET_RESTORE(); return; } } /* * If the hardware did not process an 802.1Q tag, do this now, * to allow 802.1P priority frames to be passed to the main input * path correctly. * TODO: Deal with Q-in-Q frames, but not arbitrary nesting levels. */ if ((m->m_flags & M_VLANTAG) == 0 && etype == ETHERTYPE_VLAN) { struct ether_vlan_header *evl; if (m->m_len < sizeof(*evl) && (m = m_pullup(m, sizeof(*evl))) == NULL) { #ifdef DIAGNOSTIC if_printf(ifp, "cannot pullup VLAN header\n"); #endif ifp->if_ierrors++; m_freem(m); CURVNET_RESTORE(); return; } evl = mtod(m, struct ether_vlan_header *); m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag); m->m_flags |= M_VLANTAG; bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN, ETHER_HDR_LEN - ETHER_TYPE_LEN); m_adj(m, ETHER_VLAN_ENCAP_LEN); eh = mtod(m, struct ether_header *); } M_SETFIB(m, ifp->if_fib); /* Allow ng_ether(4) to claim this frame. */ if (IFP2AC(ifp)->ac_netgraph != NULL) { KASSERT(ng_ether_input_p != NULL, ("%s: ng_ether_input_p is NULL", __func__)); m->m_flags &= ~M_PROMISC; (*ng_ether_input_p)(ifp, &m); if (m == NULL) { CURVNET_RESTORE(); return; } eh = mtod(m, struct ether_header *); }
static void shmif_rcv(void *arg) { struct ifnet *ifp = arg; struct shmif_sc *sc = ifp->if_softc; struct shmif_mem *busmem; struct mbuf *m = NULL; struct ether_header *eth; uint32_t nextpkt; bool wrap, passup; int error; const int align = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); reup: mutex_enter(&sc->sc_mtx); while ((ifp->if_flags & IFF_RUNNING) == 0 && !sc->sc_dying) cv_wait(&sc->sc_cv, &sc->sc_mtx); mutex_exit(&sc->sc_mtx); busmem = sc->sc_busmem; while (ifp->if_flags & IFF_RUNNING) { struct shmif_pkthdr sp; if (m == NULL) { m = m_gethdr(M_WAIT, MT_DATA); MCLGET(m, M_WAIT); m->m_data += align; } DPRINTF(("waiting %d/%" PRIu64 "\n", sc->sc_nextpacket, sc->sc_devgen)); KASSERT(m->m_flags & M_EXT); shmif_lockbus(busmem); KASSERT(busmem->shm_magic == SHMIF_MAGIC); KASSERT(busmem->shm_gen >= sc->sc_devgen); /* need more data? */ if (sc->sc_devgen == busmem->shm_gen && shmif_nextpktoff(busmem, busmem->shm_last) == sc->sc_nextpacket) { shmif_unlockbus(busmem); error = 0; rumpcomp_shmif_watchwait(sc->sc_kq); if (__predict_false(error)) printf("shmif_rcv: wait failed %d\n", error); membar_consumer(); continue; } if (stillvalid_p(sc)) { nextpkt = sc->sc_nextpacket; } else { KASSERT(busmem->shm_gen > 0); nextpkt = busmem->shm_first; if (busmem->shm_first > busmem->shm_last) sc->sc_devgen = busmem->shm_gen - 1; else sc->sc_devgen = busmem->shm_gen; DPRINTF(("dev %p overrun, new data: %d/%" PRIu64 "\n", sc, nextpkt, sc->sc_devgen)); } /* * If our read pointer is ahead the bus last write, our * generation must be one behind. */ KASSERT(!(nextpkt > busmem->shm_last && sc->sc_devgen == busmem->shm_gen)); wrap = false; nextpkt = shmif_busread(busmem, &sp, nextpkt, sizeof(sp), &wrap); KASSERT(sp.sp_len <= ETHERMTU + ETHER_HDR_LEN); nextpkt = shmif_busread(busmem, mtod(m, void *), nextpkt, sp.sp_len, &wrap); DPRINTF(("shmif_rcv: read packet of length %d at %d\n", sp.sp_len, nextpkt)); sc->sc_nextpacket = nextpkt; shmif_unlockbus(sc->sc_busmem); if (wrap) { sc->sc_devgen++; DPRINTF(("dev %p generation now %" PRIu64 "\n", sc, sc->sc_devgen)); } /* * Ignore packets too short to possibly be valid. * This is hit at least for the first frame on a new bus. */ if (__predict_false(sp.sp_len < ETHER_HDR_LEN)) { DPRINTF(("shmif read packet len %d < ETHER_HDR_LEN\n", sp.sp_len)); continue; } m->m_len = m->m_pkthdr.len = sp.sp_len; m->m_pkthdr.rcvif = ifp; /* * Test if we want to pass the packet upwards */ eth = mtod(m, struct ether_header *); if (memcmp(eth->ether_dhost, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN) == 0) { passup = true; } else if (ETHER_IS_MULTICAST(eth->ether_dhost)) { passup = true; } else if (ifp->if_flags & IFF_PROMISC) { m->m_flags |= M_PROMISC; passup = true; } else { passup = false; } if (passup) { KERNEL_LOCK(1, NULL); bpf_mtap(ifp, m); ifp->if_input(ifp, m); KERNEL_UNLOCK_ONE(NULL); m = NULL; } /* else: reuse mbuf for a future packet */ } m_freem(m); m = NULL; if (!sc->sc_dying) goto reup; kthread_exit(0); }
oal_uint32 dmac_11w_rx_filter(dmac_vap_stru *pst_dmac_vap, oal_netbuf_stru *pst_netbuf) { oal_uint32 ul_relt = OAL_SUCC; oal_uint8 *puc_da; dmac_rx_ctl_stru *pst_rx_ctl; mac_ieee80211_frame_stru *pst_frame_hdr; mac_user_stru *pst_user; oal_uint16 us_ta_user_idx; wlan_ciper_protocol_type_enum_uint8 en_cipher_protocol_type; pst_frame_hdr = (mac_ieee80211_frame_stru *)OAL_NETBUF_HEADER(pst_netbuf); puc_da = pst_frame_hdr->auc_address1; pst_rx_ctl = (dmac_rx_ctl_stru *)oal_netbuf_cb(pst_netbuf); en_cipher_protocol_type = hal_ctype_to_cipher_suite(pst_rx_ctl->st_rx_status.bit_cipher_protocol_type); #if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC == _PRE_MULTI_CORE_MODE) us_ta_user_idx = pst_rx_ctl->st_rx_info.bit_ta_user_idx; #else us_ta_user_idx = pst_rx_ctl->st_rx_info.us_ta_user_idx; #endif pst_user = (mac_user_stru *)mac_res_get_dmac_user(us_ta_user_idx); if (OAL_PTR_NULL == pst_user) { return OAL_SUCC; } if ((OAL_TRUE != pst_user->st_cap_info.bit_pmf_active) || (OAL_TRUE != dmac_11w_robust_frame(pst_netbuf) )) { return OAL_SUCC; } /* 广播Robust帧过滤 */ if (OAL_TRUE == ETHER_IS_MULTICAST(puc_da)) { ul_relt = OAL_SUCC; #if(_PRE_WLAN_FEATURE_PMF == _PRE_PMF_HW_CCMP_BIP) if (WLAN_80211_CIPHER_SUITE_BIP != en_cipher_protocol_type) { OAM_WARNING_LOG1(pst_dmac_vap->st_vap_base_info.uc_vap_id, OAM_SF_PMF, "{dmac_11w_rx_filter::PMF is open,but is Robust muti frame chipertype is[%d].}", en_cipher_protocol_type); return OAL_ERR_CODE_PMF_NO_PROTECTED_ERROR; } #else /* 11w组播管理帧解密 */ ul_relt = dmac_bip_decrypto(pst_dmac_vap, pst_netbuf); if (OAL_SUCC != ul_relt) { /* 组播解密失败,不上报管理帧 */ OAM_WARNING_LOG1(pst_dmac_vap->st_vap_base_info.uc_vap_id, OAM_SF_PMF, "{dmac_11w_rx_filter::dmac_bip_decrypto failed[%d].}", ul_relt); } #endif return ul_relt; } /* pmf使能,对硬件不能过滤的未加密帧进行过滤 */ if (WLAN_80211_CIPHER_SUITE_NO_ENCRYP == en_cipher_protocol_type) { OAM_WARNING_LOG0(pst_dmac_vap->st_vap_base_info.uc_vap_id, OAM_SF_PMF, "{dmac_11w_rx_filter::PMF is open,but the Robust frame is CIPHER_SUITE_NO_ENCRYP.}"); return OAL_ERR_CODE_PMF_NO_PROTECTED_ERROR; } /* PMF单播管理帧校验 */ if ((OAL_FALSE == pst_frame_hdr->st_frame_control.bit_protected_frame)|| (WLAN_80211_CIPHER_SUITE_CCMP != en_cipher_protocol_type)) { OAM_WARNING_LOG2(pst_dmac_vap->st_vap_base_info.uc_vap_id, OAM_SF_PMF, "{dmac_11w_rx_filter::robust_action protecter incorect. bit_protected_frame[%d], cipher_type[%d].}", pst_frame_hdr->st_frame_control.bit_protected_frame, en_cipher_protocol_type); return OAL_ERR_CODE_PMF_NO_PROTECTED_ERROR; } return OAL_SUCC; }