* Infiniband output routine. */
| 289 | * Infiniband output routine. |
| 290 | */ |
| 291 | static int |
| 292 | infiniband_output(struct ifnet *ifp, struct mbuf *m, |
| 293 | const struct sockaddr *dst, struct route *ro) |
| 294 | { |
| 295 | uint8_t linkhdr[INFINIBAND_HDR_LEN]; |
| 296 | uint8_t *phdr; |
| 297 | struct llentry *lle = NULL; |
| 298 | struct infiniband_header *ih; |
| 299 | int error = 0; |
| 300 | int hlen; /* link layer header length */ |
| 301 | uint32_t pflags; |
| 302 | bool addref; |
| 303 | |
| 304 | NET_EPOCH_ASSERT(); |
| 305 | |
| 306 | addref = false; |
| 307 | phdr = NULL; |
| 308 | pflags = 0; |
| 309 | if (ro != NULL) { |
| 310 | /* XXX BPF uses ro_prepend */ |
| 311 | if (ro->ro_prepend != NULL) { |
| 312 | phdr = ro->ro_prepend; |
| 313 | hlen = ro->ro_plen; |
| 314 | } else if (!(m->m_flags & (M_BCAST | M_MCAST))) { |
| 315 | if ((ro->ro_flags & RT_LLE_CACHE) != 0) { |
| 316 | lle = ro->ro_lle; |
| 317 | if (lle != NULL && |
| 318 | (lle->la_flags & LLE_VALID) == 0) { |
| 319 | LLE_FREE(lle); |
| 320 | lle = NULL; /* redundant */ |
| 321 | ro->ro_lle = NULL; |
| 322 | } |
| 323 | if (lle == NULL) { |
| 324 | /* if we lookup, keep cache */ |
| 325 | addref = 1; |
| 326 | } else |
| 327 | /* |
| 328 | * Notify LLE code that |
| 329 | * the entry was used |
| 330 | * by datapath. |
| 331 | */ |
| 332 | llentry_mark_used(lle); |
| 333 | } |
| 334 | if (lle != NULL) { |
| 335 | phdr = lle->r_linkdata; |
| 336 | hlen = lle->r_hdrlen; |
| 337 | pflags = lle->r_flags; |
| 338 | } |
| 339 | } |
| 340 | } |
| 341 | |
| 342 | #ifdef MAC |
| 343 | error = mac_ifnet_check_transmit(ifp, m); |
| 344 | if (error) |
| 345 | goto bad; |
| 346 | #endif |
| 347 | |
| 348 | M_PROFILE(m); |
nothing calls this directly
no test coverage detected