Page MenuHomeFreeBSD

D19960.diff
No OneTemporary

D19960.diff

Index: sys/netinet6/ip6_input.c
===================================================================
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -420,16 +420,11 @@
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 the payload length field is 0 and the next header field indicates
+ * Hop-by-Hop Options header, then this must be a jumbo payload. We do
+ * not support jumbo payloads, report an error to the sender.
*/
- 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.
- */
+ if (ip6->ip6_plen == 0) {
IP6STAT_INC(ip6s_badoptions);
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
@@ -850,7 +845,6 @@
/*
* Process Hop-by-Hop options header if it's contained.
* m may be modified in ip6_hopopts_input().
- * If a JumboPayload option is included, plen will also be modified.
*/
plen = (u_int32_t)ntohs(ip6->ip6_plen);
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
@@ -968,8 +962,8 @@
}
/*
- * Hop-by-Hop options header processing. If a valid jumbo payload option is
- * included, the real payload length will be stored in plenp.
+ * Hop-by-Hop options header processing. If a jumbo payload option is present
+ * report an error.
*
* rtalertp - XXX: should be stored more smart way
*/
@@ -1007,7 +1001,7 @@
off += hbhlen;
hbhlen -= sizeof(struct ip6_hbh);
if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
- hbhlen, rtalertp, plenp) < 0)
+ hbhlen, rtalertp) < 0)
return (-1);
*offp = off;
@@ -1027,13 +1021,11 @@
*/
int
ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
- u_int32_t *rtalertp, u_int32_t *plenp)
+ u_int32_t *rtalertp)
{
- struct ip6_hdr *ip6;
int optlen = 0;
u_int8_t *opt = opthead;
u_int16_t rtalert_val;
- u_int32_t jumboplen;
const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
@@ -1066,71 +1058,8 @@
*rtalertp = ntohs(rtalert_val);
break;
case IP6OPT_JUMBO:
- /* XXX may need check for alignment */
- if (hbhlen < IP6OPT_JUMBO_LEN) {
- IP6STAT_INC(ip6s_toosmall);
- goto bad;
- }
- if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) {
- /* XXX stat */
- icmp6_error(m, ICMP6_PARAM_PROB,
- ICMP6_PARAMPROB_HEADER,
- erroff + opt + 1 - opthead);
- return (-1);
- }
- optlen = IP6OPT_JUMBO_LEN;
-
- /*
- * IPv6 packets that have non 0 payload length
- * must not contain a jumbo payload option.
- */
- ip6 = mtod(m, struct ip6_hdr *);
- if (ip6->ip6_plen) {
- IP6STAT_INC(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB,
- ICMP6_PARAMPROB_HEADER,
- erroff + opt - opthead);
- return (-1);
- }
-
- /*
- * We may see jumbolen in unaligned location, so
- * we'd need to perform bcopy().
- */
- bcopy(opt + 2, &jumboplen, sizeof(jumboplen));
- jumboplen = (u_int32_t)htonl(jumboplen);
-
-#if 1
- /*
- * if there are multiple jumbo payload options,
- * *plenp will be non-zero and the packet will be
- * rejected.
- * the behavior may need some debate in ipngwg -
- * multiple options does not make sense, however,
- * there's no explicit mention in specification.
- */
- if (*plenp != 0) {
- IP6STAT_INC(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB,
- ICMP6_PARAMPROB_HEADER,
- erroff + opt + 2 - opthead);
- return (-1);
- }
-#endif
-
- /*
- * jumbo payload length must be larger than 65535.
- */
- if (jumboplen <= IPV6_MAXPACKET) {
- IP6STAT_INC(ip6s_badoptions);
- icmp6_error(m, ICMP6_PARAM_PROB,
- ICMP6_PARAMPROB_HEADER,
- erroff + opt + 2 - opthead);
- return (-1);
- }
- *plenp = jumboplen;
-
- break;
+ /* We do not support the jumbo payload option */
+ goto bad;
default: /* unknown option */
if (hbhlen < IP6OPT_MINLEN) {
IP6STAT_INC(ip6s_toosmall);
@@ -1453,7 +1382,6 @@
return;
}
#endif
-
/*
* XXX: We copy the whole header even if a
* jumbo payload option is included, the option which
Index: sys/netinet6/ip6_output.c
===================================================================
--- sys/netinet6/ip6_output.c
+++ sys/netinet6/ip6_output.c
@@ -142,7 +142,6 @@
static int ip6_copyexthdr(struct mbuf **, caddr_t, int);
static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
struct ip6_frag **);
-static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
static int ip6_getpmtu(struct route_in6 *, int,
struct ifnet *, const struct in6_addr *, u_long *, int *, u_int,
@@ -399,21 +398,9 @@
m->m_pkthdr.len += optlen;
plen = m->m_pkthdr.len - sizeof(*ip6);
- /* If this is a jumbo payload, insert a jumbo payload option. */
if (plen > IPV6_MAXPACKET) {
- if (!hdrsplit) {
- if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
- m = NULL;
- goto freehdrs;
- }
- m = exthdrs.ip6e_ip6;
- hdrsplit++;
- }
- /* adjust pointer */
- ip6 = mtod(m, struct ip6_hdr *);
- if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
- goto freehdrs;
- ip6->ip6_plen = 0;
+ error = EMSGSIZE;
+ goto freehdrs;
} else
ip6->ip6_plen = htons(plen);
@@ -766,7 +753,6 @@
if (exthdrs.ip6e_hbh) {
struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
u_int32_t dummy; /* XXX unused */
- u_int32_t plen = 0; /* XXX: ip6_process will check the value */
#ifdef DIAGNOSTIC
if ((hbh->ip6h_len + 1) << 3 > exthdrs.ip6e_hbh->m_len)
@@ -782,7 +768,7 @@
m->m_pkthdr.rcvif = ifp;
if (ip6_process_hopopts(m, (u_int8_t *)(hbh + 1),
((hbh->ip6h_len + 1) << 3) - sizeof(struct ip6_hbh),
- &dummy, &plen) < 0) {
+ &dummy) < 0) {
/* m was already freed at this point */
error = EINVAL;/* better error? */
goto done;
@@ -983,7 +969,7 @@
in6_ifstat_inc(ifp, ifs6_out_fragfail);
goto bad;
} else if (ip6->ip6_plen == 0) {
- /* jumbo payload cannot be fragmented */
+ /* we don't support jumbo payload return error */
error = EMSGSIZE;
in6_ifstat_inc(ifp, ifs6_out_fragfail);
goto bad;
@@ -1132,94 +1118,6 @@
return (0);
}
-/*
- * Insert jumbo payload option.
- */
-static int
-ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen)
-{
- struct mbuf *mopt;
- u_char *optbuf;
- u_int32_t v;
-
-#define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
-
- /*
- * If there is no hop-by-hop options header, allocate new one.
- * If there is one but it doesn't have enough space to store the
- * jumbo payload option, allocate a cluster to store the whole options.
- * Otherwise, use it to store the options.
- */
- if (exthdrs->ip6e_hbh == NULL) {
- mopt = m_get(M_NOWAIT, MT_DATA);
- if (mopt == NULL)
- return (ENOBUFS);
- mopt->m_len = JUMBOOPTLEN;
- optbuf = mtod(mopt, u_char *);
- optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */
- exthdrs->ip6e_hbh = mopt;
- } else {
- struct ip6_hbh *hbh;
-
- mopt = exthdrs->ip6e_hbh;
- if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
- /*
- * XXX assumption:
- * - exthdrs->ip6e_hbh is not referenced from places
- * other than exthdrs.
- * - exthdrs->ip6e_hbh is not an mbuf chain.
- */
- int oldoptlen = mopt->m_len;
- struct mbuf *n;
-
- /*
- * XXX: give up if the whole (new) hbh header does
- * not fit even in an mbuf cluster.
- */
- if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
- return (ENOBUFS);
-
- /*
- * As a consequence, we must always prepare a cluster
- * at this point.
- */
- n = m_getcl(M_NOWAIT, MT_DATA, 0);
- if (n == NULL)
- return (ENOBUFS);
- n->m_len = oldoptlen + JUMBOOPTLEN;
- bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
- oldoptlen);
- optbuf = mtod(n, caddr_t) + oldoptlen;
- m_freem(mopt);
- mopt = exthdrs->ip6e_hbh = n;
- } else {
- optbuf = mtod(mopt, u_char *) + mopt->m_len;
- mopt->m_len += JUMBOOPTLEN;
- }
- optbuf[0] = IP6OPT_PADN;
- optbuf[1] = 1;
-
- /*
- * Adjust the header length according to the pad and
- * the jumbo payload option.
- */
- hbh = mtod(mopt, struct ip6_hbh *);
- hbh->ip6h_len += (JUMBOOPTLEN >> 3);
- }
-
- /* fill in the option. */
- optbuf[2] = IP6OPT_JUMBO;
- optbuf[3] = 4;
- v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
- bcopy(&v, &optbuf[4], sizeof(u_int32_t));
-
- /* finally, adjust the packet header length */
- exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
-
- return (0);
-#undef JUMBOOPTLEN
-}
-
/*
* Insert fragment header and copy unfragmentable header portions.
*/
Index: sys/netinet6/ip6_var.h
===================================================================
--- sys/netinet6/ip6_var.h
+++ sys/netinet6/ip6_var.h
@@ -384,8 +384,7 @@
extern int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *,
struct mbuf *);
-int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
- u_int32_t *);
+int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *);
struct mbuf **ip6_savecontrol_v4(struct inpcb *, struct mbuf *,
struct mbuf **, int *);
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
Index: sys/netinet6/udp6_usrreq.c
===================================================================
--- sys/netinet6/udp6_usrreq.c
+++ sys/netinet6/udp6_usrreq.c
@@ -703,11 +703,6 @@
/* addr6 has been validated in udp6_send(). */
sin6 = (struct sockaddr_in6 *)addr6;
- /*
- * In contrast to to IPv4 we do not validate the max. packet length
- * here due to IPv6 Jumbograms (RFC2675).
- */
-
scope_ambiguous = 0;
if (sin6) {
/* Protect *addr6 from overwrites. */
@@ -891,6 +886,11 @@
plen = sizeof(struct udphdr) + ulen;
hlen = sizeof(struct ip6_hdr);
+ if (plen > IPV6_MAXPACKET) {
+ error = EMSGSIZE;
+ goto release;
+ }
+
/*
* Calculate data length and get a mbuf
* for UDP and IP6 headers.
@@ -921,10 +921,8 @@
* the entire UDPLite packet is covered by the checksum.
*/
cscov_partial = (cscov == 0) ? 0 : 1;
- } else if (plen <= 0xffff)
+ } else
udp6->uh_ulen = htons((u_short)plen);
- else
- udp6->uh_ulen = 0;
udp6->uh_sum = 0;
ip6 = mtod(m, struct ip6_hdr *);

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 27, 4:09 AM (20 m, 42 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16186677
Default Alt Text
D19960.diff (10 KB)

Event Timeline