* The if_transmit method for vlan(4) interface. */
| 1167 | * The if_transmit method for vlan(4) interface. |
| 1168 | */ |
| 1169 | static int |
| 1170 | vlan_transmit(struct ifnet *ifp, struct mbuf *m) |
| 1171 | { |
| 1172 | struct ifvlan *ifv; |
| 1173 | struct ifnet *p; |
| 1174 | int error, len, mcast; |
| 1175 | |
| 1176 | NET_EPOCH_ASSERT(); |
| 1177 | |
| 1178 | ifv = ifp->if_softc; |
| 1179 | if (TRUNK(ifv) == NULL) { |
| 1180 | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
| 1181 | m_freem(m); |
| 1182 | return (ENETDOWN); |
| 1183 | } |
| 1184 | p = PARENT(ifv); |
| 1185 | len = m->m_pkthdr.len; |
| 1186 | mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0; |
| 1187 | |
| 1188 | BPF_MTAP(ifp, m); |
| 1189 | |
| 1190 | #if defined(KERN_TLS) || defined(RATELIMIT) |
| 1191 | if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) { |
| 1192 | struct vlan_snd_tag *vst; |
| 1193 | struct m_snd_tag *mst; |
| 1194 | |
| 1195 | MPASS(m->m_pkthdr.snd_tag->ifp == ifp); |
| 1196 | mst = m->m_pkthdr.snd_tag; |
| 1197 | vst = mst_to_vst(mst); |
| 1198 | if (vst->tag->ifp != p) { |
| 1199 | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
| 1200 | m_freem(m); |
| 1201 | return (EAGAIN); |
| 1202 | } |
| 1203 | |
| 1204 | m->m_pkthdr.snd_tag = m_snd_tag_ref(vst->tag); |
| 1205 | m_snd_tag_rele(mst); |
| 1206 | } |
| 1207 | #endif |
| 1208 | |
| 1209 | /* |
| 1210 | * Do not run parent's if_transmit() if the parent is not up, |
| 1211 | * or parent's driver will cause a system crash. |
| 1212 | */ |
| 1213 | if (!UP_AND_RUNNING(p)) { |
| 1214 | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
| 1215 | m_freem(m); |
| 1216 | return (ENETDOWN); |
| 1217 | } |
| 1218 | |
| 1219 | if (!ether_8021q_frame(&m, ifp, p, &ifv->ifv_qtag)) { |
| 1220 | if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); |
| 1221 | return (0); |
| 1222 | } |
| 1223 | |
| 1224 | /* |
| 1225 | * Send it, precisely as ether_output() would have. |
| 1226 | */ |
nothing calls this directly
no test coverage detected