sync with OpenBSD -current

This commit is contained in:
purplerain 2023-11-13 23:00:18 +00:00
parent 62d64fa864
commit 4574748555
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
13806 changed files with 1142078 additions and 937084 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: route.c,v 1.422 2023/04/28 20:03:14 mvs Exp $ */
/* $OpenBSD: route.c,v 1.426 2023/11/13 17:18:27 bluhm Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@ -158,15 +158,17 @@ int rttrash; /* routes not in table but not freed */
struct pool rtentry_pool; /* pool for rtentry structures */
struct pool rttimer_pool; /* pool for rttimer structures */
int rt_setgwroute(struct rtentry *, u_int);
void rt_putgwroute(struct rtentry *);
int rt_setgwroute(struct rtentry *, const struct sockaddr *, u_int);
void rt_putgwroute(struct rtentry *, struct rtentry *);
int rtflushclone1(struct rtentry *, void *, u_int);
int rtflushclone(struct rtentry *, unsigned int);
int rt_ifa_purge_walker(struct rtentry *, void *, unsigned int);
struct rtentry *rt_match(struct sockaddr *, uint32_t *, int, unsigned int);
int rt_clone(struct rtentry **, struct sockaddr *, unsigned int);
struct rtentry *rt_match(const struct sockaddr *, uint32_t *, int,
unsigned int);
int rt_clone(struct rtentry **, const struct sockaddr *, unsigned int);
struct sockaddr *rt_plentosa(sa_family_t, int, struct sockaddr_in6 *);
static int rt_copysa(struct sockaddr *, struct sockaddr *, struct sockaddr **);
static int rt_copysa(const struct sockaddr *, const struct sockaddr *,
struct sockaddr **);
#define LABELID_MAX 50000
@ -229,7 +231,8 @@ rtisvalid(struct rtentry *rt)
* NDP), if it does not exist.
*/
struct rtentry *
rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid)
rt_match(const struct sockaddr *dst, uint32_t *src, int flags,
unsigned int tableid)
{
struct rtentry *rt = NULL;
@ -247,7 +250,8 @@ rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid)
}
int
rt_clone(struct rtentry **rtp, struct sockaddr *dst, unsigned int rtableid)
rt_clone(struct rtentry **rtp, const struct sockaddr *dst,
unsigned int rtableid)
{
struct rt_addrinfo info;
struct rtentry *rt = *rtp;
@ -294,7 +298,7 @@ rt_clone(struct rtentry **rtp, struct sockaddr *dst, unsigned int rtableid)
} while (0)
int
rt_hash(struct rtentry *rt, struct sockaddr *dst, uint32_t *src)
rt_hash(struct rtentry *rt, const struct sockaddr *dst, uint32_t *src)
{
uint32_t a, b, c;
@ -307,12 +311,12 @@ rt_hash(struct rtentry *rt, struct sockaddr *dst, uint32_t *src)
switch (dst->sa_family) {
case AF_INET:
{
struct sockaddr_in *sin;
const struct sockaddr_in *sin;
if (!ipmultipath)
return (-1);
sin = satosin(dst);
sin = satosin_const(dst);
a += sin->sin_addr.s_addr;
b += src[0];
mix(a, b, c);
@ -321,12 +325,12 @@ rt_hash(struct rtentry *rt, struct sockaddr *dst, uint32_t *src)
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 *sin6;
const struct sockaddr_in6 *sin6;
if (!ip6_multipath)
return (-1);
sin6 = satosin6(dst);
sin6 = satosin6_const(dst);
a += sin6->sin6_addr.s6_addr32[0];
b += sin6->sin6_addr.s6_addr32[2];
c += src[0];
@ -355,7 +359,7 @@ rt_hash(struct rtentry *rt, struct sockaddr *dst, uint32_t *src)
* Allocate a route, potentially using multipath to select the peer.
*/
struct rtentry *
rtalloc_mpath(struct sockaddr *dst, uint32_t *src, unsigned int rtableid)
rtalloc_mpath(const struct sockaddr *dst, uint32_t *src, unsigned int rtableid)
{
return (rt_match(dst, src, RT_RESOLVE, rtableid));
}
@ -368,7 +372,7 @@ rtalloc_mpath(struct sockaddr *dst, uint32_t *src, unsigned int rtableid)
* longer valid, try to cache it.
*/
struct rtentry *
rtalloc(struct sockaddr *dst, int flags, unsigned int rtableid)
rtalloc(const struct sockaddr *dst, int flags, unsigned int rtableid)
{
return (rt_match(dst, NULL, flags, rtableid));
}
@ -378,7 +382,7 @@ rtalloc(struct sockaddr *dst, int flags, unsigned int rtableid)
* the gateway entry ``rt''.
*/
int
rt_setgwroute(struct rtentry *rt, u_int rtableid)
rt_setgwroute(struct rtentry *rt, const struct sockaddr *gate, u_int rtableid)
{
struct rtentry *prt, *nhrt;
unsigned int rdomain = rtable_l2(rtableid);
@ -386,10 +390,8 @@ rt_setgwroute(struct rtentry *rt, u_int rtableid)
NET_ASSERT_LOCKED();
KASSERT(ISSET(rt->rt_flags, RTF_GATEWAY));
/* If we cannot find a valid next hop bail. */
nhrt = rt_match(rt->rt_gateway, NULL, RT_RESOLVE, rdomain);
nhrt = rt_match(gate, NULL, RT_RESOLVE, rdomain);
if (nhrt == NULL)
return (ENOENT);
@ -422,7 +424,7 @@ rt_setgwroute(struct rtentry *rt, u_int rtableid)
return (EHOSTUNREACH);
}
error = rt_clone(&prt, rt->rt_gateway, rdomain);
error = rt_clone(&prt, gate, rdomain);
if (error) {
rtfree(prt);
return (error);
@ -439,10 +441,6 @@ rt_setgwroute(struct rtentry *rt, u_int rtableid)
return (ENETUNREACH);
}
/* Next hop is valid so remove possible old cache. */
rt_putgwroute(rt);
KASSERT(rt->rt_gwroute == NULL);
/*
* If the MTU of next hop is 0, this will reset the MTU of the
* route to run PMTUD again from scratch.
@ -459,7 +457,8 @@ rt_setgwroute(struct rtentry *rt, u_int rtableid)
nhrt->rt_flags |= RTF_CACHED;
nhrt->rt_cachecnt++;
rt->rt_gwroute = nhrt;
/* commit */
rt_putgwroute(rt, nhrt);
return (0);
}
@ -468,24 +467,29 @@ rt_setgwroute(struct rtentry *rt, u_int rtableid)
* Invalidate the cached route entry of the gateway entry ``rt''.
*/
void
rt_putgwroute(struct rtentry *rt)
rt_putgwroute(struct rtentry *rt, struct rtentry *nhrt)
{
struct rtentry *nhrt = rt->rt_gwroute;
struct rtentry *onhrt;
NET_ASSERT_LOCKED();
if (!ISSET(rt->rt_flags, RTF_GATEWAY) || nhrt == NULL)
if (!ISSET(rt->rt_flags, RTF_GATEWAY))
return;
KASSERT(ISSET(nhrt->rt_flags, RTF_CACHED));
KASSERT(nhrt->rt_cachecnt > 0);
/* this is protected as per [X] in route.h */
onhrt = rt->rt_gwroute;
rt->rt_gwroute = nhrt;
--nhrt->rt_cachecnt;
if (nhrt->rt_cachecnt == 0)
nhrt->rt_flags &= ~RTF_CACHED;
if (onhrt != NULL) {
KASSERT(onhrt->rt_cachecnt > 0);
KASSERT(ISSET(onhrt->rt_flags, RTF_CACHED));
rtfree(rt->rt_gwroute);
rt->rt_gwroute = NULL;
--onhrt->rt_cachecnt;
if (onhrt->rt_cachecnt == 0)
CLR(onhrt->rt_flags, RTF_CACHED);
rtfree(onhrt);
}
}
void
@ -513,7 +517,10 @@ rtfree(struct rtentry *rt)
#ifdef MPLS
rt_mpls_clear(rt);
#endif
free(rt->rt_gateway, M_RTABLE, ROUNDUP(rt->rt_gateway->sa_len));
if (rt->rt_gateway != NULL) {
free(rt->rt_gateway, M_RTABLE,
ROUNDUP(rt->rt_gateway->sa_len));
}
free(rt_key(rt), M_RTABLE, rt_key(rt)->sa_len);
pool_put(&rtentry_pool, rt);
@ -796,7 +803,7 @@ rtrequest_delete(struct rt_addrinfo *info, u_int8_t prio, struct ifnet *ifp,
}
/* Release next hop cache before flushing cloned entries. */
rt_putgwroute(rt);
rt_putgwroute(rt, NULL);
/* Clean up any cloned children. */
if (ISSET(rt->rt_flags, RTF_CLONING))
@ -932,9 +939,11 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
tableid))) {
ifafree(ifa);
rtfree(rt->rt_parent);
rt_putgwroute(rt);
free(rt->rt_gateway, M_RTABLE,
ROUNDUP(rt->rt_gateway->sa_len));
rt_putgwroute(rt, NULL);
if (rt->rt_gateway != NULL) {
free(rt->rt_gateway, M_RTABLE,
ROUNDUP(rt->rt_gateway->sa_len));
}
free(ndst, M_RTABLE, ndst->sa_len);
pool_put(&rtentry_pool, rt);
return (error);
@ -965,9 +974,11 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
if (error != 0) {
ifafree(ifa);
rtfree(rt->rt_parent);
rt_putgwroute(rt);
free(rt->rt_gateway, M_RTABLE,
ROUNDUP(rt->rt_gateway->sa_len));
rt_putgwroute(rt, NULL);
if (rt->rt_gateway != NULL) {
free(rt->rt_gateway, M_RTABLE,
ROUNDUP(rt->rt_gateway->sa_len));
}
free(ndst, M_RTABLE, ndst->sa_len);
pool_put(&rtentry_pool, rt);
return (EEXIST);
@ -988,27 +999,35 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
}
int
rt_setgate(struct rtentry *rt, struct sockaddr *gate, u_int rtableid)
rt_setgate(struct rtentry *rt, const struct sockaddr *gate, u_int rtableid)
{
int glen = ROUNDUP(gate->sa_len);
struct sockaddr *sa;
struct sockaddr *sa, *osa;
int error = 0;
if (rt->rt_gateway == NULL || glen != ROUNDUP(rt->rt_gateway->sa_len)) {
sa = malloc(glen, M_RTABLE, M_NOWAIT);
if (sa == NULL)
return (ENOBUFS);
if (rt->rt_gateway != NULL) {
free(rt->rt_gateway, M_RTABLE,
ROUNDUP(rt->rt_gateway->sa_len));
}
rt->rt_gateway = sa;
}
memmove(rt->rt_gateway, gate, glen);
KASSERT(gate != NULL);
if (rt->rt_gateway == gate) {
/* nop */
return (0);
};
sa = malloc(glen, M_RTABLE, M_NOWAIT | M_ZERO);
if (sa == NULL)
return (ENOBUFS);
memcpy(sa, gate, gate->sa_len);
KERNEL_LOCK(); /* see [X] in route.h */
osa = rt->rt_gateway;
rt->rt_gateway = sa;
if (ISSET(rt->rt_flags, RTF_GATEWAY))
return (rt_setgwroute(rt, rtableid));
error = rt_setgwroute(rt, gate, rtableid);
KERNEL_UNLOCK();
return (0);
if (osa != NULL)
free(osa, M_RTABLE, ROUNDUP(osa->sa_len));
return (error);
}
/*
@ -1051,7 +1070,8 @@ rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst,
* that is useable for the routing table.
*/
static int
rt_copysa(struct sockaddr *src, struct sockaddr *mask, struct sockaddr **dst)
rt_copysa(const struct sockaddr *src, const struct sockaddr *mask,
struct sockaddr **dst)
{
static const u_char maskarray[] = {
0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
@ -1563,7 +1583,7 @@ rt_timer_timer(void *arg)
#ifdef MPLS
int
rt_mpls_set(struct rtentry *rt, struct sockaddr *src, uint8_t op)
rt_mpls_set(struct rtentry *rt, const struct sockaddr *src, uint8_t op)
{
struct sockaddr_mpls *psa_mpls = (struct sockaddr_mpls *)src;
struct rt_mpls *rt_mpls;
@ -1601,7 +1621,7 @@ rt_mpls_clear(struct rtentry *rt)
#endif
u_int16_t
rtlabel_name2id(char *name)
rtlabel_name2id(const char *name)
{
struct rt_label *label, *p;
u_int16_t new_id = 1, id = 0;