Changeset View
Standalone View
sys/netinet6/ip6_output.c
Show First 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | |||||
ip6_output_delayed_csum(struct mbuf *m, struct ifnet *ifp, int csum_flags, | ip6_output_delayed_csum(struct mbuf *m, struct ifnet *ifp, int csum_flags, | ||||
int plen, int optlen, bool frag) | int plen, int optlen, bool frag) | ||||
{ | { | ||||
KASSERT((plen >= optlen), ("%s:%d: plen %d < optlen %d, m %p, ifp %p " | KASSERT((plen >= optlen), ("%s:%d: plen %d < optlen %d, m %p, ifp %p " | ||||
"csum_flags %#x frag %d\n", | "csum_flags %#x frag %d\n", | ||||
__func__, __LINE__, plen, optlen, m, ifp, csum_flags, frag)); | __func__, __LINE__, plen, optlen, m, ifp, csum_flags, frag)); | ||||
if ((csum_flags & CSUM_DELAY_DATA_IPV6) || | if ((csum_flags & (CSUM_SCTP_IPV6 | CSUM_DELAY_DATA_IPV6)) != 0) { | ||||
#if defined(SCTP) || defined(SCTP_SUPPORT) | |||||
(csum_flags & CSUM_SCTP_IPV6) || | |||||
#endif | |||||
(!frag && (ifp->if_capenable & IFCAP_MEXTPG) == 0)) { | |||||
m = mb_unmapped_to_ext(m); | |||||
if (m == NULL) { | |||||
if (frag) | |||||
in6_ifstat_inc(ifp, ifs6_out_fragfail); | |||||
else | |||||
IP6STAT_INC(ip6s_odropped); | |||||
return (ENOBUFS); | |||||
} | |||||
if (csum_flags & CSUM_DELAY_DATA_IPV6) { | if (csum_flags & CSUM_DELAY_DATA_IPV6) { | ||||
in6_delayed_cksum(m, plen - optlen, | in6_delayed_cksum(m, plen - optlen, | ||||
sizeof(struct ip6_hdr) + optlen); | sizeof(struct ip6_hdr) + optlen); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; | m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; | ||||
} | } | ||||
#if defined(SCTP) || defined(SCTP_SUPPORT) | #if defined(SCTP) || defined(SCTP_SUPPORT) | ||||
if (csum_flags & CSUM_SCTP_IPV6) { | if (csum_flags & CSUM_SCTP_IPV6) { | ||||
sctp_delayed_cksum(m, sizeof(struct ip6_hdr) + optlen); | sctp_delayed_cksum(m, sizeof(struct ip6_hdr) + optlen); | ||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; | m->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; | ||||
} | } | ||||
#endif | #endif | ||||
} | |||||
if (!frag && (ifp->if_capenable & IFCAP_MEXTPG) == 0) { | |||||
m = mb_unmapped_to_ext(m); | |||||
if (m == NULL) { | |||||
if (frag) | |||||
in6_ifstat_inc(ifp, ifs6_out_fragfail); | |||||
markj: Oops, this is dead code since we have `!frag` here. I'm not sure why there's a special case for… | |||||
jhbUnsubmitted Done Inline ActionsHmmm, the boolean is a bit odd here and should probably be called "is_frag" as it is true when transmitting a fragment and false when sending an unfragmented packet. I think the intention was that we would always end up doing this check and converting the entire packet chain to unmapped if the interface didn't support the flag in the first call when frag is false and that in the frag == true case it should be redundant. Put another way, it should be possible to assert in the frag == true case that the mbuf is already mapped. This does mean that in the case of a fragmented packet I think we calculate the full checksums if needed and then throw that work away and recalc checksums on each fragment. You could probably just remove the frag check and only check for IFCAP_MEXTPG and it would be ok. I'm not sure if it is worth trying to preserve this optimization for fragments. Alternatively, you could hoist this check back out of this function and into the ip6_output itself perhaps just after the 'passout' label in ip6_output. I think I prefer that as it makes the code more obvious. It was here only to try to put all the logic in one place for calling mb_unmapped_to_ext and IFCAP_MEXTPG doesn't really have anything to do with checksums otherwise. jhb: Hmmm, the boolean is a bit odd here and should probably be called "is_frag" as it is true when… | |||||
markjAuthorUnsubmitted Done Inline ActionsYou last suggestion results in some nice simplification, so I'll go with that. markj: You last suggestion results in some nice simplification, so I'll go with that. | |||||
else | |||||
IP6STAT_INC(ip6s_odropped); | |||||
return (ENOBUFS); | |||||
} | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, | ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, | ||||
int fraglen , uint32_t id) | int fraglen , uint32_t id) | ||||
▲ Show 20 Lines • Show All 3,131 Lines • Show Last 20 Lines |
Oops, this is dead code since we have !frag here. I'm not sure why there's a special case for fragments here.