sync with OpenBSD -current
This commit is contained in:
parent
62d64fa864
commit
4574748555
13806 changed files with 1142078 additions and 937084 deletions
142
sys/net/route.c
142
sys/net/route.c
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue