-/* $OpenBSD: route.c,v 1.370 2018/02/08 13:50:48 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.371 2018/02/10 09:17:56 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
void rtflushclone(unsigned int, struct rtentry *);
int rt_ifa_purge_walker(struct rtentry *, void *, unsigned int);
struct rtentry *rt_match(struct sockaddr *, uint32_t *, int, unsigned int);
-struct rtentry *rt_clone(struct rtentry *, struct sockaddr *, unsigned int);
+int rt_clone(struct rtentry **, struct sockaddr *, unsigned int);
struct sockaddr *rt_plentosa(sa_family_t, int, struct sockaddr_in6 *);
#ifdef DDB
}
if (ISSET(rt->rt_flags, RTF_CLONING) && ISSET(flags, RT_RESOLVE))
- rt = rt_clone(rt, dst, tableid);
+ rt_clone(&rt, dst, tableid);
rt->rt_use++;
return (rt);
}
-struct rtentry *
-rt_clone(struct rtentry *rt, struct sockaddr *dst, unsigned int rtableid)
+int
+rt_clone(struct rtentry **rtp, struct sockaddr *dst, unsigned int rtableid)
{
struct rt_addrinfo info;
- struct rtentry *rt0;
+ struct rtentry *rt = *rtp;
int error = 0;
- rt0 = rt;
-
memset(&info, 0, sizeof(info));
info.rti_info[RTAX_DST] = dst;
} else {
/* Inform listeners of the new route */
rtm_send(rt, RTM_ADD, 0, rtableid);
- rtfree(rt0);
+ rtfree(*rtp);
+ *rtp = rt;
}
KERNEL_UNLOCK();
- return (rt);
+ return (error);
}
/*
{
struct rtentry *prt, *nhrt;
unsigned int rdomain = rtable_l2(rtableid);
+ int error;
NET_ASSERT_LOCKED();
return (EHOSTUNREACH);
}
- nhrt = rt_clone(prt, rt->rt_gateway, rtable_l2(rtableid));
+ error = rt_clone(&prt, rt->rt_gateway, rdomain);
+ if (error) {
+ rtfree(prt);
+ return (error);
+ }
+ nhrt = prt;
}
/*