Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143108930
D19960.id170265.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D19960.id170265.diff
View Options
diff --git a/sys/netinet/ip6.h b/sys/netinet/ip6.h
--- a/sys/netinet/ip6.h
+++ b/sys/netinet/ip6.h
@@ -258,6 +258,7 @@
#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
+#define IPV6_MAXPAYLOAD 65535 /* ip6 max payload size */
#define IPV6_MAXOPTHDR 2048 /* max option header size, 256 64-bit words */
#endif /* not _NETINET_IP6_H_ */
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -219,7 +219,7 @@
struct rmlock in6_ifaddr_lock;
RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock");
-static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
+static int ip6_hopopts_input(u_int32_t *, struct mbuf **, int *);
/*
* IP6 initialization: fill in IP6 protocol switch table.
@@ -408,14 +408,14 @@
#endif
static int
-ip6_input_hbh(struct mbuf **mp, uint32_t *plen, uint32_t *rtalert, int *off,
+ip6_input_hbh(struct mbuf **mp, uint32_t *rtalert, int *off,
int *nxt, int *ours)
{
struct mbuf *m;
struct ip6_hdr *ip6;
struct ip6_hbh *hbh;
- if (ip6_hopopts_input(plen, rtalert, mp, off)) {
+ if (ip6_hopopts_input(rtalert, mp, off)) {
#if 0 /*touches NULL pointer*/
in6_ifstat_inc((*mp)->m_pkthdr.rcvif, ifs6_in_discard);
#endif
@@ -427,16 +427,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 a Jumbo Payload option MUST be
+ * included. We no not support Jumbo Payloads so report an error.
*/
- 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);
@@ -775,6 +770,15 @@
goto bad;
}
+ plen = (u_int32_t)ntohs(ip6->ip6_plen);
+
+ /*
+ * We don't support Jumbograms, reject packets with plen == 0 as early
+ * as we can.
+ */
+ if (plen == 0)
+ goto bad;
+
/*
* Disambiguate address scope zones (if there is ambiguity).
* We first make sure that the original source or destination address
@@ -851,11 +855,9 @@
/*
* 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) {
- if (ip6_input_hbh(&m, &plen, &rtalert, &off, &nxt, &ours) != 0)
+ if (ip6_input_hbh(&m, &rtalert, &off, &nxt, &ours) != 0)
return;
} else
nxt = ip6->ip6_nxt;
@@ -964,13 +966,12 @@
/*
* Hop-by-Hop options header processing. If a valid jumbo payload option is
- * included, the real payload length will be stored in plenp.
+ * included report an error.
*
* rtalertp - XXX: should be stored more smart way
*/
static int
-ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
- struct mbuf **mp, int *offp)
+ip6_hopopts_input(u_int32_t *rtalertp, struct mbuf **mp, int *offp)
{
struct mbuf *m = *mp;
int off = *offp, hbhlen;
@@ -1000,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) {
*mp = NULL;
return (-1);
}
@@ -1022,13 +1023,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) {
@@ -1061,71 +1060,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);
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c
+++ b/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 void ip6_getpmtu(struct route_in6 *, int,
struct ifnet *, const struct in6_addr *, u_long *, u_int, u_int);
@@ -542,21 +541,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;
- ip6 = mtod(m, struct ip6_hdr *);
- hdrsplit = true;
- }
- if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
- goto freehdrs;
- ip6->ip6_plen = 0;
- optlen += 8; /* JUMBOOPTLEN */
+ error = EMSGSIZE;
+ goto freehdrs;
} else
ip6->ip6_plen = htons(plen);
nexthdrp = &ip6->ip6_nxt;
@@ -982,7 +969,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)
@@ -998,7 +984,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;
@@ -1186,7 +1172,7 @@
in6_ifstat_inc(ifp, ifs6_out_fragfail);
goto bad;
} else if (ip6->ip6_plen == 0) {
- /* Jumbo payload cannot be fragmented. */
+ /* We do not support jumbo payload. */
error = EMSGSIZE;
in6_ifstat_inc(ifp, ifs6_out_fragfail);
goto bad;
@@ -1312,94 +1298,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.
*/
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -393,8 +393,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 **);
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -703,11 +703,6 @@
sin6 = (struct sockaddr_in6 *)addr6;
- /*
- * In contrast 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. */
@@ -865,10 +860,22 @@
fport = inp->inp_fport;
}
+
+ /*
+ * We do not support IPv6 Jumbograms (RFC2675), so validate the payload
+ * length fits in a normal gram.
+ */
ulen = m->m_pkthdr.len;
plen = sizeof(struct udphdr) + ulen;
hlen = sizeof(struct ip6_hdr);
+ if (plen > IPV6_MAXPAYLOAD) {
+ if (control)
+ m_freem(control);
+ m_freem(m);
+ return (EMSGSIZE);
+ }
+
/*
* Calculate data length and get a mbuf for UDP, IP6, and possible
* link-layer headers. Immediate slide the data pointer back forward
@@ -903,10 +910,9 @@
* 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
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 27, 2:18 AM (19 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28048431
Default Alt Text
D19960.id170265.diff (12 KB)
Attached To
Mode
D19960: Remove support for RFC2675
Attached
Detach File
Event Timeline
Log In to Comment