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 mistakingly forward link-local scoped pa...



details:   https://anonhg.NetBSD.org/src/rev/b225dc81d8b0
branches:  trunk
changeset: 486322:b225dc81d8b0
user:      itojun <itojun%NetBSD.org@localhost>
date:      Fri May 19 01:40:18 2000 +0000

description:
do not mistakingly forward link-local scoped packet (the bug was added
with "beyondscope" icmp6 support).
"options FAKE_LOOPBACK_IF" will honor scope on loopback outputs.  rcvif will
be real interface, not the loopback, just like when multicast loopback.

(sync with kame)

diffstat:

 sys/netinet6/ip6_forward.c |   57 ++++++++++++++++++++--
 sys/netinet6/ip6_output.c  |  110 +++++++++++++++++++++++++++-----------------
 sys/netinet6/nd6.c         |   27 ++++++++--
 sys/netinet6/nd6.h         |    8 +-
 sys/netinet6/nd6_nbr.c     |   16 ++++--
 5 files changed, 152 insertions(+), 66 deletions(-)

diffs (truncated from 517 to 300 lines):

diff -r 864d5ade77c7 -r b225dc81d8b0 sys/netinet6/ip6_forward.c
--- a/sys/netinet6/ip6_forward.c        Fri May 19 01:09:21 2000 +0000
+++ b/sys/netinet6/ip6_forward.c        Fri May 19 01:40:18 2000 +0000
@@ -1,10 +1,10 @@
-/*     $NetBSD: ip6_forward.c,v 1.9 2000/02/26 08:39:20 itojun Exp $   */
-/*     $KAME: ip6_forward.c,v 1.28 2000/02/22 14:04:20 itojun Exp $    */
+/*     $NetBSD: ip6_forward.c,v 1.10 2000/05/19 01:40:18 itojun Exp $  */
+/*     $KAME: ip6_forward.c,v 1.35 2000/05/18 16:31:27 itojun Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -16,7 +16,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -90,6 +90,7 @@
        register struct rtentry *rt;
        int error, type = 0, code = 0;
        struct mbuf *mcopy = NULL;
+       struct ifnet *origifp;  /* maybe unnecessary */
 #ifdef IPSEC_IPV6FWD
        struct secpolicy *sp = NULL;
 #endif
@@ -383,7 +384,7 @@
                        }
 
                        /*
-                        * if mtu becomes less than minimum MTU, 
+                        * if mtu becomes less than minimum MTU,
                         * tell minimum MTU (and I'll need to fragment it).
                         */
                        if (mtu < IPV6_MMTU)
@@ -427,13 +428,55 @@
        }
 #endif
 
+       /*
+        * Fake scoped addresses. Note that even link-local source or
+        * destinaion can appear, if the originating node just sends the
+        * packet to us (without address resolution for the destination).
+        * Since both icmp6_error and icmp6_redirect_output fill the embedded
+        * link identifiers, we can do this stuff after make a copy for
+        * returning error.
+        */
+       if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
+               /*
+                * See corresponding comments in ip6_output.
+                * XXX: but is it possible that ip6_forward() sends a packet
+                *      to a loopback interface? I don't think so, and thus
+                *      I bark here. (jinmei%kame.net@localhost)
+                */
+               printf("ip6_forward: outgoing interface is loopback. "
+                      "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
+                      ip6_sprintf(&ip6->ip6_src), ip6_sprintf(&ip6->ip6_dst),
+                      ip6->ip6_nxt, if_name(m->m_pkthdr.rcvif),
+                      if_name(rt->rt_ifp));
+                      
+               if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+                       origifp = ifindex2ifnet[ntohs(ip6->ip6_src.s6_addr16[1])];
+               else if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+                       origifp = ifindex2ifnet[ntohs(ip6->ip6_dst.s6_addr16[1])];
+               else
+                       origifp = rt->rt_ifp;
+       }
+       else
+               origifp = rt->rt_ifp;
+#ifndef FAKE_LOOPBACK_IF
+       if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0)
+#else
+       if (1)
+#endif
+       {
+               if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+                       ip6->ip6_src.s6_addr16[1] = 0;
+               if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+                       ip6->ip6_dst.s6_addr16[1] = 0;
+       }
+
 #ifdef OLDIP6OUTPUT
        error = (*rt->rt_ifp->if_output)(rt->rt_ifp, m,
                                         (struct sockaddr *)dst,
                                         ip6_forward_rt.ro_rt);
 #else
-       error = nd6_output(rt->rt_ifp, m, dst, rt);
-#endif 
+       error = nd6_output(rt->rt_ifp, origifp, m, dst, rt);
+#endif
        if (error) {
                in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard);
                ip6stat.ip6s_cantforward++;
diff -r 864d5ade77c7 -r b225dc81d8b0 sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c Fri May 19 01:09:21 2000 +0000
+++ b/sys/netinet6/ip6_output.c Fri May 19 01:40:18 2000 +0000
@@ -1,9 +1,10 @@
-/*     $NetBSD: ip6_output.c,v 1.18 2000/03/29 03:38:53 simonb Exp $   */
+/*     $NetBSD: ip6_output.c,v 1.19 2000/05/19 01:40:18 itojun Exp $   */
+/*     $KAME: ip6_output.c,v 1.102 2000/05/17 15:31:56 itojun Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -15,7 +16,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -143,7 +144,7 @@
        struct ifnet **ifpp;            /* XXX: just for statistics */
 {
        struct ip6_hdr *ip6, *mhip6;
-       struct ifnet *ifp;
+       struct ifnet *ifp, *origifp;
        struct mbuf *m = m0;
        int hlen, tlen, len, off;
        struct route_in6 ip6route;
@@ -520,7 +521,7 @@
 
                exthdrs.ip6e_ip6 = m;
        }
