Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/ip6_output.c
Show First 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, | ||||
struct route_in6 *ro, int flags, struct ip6_moptions *im6o, | struct route_in6 *ro, int flags, struct ip6_moptions *im6o, | ||||
struct ifnet **ifpp, struct inpcb *inp) | struct ifnet **ifpp, struct inpcb *inp) | ||||
{ | { | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
struct ifnet *ifp, *origifp; | struct ifnet *ifp, *origifp; | ||||
struct mbuf *m = m0; | struct mbuf *m = m0; | ||||
struct mbuf *mprev = NULL; | struct mbuf *mprev = NULL; | ||||
int hlen, tlen, len; | int hlen, tlen, len; | ||||
struct epoch_tracker et; | |||||
struct route_in6 ip6route; | struct route_in6 ip6route; | ||||
struct rtentry *rt = NULL; | struct rtentry *rt = NULL; | ||||
struct sockaddr_in6 *dst, src_sa, dst_sa; | struct sockaddr_in6 *dst, src_sa, dst_sa; | ||||
struct in6_addr odst; | struct in6_addr odst; | ||||
int error = 0; | int error = 0; | ||||
struct in6_ifaddr *ia = NULL; | struct in6_ifaddr *ia = NULL; | ||||
u_long mtu; | u_long mtu; | ||||
int alwaysfrag, dontfrag; | int alwaysfrag, dontfrag; | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | if (ro == NULL) { | ||||
ro = &ip6route; | ro = &ip6route; | ||||
bzero((caddr_t)ro, sizeof(*ro)); | bzero((caddr_t)ro, sizeof(*ro)); | ||||
} | } | ||||
ro_pmtu = ro; | ro_pmtu = ro; | ||||
if (opt && opt->ip6po_rthdr) | if (opt && opt->ip6po_rthdr) | ||||
ro = &opt->ip6po_route; | ro = &opt->ip6po_route; | ||||
dst = (struct sockaddr_in6 *)&ro->ro_dst; | dst = (struct sockaddr_in6 *)&ro->ro_dst; | ||||
fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m); | fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m); | ||||
NET_EPOCH_ENTER(et); | |||||
again: | again: | ||||
/* | /* | ||||
* if specified, try to fill in the traffic class field. | * if specified, try to fill in the traffic class field. | ||||
* do not override if a non-zero value is already set. | * do not override if a non-zero value is already set. | ||||
* we check the diffserv field and the ecn field separately. | * we check the diffserv field and the ecn field separately. | ||||
*/ | */ | ||||
if (opt && opt->ip6po_tclass >= 0) { | if (opt && opt->ip6po_tclass >= 0) { | ||||
int mask = 0; | int mask = 0; | ||||
▲ Show 20 Lines • Show All 585 Lines • ▼ Show 20 Lines | #endif | ||||
} else | } else | ||||
m_freem(m); | m_freem(m); | ||||
} | } | ||||
if (error == 0) | if (error == 0) | ||||
IP6STAT_INC(ip6s_fragmented); | IP6STAT_INC(ip6s_fragmented); | ||||
done: | done: | ||||
NET_EPOCH_EXIT(et); | |||||
if (ro == &ip6route) | if (ro == &ip6route) | ||||
RO_RTFREE(ro); | RO_RTFREE(ro); | ||||
return (error); | return (error); | ||||
freehdrs: | freehdrs: | ||||
m_freem(exthdrs.ip6e_hbh); /* m_freem will check if mbuf is 0 */ | m_freem(exthdrs.ip6e_hbh); /* m_freem will check if mbuf is 0 */ | ||||
m_freem(exthdrs.ip6e_dest1); | m_freem(exthdrs.ip6e_dest1); | ||||
m_freem(exthdrs.ip6e_rthdr); | m_freem(exthdrs.ip6e_rthdr); | ||||
▲ Show 20 Lines • Show All 2,039 Lines • Show Last 20 Lines |