MCPcopy Create free account
hub / github.com/F-Stack/f-stack / stf_output

Function stf_output

freebsd/net/if_stf.c:407–512  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

405}
406
407static int
408stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
409 struct route *ro)
410{
411 struct stf_softc *sc;
412 const struct sockaddr_in6 *dst6;
413 struct in_addr in4;
414 const void *ptr;
415 u_int8_t tos;
416 struct ip *ip;
417 struct ip6_hdr *ip6;
418 struct in6_addr addr6, mask6;
419 int error;
420
421#ifdef MAC
422 error = mac_ifnet_check_transmit(ifp, m);
423 if (error) {
424 m_freem(m);
425 return (error);
426 }
427#endif
428
429 sc = ifp->if_softc;
430 dst6 = (const struct sockaddr_in6 *)dst;
431
432 /* just in case */
433 if ((ifp->if_flags & IFF_UP) == 0) {
434 m_freem(m);
435 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
436 return ENETDOWN;
437 }
438
439 /*
440 * If we don't have an ip4 address that match my inner ip6 address,
441 * we shouldn't generate output. Without this check, we'll end up
442 * using wrong IPv4 source.
443 */
444 if (stf_getsrcifa6(ifp, &addr6, &mask6) != 0) {
445 m_freem(m);
446 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
447 return ENETDOWN;
448 }
449
450 if (m->m_len < sizeof(*ip6)) {
451 m = m_pullup(m, sizeof(*ip6));
452 if (!m) {
453 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
454 return ENOBUFS;
455 }
456 }
457 ip6 = mtod(m, struct ip6_hdr *);
458 tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
459
460 /*
461 * Pickup the right outer dst addr from the list of candidates.
462 * ip6_dst has priority as it may be able to give us shorter IPv4 hops.
463 */
464 ptr = NULL;

Callers

nothing calls this directly

Calls 10

mac_ifnet_check_transmitFunction · 0.85
if_inc_counterFunction · 0.85
stf_getsrcifa6Function · 0.85
m_pullupFunction · 0.85
bpf_mtap2Function · 0.85
bzeroFunction · 0.85
ip_ecn_ingressFunction · 0.85
ip_outputFunction · 0.85
bpf_peers_presentFunction · 0.70
m_freemFunction · 0.50

Tested by

no test coverage detected