Changeset View
Standalone View
sys/netinet6/frag6.c
Show All 26 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $KAME: frag6.c,v 1.33 2002/01/07 11:34:48 kjc Exp $ | * $KAME: frag6.c,v 1.33 2002/01/07 11:34:48 kjc Exp $ | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "opt_rss.h" | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mbuf.h> | #include <sys/mbuf.h> | ||||
#include <sys/domain.h> | #include <sys/domain.h> | ||||
#include <sys/protosw.h> | #include <sys/protosw.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/errno.h> | #include <sys/errno.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/netisr.h> | |||||
#include <net/route.h> | #include <net/route.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/in_var.h> | #include <netinet/in_var.h> | ||||
#include <netinet/ip6.h> | #include <netinet/ip6.h> | ||||
#include <netinet6/ip6_var.h> | #include <netinet6/ip6_var.h> | ||||
#include <netinet/icmp6.h> | #include <netinet/icmp6.h> | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | frag6_input(struct mbuf **mp, int *offp, int proto) | ||||
struct ip6q *q6; | struct ip6q *q6; | ||||
struct ip6asfrag *af6, *ip6af, *af6dwn; | struct ip6asfrag *af6, *ip6af, *af6dwn; | ||||
struct in6_ifaddr *ia; | struct in6_ifaddr *ia; | ||||
int offset = *offp, nxt, i, next; | int offset = *offp, nxt, i, next; | ||||
int first_frag = 0; | int first_frag = 0; | ||||
int fragoff, frgpartlen; /* must be larger than u_int16_t */ | int fragoff, frgpartlen; /* must be larger than u_int16_t */ | ||||
struct ifnet *dstifp; | struct ifnet *dstifp; | ||||
u_int8_t ecn, ecn0; | u_int8_t ecn, ecn0; | ||||
#ifdef RSS | |||||
struct m_tag *mtag; | |||||
struct ip6_direct_ctx *ip6dc; | |||||
#endif | |||||
#if 0 | #if 0 | ||||
char ip6buf[INET6_ADDRSTRLEN]; | char ip6buf[INET6_ADDRSTRLEN]; | ||||
#endif | #endif | ||||
ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); | ||||
#ifndef PULLDOWN_TEST | #ifndef PULLDOWN_TEST | ||||
IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE); | IP6_EXTHDR_CHECK(m, offset, sizeof(struct ip6_frag), IPPROTO_DONE); | ||||
ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset); | ip6f = (struct ip6_frag *)((caddr_t)ip6 + offset); | ||||
▲ Show 20 Lines • Show All 402 Lines • ▼ Show 20 Lines | #endif | ||||
if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */ | if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */ | ||||
int plen = 0; | int plen = 0; | ||||
for (t = m; t; t = t->m_next) | for (t = m; t; t = t->m_next) | ||||
plen += t->m_len; | plen += t->m_len; | ||||
m->m_pkthdr.len = plen; | m->m_pkthdr.len = plen; | ||||
} | } | ||||
#ifdef RSS | |||||
mtag = m_tag_alloc(MTAG_ABI_IPV6, IPV6_TAG_DIRECT, sizeof(*ip6dc), | |||||
M_NOWAIT); | |||||
if (mtag == NULL) | |||||
btw: I'm wondering whether it is a better choice to replace these error handling codes with a… | |||||
goto dropfrag; | |||||
ip6dc = (struct ip6_direct_ctx *)(mtag + 1); | |||||
Done Inline ActionsYou should just define it as a struct with two uint32_t members. That way (a) it doesn't change size based on different architectures (eg assuming int is a fixed 32 bit size isn't valid!) and (b) it's less error prone to use a struct with named fields. adrian: You should just define it as a struct with two uint32_t members. That way (a) it doesn't change… | |||||
ip6dc->ip6dc_nxt = nxt; | |||||
ip6dc->ip6dc_off = offset; | |||||
m_tag_prepend(m, mtag); | |||||
#endif | |||||
IP6Q_UNLOCK(); | |||||
IP6STAT_INC(ip6s_reassembled); | IP6STAT_INC(ip6s_reassembled); | ||||
in6_ifstat_inc(dstifp, ifs6_reass_ok); | in6_ifstat_inc(dstifp, ifs6_reass_ok); | ||||
#ifdef RSS | |||||
Not Done Inline ActionsHi, This bit is fixing a separate bug, right? Are we able to commit just this bit first as a separate fix? adrian: Hi,
This bit is fixing a separate bug, right? Are we able to commit just this bit first as a… | |||||
Not Done Inline ActionsThat bit is not fixing a separate bug. Previously, after the processing /* * Tell launch routine the next header */ *mp = m; *offp = offset; IP6Q_UNLOCK(); return nxt; And the processing of the next header will be invoked by the following while (nxt != IPPROTO_DONE) { ...... nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); } But now, the processing of the rest headers (headers after the fragment PS. I'm not pretty sure whether it is the best choice to save the protocol Many thanks! ^_^ btw: That bit is not fixing a separate bug. Previously, after the processing
of fragment header, the… | |||||
/* | /* | ||||
* Queue/dispatch for reprocessing. | |||||
*/ | |||||
netisr_dispatch(NETISR_IPV6_DIRECT, m); | |||||
return IPPROTO_DONE; | |||||
#endif | |||||
/* | |||||
* Tell launch routine the next header | * Tell launch routine the next header | ||||
*/ | */ | ||||
*mp = m; | *mp = m; | ||||
*offp = offset; | *offp = offset; | ||||
IP6Q_UNLOCK(); | |||||
return nxt; | return nxt; | ||||
dropfrag: | dropfrag: | ||||
IP6Q_UNLOCK(); | IP6Q_UNLOCK(); | ||||
in6_ifstat_inc(dstifp, ifs6_reass_fail); | in6_ifstat_inc(dstifp, ifs6_reass_fail); | ||||
IP6STAT_INC(ip6s_fragdropped); | IP6STAT_INC(ip6s_fragdropped); | ||||
m_freem(m); | m_freem(m); | ||||
return IPPROTO_DONE; | return IPPROTO_DONE; | ||||
▲ Show 20 Lines • Show All 192 Lines • Show Last 20 Lines |
I'm wondering whether it is a better choice to replace these error handling codes with a KASSERT().