MFp4 bz_ipv6_fast:
Factor out Hop-By-Hop option processing. It's still not heavily used, it reduces the footprint of ip6_input() and makes ip6_input() more readable. Sponsored by: The FreeBSD Foundation Sponsored by: iXsystems Reviewed by: gnn (as part of the whole) MFC After: 3 days
This commit is contained in:
parent
45747ba53c
commit
ae14505058
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=235962
@ -331,6 +331,83 @@ ip6_init2(void *dummy)
|
||||
/* This must be after route_init(), which is now SI_ORDER_THIRD */
|
||||
SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL);
|
||||
|
||||
static int
|
||||
ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off,
|
||||
int *nxt, int *ours)
|
||||
{
|
||||
struct ip6_hdr *ip6;
|
||||
struct ip6_hbh *hbh;
|
||||
|
||||
if (ip6_hopopts_input(plen, rtalert, &m, off)) {
|
||||
#if 0 /*touches NULL pointer*/
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
|
||||
#endif
|
||||
goto out; /* m have already been freed */
|
||||
}
|
||||
|
||||
/* adjust pointer */
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/*
|
||||
* if the payload length field is 0 and the next header field
|
||||
* indicates Hop-by-Hop Options header, then a Jumbo Payload
|
||||
* option MUST be included.
|
||||
*/
|
||||
if (ip6->ip6_plen == 0 && *plen == 0) {
|
||||
/*
|
||||
* Note that if a valid jumbo payload option is
|
||||
* contained, ip6_hopopts_input() must set a valid
|
||||
* (non-zero) payload length to the variable plen.
|
||||
*/
|
||||
V_ip6stat.ip6s_badoptions++;
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
|
||||
icmp6_error(m, ICMP6_PARAM_PROB,
|
||||
ICMP6_PARAMPROB_HEADER,
|
||||
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
|
||||
goto out;
|
||||
}
|
||||
#ifndef PULLDOWN_TEST
|
||||
/* ip6_hopopts_input() ensures that mbuf is contiguous */
|
||||
hbh = (struct ip6_hbh *)(ip6 + 1);
|
||||
#else
|
||||
IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
|
||||
sizeof(struct ip6_hbh));
|
||||
if (hbh == NULL) {
|
||||
V_ip6stat.ip6s_tooshort++;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
*nxt = hbh->ip6h_nxt;
|
||||
|
||||
/*
|
||||
* If we are acting as a router and the packet contains a
|
||||
* router alert option, see if we know the option value.
|
||||
* Currently, we only support the option value for MLD, in which
|
||||
* case we should pass the packet to the multicast routing
|
||||
* daemon.
|
||||
*/
|
||||
if (*rtalert != ~0) {
|
||||
switch (*rtalert) {
|
||||
case IP6OPT_RTALERT_MLD:
|
||||
if (V_ip6_forwarding)
|
||||
*ours = 1;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* RFC2711 requires unrecognized values must be
|
||||
* silently ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
out:
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ip6_input(struct mbuf *m)
|
||||
{
|
||||
@ -825,71 +902,11 @@ ip6_input(struct mbuf *m)
|
||||
*/
|
||||
plen = (u_int32_t)ntohs(ip6->ip6_plen);
|
||||
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
|
||||
struct ip6_hbh *hbh;
|
||||
int error;
|
||||
|
||||
if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
|
||||
#if 0 /*touches NULL pointer*/
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
|
||||
#endif
|
||||
goto out; /* m have already been freed */
|
||||
}
|
||||
|
||||
/* adjust pointer */
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/*
|
||||
* if the payload length field is 0 and the next header field
|
||||
* indicates Hop-by-Hop Options header, then a Jumbo Payload
|
||||
* option MUST be included.
|
||||
*/
|
||||
if (ip6->ip6_plen == 0 && plen == 0) {
|
||||
/*
|
||||
* Note that if a valid jumbo payload option is
|
||||
* contained, ip6_hopopts_input() must set a valid
|
||||
* (non-zero) payload length to the variable plen.
|
||||
*/
|
||||
V_ip6stat.ip6s_badoptions++;
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
|
||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
|
||||
icmp6_error(m, ICMP6_PARAM_PROB,
|
||||
ICMP6_PARAMPROB_HEADER,
|
||||
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
|
||||
error = ip6_input_hbh(m, &plen, &rtalert, &off, &nxt, &ours);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
}
|
||||
#ifndef PULLDOWN_TEST
|
||||
/* ip6_hopopts_input() ensures that mbuf is contiguous */
|
||||
hbh = (struct ip6_hbh *)(ip6 + 1);
|
||||
#else
|
||||
IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),
|
||||
sizeof(struct ip6_hbh));
|
||||
if (hbh == NULL) {
|
||||
V_ip6stat.ip6s_tooshort++;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
nxt = hbh->ip6h_nxt;
|
||||
|
||||
/*
|
||||
* If we are acting as a router and the packet contains a
|
||||
* router alert option, see if we know the option value.
|
||||
* Currently, we only support the option value for MLD, in which
|
||||
* case we should pass the packet to the multicast routing
|
||||
* daemon.
|
||||
*/
|
||||
if (rtalert != ~0) {
|
||||
switch (rtalert) {
|
||||
case IP6OPT_RTALERT_MLD:
|
||||
if (V_ip6_forwarding)
|
||||
ours = 1;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* RFC2711 requires unrecognized values must be
|
||||
* silently ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
nxt = ip6->ip6_nxt;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user