summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2016-12-17 14:26:54 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2016-12-17 14:26:54 +0000
commit4d9be3b091561fd8eaaab2169b453b4dfccc8ff4 (patch)
tree45e07204b25fc205130eaad94e6b87036533764f
parentc039194158f1b24bb7f51e0d6278797088ccd0b7 (diff)
Insert RTF_CLONED routes at a higher priority than their partent to
prevent a mpath conflict for /32 RTF_CLONING routes. Found the hardway by jsing@ on Google Compute Engine. ok bluhm@, jsing@
-rw-r--r--sys/net/route.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 9919b9e036a..fdbb8a1160b 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.343 2016/12/14 20:35:20 stsp Exp $ */
+/* $OpenBSD: route.c,v 1.344 2016/12/17 14:26:53 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -252,8 +252,15 @@ rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid)
info.rti_info[RTAX_DST] = dst;
KERNEL_LOCK();
- error = rtrequest(RTM_RESOLVE, &info, RTP_DEFAULT,
- &rt, tableid);
+ /*
+ * The priority of cloned route should be different
+ * to avoid conflict with /32 cloning routes.
+ *
+ * It should also be higher to let the ARP layer find
+ * cloned routes instead of the cloning one.
+ */
+ error = rtrequest(RTM_RESOLVE, &info,
+ rt->rt_priority - 1, &rt, tableid);
if (error) {
rt_missmsg(RTM_MISS, &info, 0, RTP_NONE, 0,
error, tableid);
@@ -1046,15 +1053,14 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
ifa->ifa_refcnt++;
rt->rt_ifa = ifa;
rt->rt_ifidx = ifp->if_index;
- if (rt->rt_flags & RTF_CLONED) {
- /*
- * Copy both metrics and a back pointer to the cloned
- * route's parent.
- */
- rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
- rt->rt_priority = (*ret_nrt)->rt_priority;
- rt->rt_parent = *ret_nrt; /* Back ptr. to parent. */
- rtref(rt->rt_parent);
+ /*
+ * Copy metrics and a back pointer from the cloned
+ * route's parent.
+ */
+ if (ISSET(rt->rt_flags, RTF_CLONED)) {
+ rtref(*ret_nrt);
+ rt->rt_parent = *ret_nrt;
+ rt->rt_rmx = (*ret_nrt)->rt_rmx;
}
/*