Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 do not use cached route if the route becomes !R...



details:   https://anonhg.NetBSD.org/src/rev/6f6aa2cd2d3f
branches:  trunk
changeset: 487831:6f6aa2cd2d3f
user:      itojun <itojun%NetBSD.org@localhost>
date:      Tue Jun 13 14:43:44 2000 +0000

description:
do not use cached route if the route becomes !RTF_UP.
make the validation for jumbo payload option more strict.

diffstat:

 sys/netinet6/ip6_input.c |  158 +++++++++++++++++++++++++++++-----------------
 1 files changed, 100 insertions(+), 58 deletions(-)

diffs (223 lines):

diff -r dfafe31a205e -r 6f6aa2cd2d3f sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c  Tue Jun 13 14:42:55 2000 +0000
+++ b/sys/netinet6/ip6_input.c  Tue Jun 13 14:43:44 2000 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: ip6_input.c,v 1.21 2000/05/19 20:09:27 itojun Exp $    */
-/*     $KAME: ip6_input.c,v 1.89 2000/05/19 19:59:05 itojun Exp $      */
+/*     $NetBSD: ip6_input.c,v 1.22 2000/06/13 14:43:44 itojun Exp $    */
+/*     $KAME: ip6_input.c,v 1.94 2000/06/13 10:06:19 jinmei Exp $      */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -261,8 +261,7 @@
                if (m->m_next) {
                        if (m->m_flags & M_LOOP) {
                                ip6stat.ip6s_m2m[loif[0].if_index]++;   /*XXX*/
-                       }
-                       else if (m->m_pkthdr.rcvif->if_index <= 31)
+                       } else if (m->m_pkthdr.rcvif->if_index <= 31)
                                ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
                        else
                                ip6stat.ip6s_m2m[0]++;
@@ -443,13 +442,18 @@
        /*
         *  Unicast check
         */
-       if (ip6_forward_rt.ro_rt == 0 ||
-           !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
-                               &ip6_forward_rt.ro_dst.sin6_addr)) {
+       if (ip6_forward_rt.ro_rt != NULL &&
+           (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 && 
+           IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
+                              &ip6_forward_rt.ro_dst.sin6_addr))
+               ; /* cache hit */
+       else {
                if (ip6_forward_rt.ro_rt) {
+                       /* route is down or destination is different */
                        RTFREE(ip6_forward_rt.ro_rt);
                        ip6_forward_rt.ro_rt = 0;
                }
+
                bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
                ip6_forward_rt.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
                ip6_forward_rt.ro_dst.sin6_family = AF_INET6;
@@ -562,8 +566,29 @@
 #endif
                        return; /* 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_hoptops_input() must set a valid
+                        * (non-zero) payload length to the variable plen. 
+                        */
+                       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);
+                       return;
+               }
 #ifndef PULLDOWN_TEST
                /* ip6_hopopts_input() ensures that mbuf is contiguous */
                hbh = (struct ip6_hbh *)(ip6 + 1);
@@ -626,8 +651,7 @@
                        m_freem(m);
                        return;
                }
-       }
-       else if (!ours) {
+       } else if (!ours) {
                ip6_forward(m, 0);
                return;
        }       