-#endif /*IPESC*/
+#endif /*IPSEC*/
 
        if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
                /* Unicast */
@@ -534,7 +535,7 @@
                 */
                if (ro->ro_rt == 0) {
                        /*
-                        * NetBSD/OpenBSD always clones routes, if parent is
+                        * non-bsdi always clone routes, if parent is
                         * PRF_CLONING.
                         */
                        rtalloc((struct route *)ro);
@@ -555,11 +556,11 @@
                in6_ifstat_inc(ifp, ifs6_out_request);
 
                /*
-                * Check if there is the outgoing interface conflicts with
-                * the interface specified by ifi6_ifindex(if specified).
+                * Check if the outgoing interface conflicts with
+                * the interface specified by ifi6_ifindex (if specified).
                 * Note that loopback interface is always okay.
-                * (this happens when we are sending packet toward my
-                * interface)
+                * (this may happen when we are sending a packet to one of
+                *  our own addresses.)
                 */
                if (opt && opt->ip6po_pktinfo
                 && opt->ip6po_pktinfo->ipi6_ifindex) {
@@ -614,8 +615,7 @@
                                /* XXX correct ifp? */
                                in6_ifstat_inc(ifp, ifs6_out_discard);
                                goto bad;
-                       }
-                       else {
+                       } else {
                                ifp = &loif[0];
                        }
                }
@@ -753,10 +753,38 @@
                mtu = nd_ifinfo[ifp->if_index].linkmtu;
        }
 
-       /*
-        * Fake link-local scope-class addresses
-        */
-       if ((ifp->if_flags & IFF_LOOPBACK) == 0) {
+       /* Fake scoped addresses */
+       if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
+               /*
+                * If source or destination address is a scoped address, and
+                * the packet is going to be sent to a loopback interface,
+                * we should keep the original interface.
+                */
+
+               /*
+                * XXX: this is a very experimental and temporary solution.
+                * We eventually have sockaddr_in6 and use the sin6_scope_id
+                * field of the structure here.
+                * We rely on the consistency between two scope zone ids
+                * of source add destination, which should already be assured
+                * Larger scopes than link will be supported in the near
+                * future.
+                */
+               if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
+                       origifp = ifindex2ifnet[ntohs(ip6->ip6_src.s6_addr16[1])];
+               else if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
+                       origifp = ifindex2ifnet[ntohs(ip6->ip6_dst.s6_addr16[1])];
+               else
+                       origifp = ifp;
+       }
+       else
+               origifp = ifp;
+#ifndef FAKE_LOOPBACK_IF
+       if ((ifp->if_flags & IFF_LOOPBACK) != 0)
+#else
+       if (1)
+#endif
+       {
                if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
                        ip6->ip6_src.s6_addr16[1] = 0;
                if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
@@ -816,7 +844,7 @@
 #endif /* PFIL_HOOKS */
        /*
         * Send the packet to the outgoing interface.
-        * If necessary, do IPv6 fragmentation before sending. 
+        * If necessary, do IPv6 fragmentation before sending.
         */
        tlen = m->m_pkthdr.len;
        if (tlen <= mtu
@@ -830,7 +858,7 @@
             * larger than the link's MTU.
             * XXX: IFF_FRAGMENTABLE (or such) flag has not been defined yet...
             */
-           
+       
            || ifp->if_flags & IFF_FRAGMENTABLE
 #endif
            )
@@ -850,7 +878,7 @@
                error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
                                          ro->ro_rt);
 #else
-               error = nd6_output(ifp, m, dst, ro->ro_rt);
+               error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
 #endif
                goto done;
        } else if (mtu < IPV6_MMTU) {
@@ -895,16 +923,13 @@
                if (exthdrs.ip6e_rthdr) {
                        nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
                        *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
-               }
-               else if (exthdrs.ip6e_dest1) {
+               } else if (exthdrs.ip6e_dest1) {
                        nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
                        *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
-               }
-               else if (exthdrs.ip6e_hbh) {
+               } else if (exthdrs.ip6e_hbh) {
                        nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
                        *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
-               }
-               else {
+               } else {
                        nextproto = ip6->ip6_nxt;
                        ip6->ip6_nxt = IPPROTO_FRAGMENT;
                }
@@ -986,10 +1011,9 @@
                                                  (struct sockaddr *)dst,
                                                  ro->ro_rt);
 #else
-                       error = nd6_output(ifp, m, dst, ro->ro_rt);
+                       error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
 #endif
-               }
-               else
+               } else
                        m_freem(m);
        }
 
@@ -1052,7 +1076,7 @@
 }
 
 /*
- * Insert jumbo payload option. 
+ * Insert jumbo payload option.
  */
 static int
 ip6_insert_jumboopt(exthdrs, plen)
@@ -1078,8 +1102,7 @@
                optbuf = mtod(mopt, u_char *);
                optbuf[1] = 0;  /* = ((JUMBOOPTLEN) >> 3) - 1 */
                exthdrs->ip6e_hbh = mopt;
-       }
-       else {
+       } else {
                struct ip6_hbh *hbh;
 



Home | Main Index | Thread Index | Old Index