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