@@ -638,7 +662,6 @@
 #ifdef IFA_STATS
        if (IFA_STATS && deliverifp != NULL) {
                struct in6_ifaddr *ia6;
-               ip6 = mtod(m, struct ip6_hdr *);
                ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
                if (ia6)
                        ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len;
@@ -740,6 +763,7 @@
        int optlen = 0;
        u_int8_t *opt = opthead;
        u_int16_t rtalert_val;
+       u_int32_t jumboplen;
 
        for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
                switch(*opt) {
@@ -768,57 +792,75 @@
                         *rtalertp = ntohs(rtalert_val);
                         break;
                 case IP6OPT_JUMBO:
-                        /* XXX may need check for alignment */
-                        if (hbhlen < IP6OPT_JUMBO_LEN) {
-                                ip6stat.ip6s_toosmall++;
-                                goto bad;
-                        }
-                        if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2)
-                                 /* XXX: should we discard the packet? */
-                                log(LOG_ERR, "length of jumbopayload opt "
-                                    "is inconsistent(%d)",
-                                    *(opt + 1));
-                        optlen = IP6OPT_JUMBO_LEN;
+                       /* XXX may need check for alignment */
+                       if (hbhlen < IP6OPT_JUMBO_LEN) {
+                               ip6stat.ip6s_toosmall++;
+                               goto bad;
+                       }
+                       if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2)
+                                /* XXX: should we discard the packet? */
+                               log(LOG_ERR, "length of jumbopayload opt "
+                                   "is inconsistent(%d)",
+                                   *(opt + 1));
+                       optlen = IP6OPT_JUMBO_LEN;
 
-                        /*
-                         * We can simply cast because of the alignment
-                         * requirement of the jumbo payload option.
-                         */
-#if 0
-                        *plenp = ntohl(*(u_int32_t *)(opt + 2));
-#else
-                        bcopy(opt + 2, plenp, sizeof(*plenp));
-                        *plenp = htonl(*plenp);
+                       /*
+                        * IPv6 packets that have non 0 payload length
+                        * must not contain a jumbo paylod option.
+                        */
+                       ip6 = mtod(m, struct ip6_hdr *);
+                       if (ip6->ip6_plen) {
+                               ip6stat.ip6s_badoptions++;
+                               icmp6_error(m, ICMP6_PARAM_PROB,
+                                           ICMP6_PARAMPROB_HEADER,
+                                           sizeof(struct ip6_hdr) +
+                                           sizeof(struct ip6_hbh) +
+                                           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.ip6s_badoptions++;
+                               icmp6_error(m, ICMP6_PARAM_PROB,
+                                           ICMP6_PARAMPROB_HEADER,
+                                           sizeof(struct ip6_hdr) +
+                                           sizeof(struct ip6_hbh) +
+                                           opt + 2 - opthead);
+                               return(-1);
+                       }
 #endif
-                        if (*plenp <= IPV6_MAXPACKET) {
-                                /*
-                                 * jumbo payload length must be larger
-                                 * than 65535
-                                 */
-                                ip6stat.ip6s_badoptions++;
-                                icmp6_error(m, ICMP6_PARAM_PROB,
-                                            ICMP6_PARAMPROB_HEADER,
-                                            sizeof(struct ip6_hdr) +
-                                            sizeof(struct ip6_hbh) +
-                                            opt + 2 - opthead);
-                                return(-1);
-                        }
 
-                        ip6 = mtod(m, struct ip6_hdr *);
-                        if (ip6->ip6_plen) {
-                                /*
-                                 * IPv6 packets that have non 0 payload length
-                                 * must not contain a jumbo paylod option.
-                                 */
-                                ip6stat.ip6s_badoptions++;
-                                icmp6_error(m, ICMP6_PARAM_PROB,
-                                            ICMP6_PARAMPROB_HEADER,
-                                            sizeof(struct ip6_hdr) +
-                                            sizeof(struct ip6_hbh) +
-                                            opt - opthead);
-                                return(-1);
-                        }
-                        break;
+                       /*
+                        * jumbo payload length must be larger than 65535.
+                        */
+                       if (jumboplen <= IPV6_MAXPACKET) {
+                               ip6stat.ip6s_badoptions++;
+                               icmp6_error(m, ICMP6_PARAM_PROB,
+                                           ICMP6_PARAMPROB_HEADER,
+                                           sizeof(struct ip6_hdr) +
+                                           sizeof(struct ip6_hbh) +
+                                           opt + 2 - opthead);
+                               return(-1);
+                       }
+                       *plenp = jumboplen;
+
+                       break;
                 default:               /* unknown option */
                         if (hbhlen < IP6OPT_MINLEN) {
                                 ip6stat.ip6s_toosmall++;



Home | Main Index | Thread Index | Old Index