* Ethernet output routine. * Encapsulate a packet of type family for the local net. * Use trailer local net encapsulation if enough data in first * packet leaves a multiple of 512 bytes of data in remainder. */
| 280 | * packet leaves a multiple of 512 bytes of data in remainder. |
| 281 | */ |
| 282 | int |
| 283 | ether_output(struct ifnet *ifp, struct mbuf *m, |
| 284 | const struct sockaddr *dst, struct route *ro) |
| 285 | { |
| 286 | int error = 0; |
| 287 | char linkhdr[ETHER_HDR_LEN], *phdr; |
| 288 | struct ether_header *eh; |
| 289 | struct pf_mtag *t; |
| 290 | bool loop_copy; |
| 291 | int hlen; /* link layer header length */ |
| 292 | uint32_t pflags; |
| 293 | struct llentry *lle = NULL; |
| 294 | int addref = 0; |
| 295 | |
| 296 | phdr = NULL; |
| 297 | pflags = 0; |
| 298 | if (ro != NULL) { |
| 299 | /* XXX BPF uses ro_prepend */ |
| 300 | if (ro->ro_prepend != NULL) { |
| 301 | phdr = ro->ro_prepend; |
| 302 | hlen = ro->ro_plen; |
| 303 | } else if (!(m->m_flags & (M_BCAST | M_MCAST))) { |
| 304 | if ((ro->ro_flags & RT_LLE_CACHE) != 0) { |
| 305 | lle = ro->ro_lle; |
| 306 | if (lle != NULL && |
| 307 | (lle->la_flags & LLE_VALID) == 0) { |
| 308 | LLE_FREE(lle); |
| 309 | lle = NULL; /* redundant */ |
| 310 | ro->ro_lle = NULL; |
| 311 | } |
| 312 | if (lle == NULL) { |
| 313 | /* if we lookup, keep cache */ |
| 314 | addref = 1; |
| 315 | } else |
| 316 | /* |
| 317 | * Notify LLE code that |
| 318 | * the entry was used |
| 319 | * by datapath. |
| 320 | */ |
| 321 | llentry_mark_used(lle); |
| 322 | } |
| 323 | if (lle != NULL) { |
| 324 | phdr = lle->r_linkdata; |
| 325 | hlen = lle->r_hdrlen; |
| 326 | pflags = lle->r_flags; |
| 327 | } |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | #ifdef MAC |
| 332 | error = mac_ifnet_check_transmit(ifp, m); |
| 333 | if (error) |
| 334 | senderr(error); |
| 335 | #endif |
| 336 | |
| 337 | M_PROFILE(m); |
| 338 | if (ifp->if_flags & IFF_MONITOR) |
| 339 | senderr(ENETDOWN); |
nothing calls this directly
no test coverage detected