Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netinet6 Fix RTF_{REJECT, BLACKHOLE} behavior for IPv6 ro...
details: https://anonhg.NetBSD.org/src/rev/70d9505f381e
branches: trunk
changeset: 814937:70d9505f381e
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Thu Apr 21 05:07:50 2016 +0000
description:
Fix RTF_{REJECT,BLACKHOLE} behavior for IPv6 routes
We still need a nexthop route to reflect RTF_{REJECT,BLACKHOLE}.
In the future, we would do it w/o looking up a route.
diffstat:
sys/netinet6/nd6.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 83 insertions(+), 2 deletions(-)
diffs (127 lines):
diff -r 26019fc2c4a4 -r 70d9505f381e sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c Wed Apr 20 17:18:52 2016 +0000
+++ b/sys/netinet6/nd6.c Thu Apr 21 05:07:50 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6.c,v 1.190 2016/04/10 08:15:52 ozaki-r Exp $ */
+/* $NetBSD: nd6.c,v 1.191 2016/04/21 05:07:50 ozaki-r Exp $ */
/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.190 2016/04/10 08:15:52 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.191 2016/04/21 05:07:50 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -2107,6 +2107,70 @@
mutex_exit(softnet_lock);
}
+/*
+ * Next hop determination. This routine was derived from ip_output.c.
+ */
+static int
+nd6_determine_nexthop(struct ifnet *ifp, const struct sockaddr_in6 *dst,
+ struct rtentry *rt0, struct rtentry **ret_rt, bool *sendpkt)
+{
+ struct rtentry *rt = rt0;
+ struct rtentry *gwrt = NULL;
+ struct sockaddr_in6 *gw6 = satosin6(rt->rt_gateway);
+
+ /*
+ * We skip link-layer address resolution and NUD
+ * if the gateway is not a neighbor from ND point
+ * of view, regardless of the value of nd_ifinfo.flags.
+ * The second condition is a bit tricky; we skip
+ * if the gateway is our own address, which is
+ * sometimes used to install a route to a p2p link.
+ */
+ if (!nd6_is_addr_neighbor(gw6, ifp) ||
+ in6ifa_ifpwithaddr(ifp, &gw6->sin6_addr)) {
+ /*
+ * We allow this kind of tricky route only
+ * when the outgoing interface is p2p.
+ * XXX: we may need a more generic rule here.
+ */
+ if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+ goto hostunreach;
+
+ *sendpkt = true;
+ return 0;
+ }
+
+ /* Try to use a cached nexthop route (gwroute) if exists */
+ gwrt = rt_get_gwroute(rt);
+ if (gwrt == NULL || (gwrt->rt_flags & RTF_UP) == 0) {
+ if (gwrt != NULL) {
+ rtfree(gwrt);
+ }
+ /* Look up a nexthop route */
+ gwrt = rtalloc1(rt->rt_gateway, 1);
+ rt_set_gwroute(rt, gwrt);
+ rt = gwrt;
+ if (rt == NULL)
+ goto hostunreach;
+ /* the "G" test below also prevents rt == rt0 */
+ if ((rt->rt_flags & RTF_GATEWAY) ||
+ (rt->rt_ifp != ifp)) {
+ if (rt0->rt_gwroute != NULL)
+ rtfree(rt0->rt_gwroute);
+ rt0->rt_gwroute = NULL;
+ goto hostunreach;
+ }
+ }
+ *ret_rt = gwrt;
+ return 0;
+
+hostunreach:
+ if (gwrt != NULL)
+ rtfree(gwrt);
+
+ return EHOSTUNREACH;
+}
+
int
nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m,
const struct sockaddr_in6 *dst, struct rtentry *rt)
@@ -2115,6 +2179,7 @@
struct llentry *ln = NULL;
int error = 0;
bool created = false;
+ struct rtentry *nexthop = NULL;
if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
goto sendpkt;
@@ -2129,6 +2194,19 @@
* or an anycast address(i.e. not a multicast).
*/
+ if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0) {
+ bool sendpkt = false;
+
+ /* Still need a nexthop to reflect RTF_{REJECT,BLACKHOLE} */
+ error = nd6_determine_nexthop(ifp, dst, rt, &nexthop, &sendpkt);
+ if (error != 0)
+ senderr(error);
+ if (nexthop != NULL)
+ rt = nexthop;
+ if (sendpkt)
+ goto sendpkt;
+ }
+
/* Look up the neighbor cache for the nexthop */
ln = nd6_lookup(&dst->sin6_addr, ifp, true);
if ((ln == NULL) && nd6_is_addr_neighbor(dst, ifp)) {
@@ -2262,6 +2340,9 @@
if (m != NULL)
m_freem(m);
exit:
+ if (nexthop != NULL)
+ rtfree(nexthop);
+
if (created)
nd6_gc_neighbors(LLTABLE6(ifp));
Home |
Main Index |
Thread Index |
Old Index