Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Jun 2020 23:28:37 +0200
From:      Michael Tuexen <tuexen@fh-muenster.de>
To:        "Alexander V. Chernikov" <melifaro@freebsd.org>
Cc:        src-committers <src-committers@freebsd.org>, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r361706 - in head/sys: net net/route netinet netinet6
Message-ID:  <6FE2C649-2D81-4C9C-B821-D8226B6BB95C@fh-muenster.de>
In-Reply-To: <202006012049.051KnhxX060695@repo.freebsd.org>
References:  <202006012049.051KnhxX060695@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--Apple-Mail=_30A6D176-B5FA-4F13-A949-3CE33C73C3B8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

> On 1. Jun 2020, at 22:49, Alexander V. Chernikov =
<melifaro@freebsd.org> wrote:
>=20
> Author: melifaro
> Date: Mon Jun  1 20:49:42 2020
> New Revision: 361706
> URL: https://svnweb.freebsd.org/changeset/base/361706
>=20
> Log:
>  * Add rib_<add|del|change>_route() functions to manipulate the =
routing table.
>=20
>  The main driver for the change is the need to improve notification =
mechanism.
>  Currently callers guess the operation data based on the rtentry =
structure
>   returned in case of successful operation result. There are two =
problems with
>   this appoach. First is that it doesn't provide enough information =
for the
>   upcoming multipath changes, where rtentry refers to a new nexthop =
group,
>   and there is no way of guessing which paths were added during the =
change.
>   Second is that some rtentry fields can change during notification =
and
>   protecting from it by requiring customers to unlock rtentry is not =
desired.
>=20
>  Additionally, as the consumers such as rtsock do know which operation =
they
>   request in advance, making explicit add/change/del versions of the =
functions
>   makes sense, especially given the functions don't share a lot of =
code.
>=20
>  With that in mind, introduce rib_cmd_info notification structure and
>   rib_<add|del|change>_route() functions, with mandatory rib_cmd_info =
pointer.
>   It will be used in upcoming generalized notifications.
>=20
>  * Move definitions of the new functions and some other =
functions/structures
>   used for the routing table manipulation to a separate header file,
>   net/route/route_ctl.h. net/route.h is a frequently used file =
included in
>   ~140 places in kernel, and 90% of the users don't need these =
definitions.
>=20
>  Reviewed by:		ae
>  Differential Revision:	https://reviews.freebsd.org/D25067
>=20
> Modified:
>  head/sys/net/if_llatbl.c
>  head/sys/net/route.c
>  head/sys/net/route.h
>  head/sys/net/route/nhop_ctl.c
>  head/sys/net/route/route_ctl.c
>  head/sys/net/route/route_ddb.c
>  head/sys/net/route/route_helpers.c
>  head/sys/net/route/route_temporal.c
>  head/sys/net/route/route_var.h
>  head/sys/netinet/in_rmx.c
>  head/sys/netinet/ip_icmp.c
>  head/sys/netinet6/icmp6.c
>  head/sys/netinet6/in6_rmx.c
>  head/sys/netinet6/nd6_rtr.c
>=20
> Modified: head/sys/net/if_llatbl.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/if_llatbl.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/if_llatbl.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_dl.h>
> #include <net/if_var.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
Where is this file coming from?

Best regards
Michael
> #include <net/vnet.h>
> #include <netinet/if_ether.h>
> #include <netinet6/in6_var.h>
>=20
> Modified: head/sys/net/route.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -61,6 +61,7 @@
> #include <net/if_var.h>
> #include <net/if_dl.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/route/nhop.h>
> #include <net/route/shared.h>
> @@ -346,6 +347,9 @@ rt_table_init(int offset, int family, u_int =
fibnum)
>=20
> 	nhops_init_rib(rh);
>=20
> +	/* Init subscription system */
> +	CK_STAILQ_INIT(&rh->rnh_subscribers);
> +
> 	/* Finally, set base callbacks */
> 	rh->rnh_addaddr =3D rn_addroute;
> 	rh->rnh_deladdr =3D rn_delete;
> @@ -1148,6 +1152,7 @@ rtrequest1_fib(int req, struct rt_addrinfo =
*info, stru
> {
> 	const struct sockaddr *dst;
> 	struct rib_head *rnh;
> +	struct rib_cmd_info rc;
> 	int error;
>=20
> 	KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
> @@ -1180,10 +1185,11 @@ rtrequest1_fib(int req, struct rt_addrinfo =
*info, stru
> 	if (info->rti_flags & RTF_HOST)
> 		info->rti_info[RTAX_NETMASK] =3D NULL;
>=20
> +	bzero(&rc, sizeof(struct rib_cmd_info));
> 	error =3D 0;
> 	switch (req) {
> 	case RTM_DELETE:
> -		error =3D del_route(rnh, info, ret_nrt);
> +		error =3D del_route(rnh, info, &rc);
> 		break;
> 	case RTM_RESOLVE:
> 		/*
> @@ -1192,14 +1198,17 @@ rtrequest1_fib(int req, struct rt_addrinfo =
*info, stru
> 		 */
> 		break;
> 	case RTM_ADD:
> -		error =3D add_route(rnh, info, ret_nrt);
> +		error =3D add_route(rnh, info, &rc);
> 		break;
> 	case RTM_CHANGE:
> -		error =3D change_route(rnh, info, ret_nrt);
> +		error =3D change_route(rnh, info, &rc);
> 		break;
> 	default:
> 		error =3D EOPNOTSUPP;
> 	}
> +
> +	if (ret_nrt !=3D NULL)
> +		*ret_nrt =3D rc.rc_rt;
>=20
> 	return (error);
> }
>=20
> Modified: head/sys/net/route.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route.h	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route.h	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -399,12 +399,6 @@ void	 rtfree(struct rtentry *);
> void	 rtfree_func(struct rtentry *);
> void	rt_updatemtu(struct ifnet *);
>=20
> -typedef int rt_walktree_f_t(struct rtentry *, void *);
> -typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *);
> -void	rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f,
> -	    void *arg, bool report);
> -void	rt_foreach_fib_walk(int af, rt_setwarg_t *, rt_walktree_f_t *, =
void *);
> -void	rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void =
*arg);
> void	rt_flushifroutes_af(struct ifnet *, int);
> void	rt_flushifroutes(struct ifnet *ifp);
>=20
> @@ -423,12 +417,8 @@ int	 rtrequest1_fib(int, struct rt_addrinfo =
*, struct=20
> int	rib_lookup_info(uint32_t, const struct sockaddr *, uint32_t, =
uint32_t,
> 	    struct rt_addrinfo *);
> void	rib_free_info(struct rt_addrinfo *info);
> -int	rib_add_redirect(u_int fibnum, struct sockaddr *dst,
> -	   struct sockaddr *gateway, struct sockaddr *author, struct =
ifnet *ifp,
> -	   int flags, int expire_sec);
>=20
> /* New API */
> -void	rib_walk(int af, u_int fibnum, rt_walktree_f_t *wa_f, void =
*arg);
> struct nhop_object *rib_lookup(uint32_t fibnum, const struct sockaddr =
*dst,
> 	    uint32_t flags, uint32_t flowid);
> #endif
>=20
> Modified: head/sys/net/route/nhop_ctl.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route/nhop_ctl.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route/nhop_ctl.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_var.h>
> #include <net/if_dl.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/route/nhop_utils.h>
> #include <net/route/nhop.h>
>=20
> Modified: head/sys/net/route/route_ctl.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route/route_ctl.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route/route_ctl.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_dl.h>
> #include <net/vnet.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/route/nhop_utils.h>
> #include <net/route/nhop.h>
> @@ -67,11 +68,61 @@ __FBSDID("$FreeBSD$");
>  * All functions assumes they are called in net epoch.
>  */
>=20
> +static void rib_notify(struct rib_head *rnh, enum =
rib_subscription_type type,
> +    struct rib_cmd_info *rc);
> +
> static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo =
*info);
>=20
> +static struct rib_head *
> +get_rnh(uint32_t fibnum, const struct rt_addrinfo *info)
> +{
> +	struct rib_head *rnh;
> +	struct sockaddr *dst;
> +
> +	KASSERT((fibnum < rt_numfibs), ("rib_add_route: bad fibnum"));
> +
> +	dst =3D info->rti_info[RTAX_DST];
> +	rnh =3D rt_tables_get_rnh(fibnum, dst->sa_family);
> +
> +	return (rnh);
> +}
> +
> +/*
> + * Adds route defined by @info into the kernel table specified by =
@fibnum and
> + * sa_family in @info->rti_info[RTAX_DST].
> + *
> + * Returns 0 on success and fills in operation metadata into @rc.
> + */
> int
> +rib_add_route(uint32_t fibnum, struct rt_addrinfo *info,
> +    struct rib_cmd_info *rc)
> +{
> +	struct rib_head *rnh;
> +
> +	NET_EPOCH_ASSERT();
> +
> +	rnh =3D get_rnh(fibnum, info);
> +	if (rnh =3D=3D NULL)
> +		return (EAFNOSUPPORT);
> +
> +	/*
> +	 * Check consistency between RTF_HOST flag and netmask
> +	 * existence.
> +	 */
> +	if (info->rti_flags & RTF_HOST)
> +		info->rti_info[RTAX_NETMASK] =3D NULL;
> +	else if (info->rti_info[RTAX_NETMASK] =3D=3D NULL)
> +		return (EINVAL);
> +
> +	bzero(rc, sizeof(struct rib_cmd_info));
> +	rc->rc_cmd =3D RTM_ADD;
> +
> +	return (add_route(rnh, info, rc));
> +}
> +
> +int
> add_route(struct rib_head *rnh, struct rt_addrinfo *info,
> -    struct rtentry **ret_nrt)
> +    struct rib_cmd_info *rc)
> {
> 	struct sockaddr *dst, *ndst, *gateway, *netmask;
> 	struct rtentry *rt, *rt_old;
> @@ -146,6 +197,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo =
*in
> 	rt->rt_weight =3D 1;
>=20
> 	rt_setmetrics(info, rt);
> +	rt_old =3D NULL;
>=20
> 	RIB_WLOCK(rnh);
> 	RT_LOCK(rt);
> @@ -163,12 +215,20 @@ add_route(struct rib_head *rnh, struct =
rt_addrinfo *in
>=20
> 	rn =3D rnh->rnh_addaddr(ndst, netmask, &rnh->head, =
rt->rt_nodes);
>=20
> -	if (rn !=3D NULL && rt->rt_expire > 0)
> -		tmproutes_update(rnh, rt);
> +	if (rn !=3D NULL) {
> +		/* Most common usecase */
> +		if (rt->rt_expire > 0)
> +			tmproutes_update(rnh, rt);
>=20
> -	rt_old =3D NULL;
> -	if (rn =3D=3D NULL && (info->rti_flags & RTF_PINNED) !=3D 0) {
> +		/* Finalize notification */
> +		rnh->rnh_gen++;
>=20
> +		rc->rc_rt =3D RNTORT(rn);
> +		rc->rc_nh_new =3D nh;
> +
> +		rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
> +	} else if ((info->rti_flags & RTF_PINNED) !=3D 0) {
> +
> 		/*
> 		 * Force removal and re-try addition
> 		 * TODO: better multipath&pinned support
> @@ -180,9 +240,26 @@ add_route(struct rib_head *rnh, struct =
rt_addrinfo *in
> 		rt_old =3D rt_unlinkrte(rnh, info, &error);
> 		info->rti_flags |=3D RTF_PINNED;
> 		info->rti_info[RTAX_DST] =3D info_dst;
> -		if (rt_old !=3D NULL)
> +		if (rt_old !=3D NULL) {
> 			rn =3D rnh->rnh_addaddr(ndst, netmask, =
&rnh->head,
> 			    rt->rt_nodes);
> +
> +			/* Finalize notification */
> +			rnh->rnh_gen++;
> +
> +			if (rn !=3D NULL) {
> +				rc->rc_cmd =3D RTM_CHANGE;
> +				rc->rc_rt =3D RNTORT(rn);
> +				rc->rc_nh_old =3D rt_old->rt_nhop;
> +				rc->rc_nh_new =3D nh;
> +			} else {
> +				rc->rc_cmd =3D RTM_DELETE;
> +				rc->rc_rt =3D RNTORT(rn);
> +				rc->rc_nh_old =3D rt_old->rt_nhop;
> +				rc->rc_nh_new =3D nh;
> +			}
> +			rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
> +		}
> 	}
> 	RIB_WUNLOCK(rnh);
>=20
> @@ -208,12 +285,6 @@ add_route(struct rib_head *rnh, struct =
rt_addrinfo *in
> 	if (ifa->ifa_rtrequest)
> 		ifa->ifa_rtrequest(RTM_ADD, rt, rt->rt_nhop, info);
>=20
> -	/*
> -	 * actually return a resultant rtentry
> -	 */
> -	if (ret_nrt)
> -		*ret_nrt =3D rt;
> -	rnh->rnh_gen++;		/* Routing table updated */
> 	RT_UNLOCK(rt);
>=20
> 	return (0);
> @@ -221,6 +292,29 @@ add_route(struct rib_head *rnh, struct =
rt_addrinfo *in
>=20
>=20
> /*
> + * Removes route defined by @info from the kernel table specified by =
@fibnum and
> + * sa_family in @info->rti_info[RTAX_DST].
> + *
> + * Returns 0 on success and fills in operation metadata into @rc.
> + */
> +int
> +rib_del_route(uint32_t fibnum, struct rt_addrinfo *info, struct =
rib_cmd_info *rc)
> +{
> +	struct rib_head *rnh;
> +
> +	NET_EPOCH_ASSERT();
> +
> +	rnh =3D get_rnh(fibnum, info);
> +	if (rnh =3D=3D NULL)
> +		return (EAFNOSUPPORT);
> +
> +	bzero(rc, sizeof(struct rib_cmd_info));
> +	rc->rc_cmd =3D RTM_DELETE;
> +
> +	return (del_route(rnh, info, rc));
> +}
> +
> +/*
>  * Conditionally unlinks rtentry matching data inside @info from @rnh.
>  * Returns unlinked, locked and referenced @rtentry on success,
>  * Returns NULL and sets @perror to:
> @@ -295,7 +389,7 @@ rt_unlinkrte(struct rib_head *rnh, struct =
rt_addrinfo=20
>=20
> int
> del_route(struct rib_head *rnh, struct rt_addrinfo *info,
> -    struct rtentry **ret_nrt)
> +    struct rib_cmd_info *rc)
> {
> 	struct sockaddr *dst, *netmask;
> 	struct sockaddr_storage mdst;
> @@ -314,6 +408,13 @@ del_route(struct rib_head *rnh, struct =
rt_addrinfo *in
>=20
> 	RIB_WLOCK(rnh);
> 	rt =3D rt_unlinkrte(rnh, info, &error);
> +	if (rt !=3D NULL) {
> +		/* Finalize notification */
> +		rnh->rnh_gen++;
> +		rc->rc_rt =3D rt;
> +		rc->rc_nh_old =3D rt->rt_nhop;
> +		rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
> +	}
> 	RIB_WUNLOCK(rnh);
> 	if (error !=3D 0)
> 		return (error);
> @@ -324,17 +425,32 @@ del_route(struct rib_head *rnh, struct =
rt_addrinfo *in
> 	 * If the caller wants it, then it can have it,
> 	 * the entry will be deleted after the end of the current epoch.
> 	 */
> -	if (ret_nrt)
> -		*ret_nrt =3D rt;
> -
> 	rtfree(rt);
>=20
> 	return (0);
> }
>=20
> +int
> +rib_change_route(uint32_t fibnum, struct rt_addrinfo *info,
> +    struct rib_cmd_info *rc)
> +{
> +	struct rib_head *rnh;
> +
> +	NET_EPOCH_ASSERT();
> +
> +	rnh =3D get_rnh(fibnum, info);
> +	if (rnh =3D=3D NULL)
> +		return (EAFNOSUPPORT);
> +
> +	bzero(rc, sizeof(struct rib_cmd_info));
> +	rc->rc_cmd =3D RTM_CHANGE;
> +
> +	return (change_route(rnh, info, rc));
> +}
> +
> static int
> change_route_one(struct rib_head *rnh, struct rt_addrinfo *info,
> -    struct rtentry **ret_nrt)
> +    struct rib_cmd_info *rc)
> {
> 	RIB_RLOCK_TRACKER;
> 	struct rtentry *rt =3D NULL;
> @@ -434,14 +550,18 @@ change_route_one(struct rib_head *rnh, struct =
rt_addri
> 	if ((nh_orig->nh_ifa !=3D nh->nh_ifa) && =
nh_orig->nh_ifa->ifa_rtrequest)
> 		nh_orig->nh_ifa->ifa_rtrequest(RTM_DELETE, rt, nh_orig, =
info);
>=20
> -	if (ret_nrt !=3D NULL)
> -		*ret_nrt =3D rt;
> +	/* Finalize notification */
> +	rc->rc_rt =3D rt;
> +	rc->rc_nh_old =3D nh_orig;
> +	rc->rc_nh_new =3D rt->rt_nhop;
>=20
> 	RT_UNLOCK(rt);
>=20
> 	/* Update generation id to reflect rtable change */
> 	rnh->rnh_gen++;
>=20
> +	rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc);
> +
> 	RIB_WUNLOCK(rnh);
>=20
> 	nhop_free(nh_orig);
> @@ -451,7 +571,7 @@ change_route_one(struct rib_head *rnh, struct =
rt_addri
>=20
> int
> change_route(struct rib_head *rnh, struct rt_addrinfo *info,
> -    struct rtentry **ret_nrt)
> +    struct rib_cmd_info *rc)
> {
> 	int error;
>=20
> @@ -468,7 +588,7 @@ change_route(struct rib_head *rnh, struct =
rt_addrinfo=20
> 	 * multiple times before failing.
> 	 */
> 	for (int i =3D 0; i < RIB_MAX_RETRIES; i++) {
> -		error =3D change_route_one(rnh, info, ret_nrt);
> +		error =3D change_route_one(rnh, info, rc);
> 		if (error !=3D EAGAIN)
> 			break;
> 	}
> @@ -581,4 +701,62 @@ rib_walk_del(u_int fibnum, int family, =
rt_filter_f_t *
> 	}
> }
>=20
> +static void
> +rib_notify(struct rib_head *rnh, enum rib_subscription_type type,
> +    struct rib_cmd_info *rc)
> +{
> +	struct rib_subscription *rs;
> +
> +	CK_STAILQ_FOREACH(rs, &rnh->rnh_subscribers, next) {
> +		if (rs->type =3D=3D type)
> +			rs->func(rnh, rc, rs->arg);
> +	}
> +}
> +
> +struct rib_subscription *
> +rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, =
void *arg,
> +    enum rib_subscription_type type, int waitok)
> +{
> +	struct rib_head *rnh;
> +	struct rib_subscription *rs;
> +	int flags =3D M_ZERO | (waitok ? M_WAITOK : 0);
> +
> +	NET_EPOCH_ASSERT();
> +	KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
> +	rnh =3D rt_tables_get_rnh(fibnum, family);
> +
> +	rs =3D malloc(sizeof(struct rib_subscription), M_RTABLE, flags);
> +	if (rs =3D=3D NULL)
> +		return (NULL);
> +
> +	rs->func =3D f;
> +	rs->arg =3D arg;
> +	rs->type =3D type;
> +
> +	RIB_WLOCK(rnh);
> +	CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next);
> +	RIB_WUNLOCK(rnh);
> +
> +	return (rs);
> +}
> +
> +int
> +rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription =
*rs)
> +{
> +	struct rib_head *rnh;
> +
> +	NET_EPOCH_ASSERT();
> +	KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__));
> +	rnh =3D rt_tables_get_rnh(fibnum, family);
> +
> +	if (rnh =3D=3D NULL)
> +		return (ENOENT);
> +
> +	RIB_WLOCK(rnh);
> +	CK_STAILQ_REMOVE(&rnh->rnh_subscribers, rs, rib_subscription, =
next);
> +	RIB_WUNLOCK(rnh);
> +
> +	free(rs, M_RTABLE);
> +	return (0);
> +}
>=20
>=20
> Modified: head/sys/net/route/route_ddb.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route/route_ddb.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route/route_ddb.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_dl.h>
> #include <net/route.h>
> #include <net/route/nhop.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
>=20
> /*
>=20
> Modified: head/sys/net/route/route_helpers.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route/route_helpers.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route/route_helpers.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_var.h>
> #include <net/if_dl.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/route/nhop_utils.h>
> #include <net/route/nhop.h>
>=20
> Modified: head/sys/net/route/route_temporal.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route/route_temporal.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route/route_temporal.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -38,11 +38,13 @@ __FBSDID("$FreeBSD$");
> #include <sys/socket.h>
> #include <sys/kernel.h>
> #include <sys/lock.h>
> +#include <sys/ck.h>
> #include <sys/rmlock.h>
> #include <sys/callout.h>
>=20
> #include <net/if.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/vnet.h>
>=20
>=20
> Modified: head/sys/net/route/route_var.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/net/route/route_var.h	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/net/route/route_var.h	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -35,6 +35,7 @@
> #ifndef RNF_NORMAL
> #include <net/radix.h>
> #endif
> +#include <sys/ck.h>
> #include <sys/epoch.h>
> #include <netinet/in.h>		/* struct sockaddr_in */
> #include <sys/counter.h>
> @@ -63,6 +64,7 @@ struct rib_head {
> 	struct callout		expire_callout;	/* Callout for expiring =
dynamic routes */
> 	time_t			next_expire;	/* Next expire run ts */
> 	struct nh_control	*nh_control;	/* nexthop subsystem =
data */
> +	CK_STAILQ_HEAD(, rib_subscription)	rnh_subscribers;/* =
notification subscribers */
> };
>=20
> #define	RIB_RLOCK_TRACKER	struct rm_priotracker =
_rib_tracker
> @@ -110,12 +112,13 @@ void rt_setmetrics(const struct rt_addrinfo =
*info, str
> struct radix_node *rt_mpath_unlink(struct rib_head *rnh,
>     struct rt_addrinfo *info, struct rtentry *rto, int *perror);
> #endif
> +struct rib_cmd_info;
> int add_route(struct rib_head *rnh, struct rt_addrinfo *info,
> -    struct rtentry **ret_nrt);
> +    struct rib_cmd_info *rc);
> int del_route(struct rib_head *rnh, struct rt_addrinfo *info,
> -    struct rtentry **ret_nrt);
> +    struct rib_cmd_info *rc);
> int change_route(struct rib_head *, struct rt_addrinfo *,
> -    struct rtentry **);
> +    struct rib_cmd_info *rc);
>=20
> VNET_PCPUSTAT_DECLARE(struct rtstat, rtstat);
> #define	RTSTAT_ADD(name, val)	\
>=20
> Modified: head/sys/netinet/in_rmx.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/netinet/in_rmx.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/netinet/in_rmx.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if.h>
> #include <net/if_var.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/route/nhop.h>
> #include <net/route/shared.h>
>=20
> Modified: head/sys/netinet/ip_icmp.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/netinet/ip_icmp.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/netinet/ip_icmp.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_var.h>
> #include <net/if_types.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/nhop.h>
> #include <net/vnet.h>
>=20
>=20
> Modified: head/sys/netinet6/icmp6.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/netinet6/icmp6.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/netinet6/icmp6.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_llatbl.h>
> #include <net/if_types.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/nhop.h>
> #include <net/vnet.h>
>=20
>=20
> Modified: head/sys/netinet6/in6_rmx.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/netinet6/in6_rmx.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/netinet6/in6_rmx.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if.h>
> #include <net/if_var.h>
> #include <net/route.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/route/nhop.h>
> #include <net/route/shared.h>
>=20
> Modified: head/sys/netinet6/nd6_rtr.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- head/sys/netinet6/nd6_rtr.c	Mon Jun  1 20:40:40 2020	=
(r361705)
> +++ head/sys/netinet6/nd6_rtr.c	Mon Jun  1 20:49:42 2020	=
(r361706)
> @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
> #include <net/if_dl.h>
> #include <net/route.h>
> #include <net/route/nhop.h>
> +#include <net/route/route_ctl.h>
> #include <net/route/route_var.h>
> #include <net/radix.h>
> #include <net/vnet.h>


--Apple-Mail=_30A6D176-B5FA-4F13-A949-3CE33C73C3B8
Content-Disposition: attachment;
	filename=smime.p7s
Content-Type: application/pkcs7-signature;
	name=smime.p7s
Content-Transfer-Encoding: base64

MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCCEKow
ggUSMIID+qADAgECAgkA4wvV+K8l2YEwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAkRFMSsw
KQYDVQQKDCJULVN5c3RlbXMgRW50ZXJwcmlzZSBTZXJ2aWNlcyBHbWJIMR8wHQYDVQQLDBZULVN5
c3RlbXMgVHJ1c3QgQ2VudGVyMSUwIwYDVQQDDBxULVRlbGVTZWMgR2xvYmFsUm9vdCBDbGFzcyAy
MB4XDTE2MDIyMjEzMzgyMloXDTMxMDIyMjIzNTk1OVowgZUxCzAJBgNVBAYTAkRFMUUwQwYDVQQK
EzxWZXJlaW4genVyIEZvZXJkZXJ1bmcgZWluZXMgRGV1dHNjaGVuIEZvcnNjaHVuZ3NuZXR6ZXMg
ZS4gVi4xEDAOBgNVBAsTB0RGTi1QS0kxLTArBgNVBAMTJERGTi1WZXJlaW4gQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMtg1/9moUHN0vqH
l4pzq5lN6mc5WqFggEcVToyVsuXPztNXS43O+FZsFVV2B+pG/cgDRWM+cNSrVICxI5y+NyipCf8F
XRgPxJiZN7Mg9mZ4F4fCnQ7MSjLnFp2uDo0peQcAIFTcFV9Kltd4tjTTwXS1nem/wHdN6r1ZB+Ba
L2w8pQDcNb1lDY9/Mm3yWmpLYgHurDg0WUU2SQXaeMpqbVvAgWsRzNI8qIv4cRrKO+KA3Ra0Z3qL
NupOkSk9s1FcragMvp0049ENF4N1xDkesJQLEvHVaY4l9Lg9K7/AjsMeO6W/VRCrKq4Xl14zzsjz
9AkH4wKGMUZrAcUQDBHHWekCAwEAAaOCAXQwggFwMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
k+PYMiba1fFKpZFK4OpL4qIMz+EwHwYDVR0jBBgwFoAUv1kgNgB5oKAia4zV8mHSuCzLgkowEgYD
VR0TAQH/BAgwBgEB/wIBAjAzBgNVHSAELDAqMA8GDSsGAQQBga0hgiwBAQQwDQYLKwYBBAGBrSGC
LB4wCAYGZ4EMAQICMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9wa2kwMzM2LnRlbGVzZWMuZGUv
cmwvVGVsZVNlY19HbG9iYWxSb290X0NsYXNzXzIuY3JsMIGGBggrBgEFBQcBAQR6MHgwLAYIKwYB
BQUHMAGGIGh0dHA6Ly9vY3NwMDMzNi50ZWxlc2VjLmRlL29jc3ByMEgGCCsGAQUFBzAChjxodHRw
Oi8vcGtpMDMzNi50ZWxlc2VjLmRlL2NydC9UZWxlU2VjX0dsb2JhbFJvb3RfQ2xhc3NfMi5jZXIw
DQYJKoZIhvcNAQELBQADggEBAIcL/z4Cm2XIVi3WO5qYi3FP2ropqiH5Ri71sqQPrhE4eTizDnS6
dl2e6BiClmLbTDPo3flq3zK9LExHYFV/53RrtCyD2HlrtrdNUAtmB7Xts5et6u5/MOaZ/SLick0+
hFvu+c+Z6n/XUjkurJgARH5pO7917tALOxrN5fcPImxHhPalR6D90Bo0fa3SPXez7vTXTf/D6OWS
T1k+kEcQSrCFWMBvf/iu7QhCnh7U3xQuTY+8npTD5+32GPg8SecmqKc22CzeIs2LgtjZeOJVEqM7
h0S2EQvVDFKvaYwPBt/QolOLV5h7z/0HJPT8vcP9SpIClxvyt7bPZYoaorVyGTkwggWsMIIElKAD
AgECAgcbY7rQHiw9MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYDVQQGEwJERTFFMEMGA1UEChM8VmVy
ZWluIHp1ciBGb2VyZGVydW5nIGVpbmVzIERldXRzY2hlbiBGb3JzY2h1bmdzbmV0emVzIGUuIFYu
MRAwDgYDVQQLEwdERk4tUEtJMS0wKwYDVQQDEyRERk4tVmVyZWluIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IDIwHhcNMTYwNTI0MTEzODQwWhcNMzEwMjIyMjM1OTU5WjCBjTELMAkGA1UEBhMCREUx
RTBDBgNVBAoMPFZlcmVpbiB6dXIgRm9lcmRlcnVuZyBlaW5lcyBEZXV0c2NoZW4gRm9yc2NodW5n
c25ldHplcyBlLiBWLjEQMA4GA1UECwwHREZOLVBLSTElMCMGA1UEAwwcREZOLVZlcmVpbiBHbG9i
YWwgSXNzdWluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ07eRxH3h+Gy8Zp
1xCeOdfZojDbchwFfylfS2jxrRnWTOFrG7ELf6Gr4HuLi9gtzm6IOhDuV+UefwRRNuu6cG1joL6W
LkDh0YNMZj0cZGnlm6Stcq5oOVGHecwX064vXWNxSzl660Knl5BpBb+Q/6RAcL0D57+eGIgfn5mI
TQ5HjUhfZZkQ0tkqSe3BuS0dnxLLFdM/fx5ULzquk1enfnjK1UriGuXtQX1TX8izKvWKMKztFwUk
P7agCwf9TRqaA1KgNpzeJIdl5Of6x5ZzJBTN0OgbaJ4YWa52fvfRCng8h0uwN89Tyjo4EPPLR22M
ZD08WkVKusqAfLjz56dMTM0CAwEAAaOCAgUwggIBMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0P
AQH/BAQDAgEGMCkGA1UdIAQiMCAwDQYLKwYBBAGBrSGCLB4wDwYNKwYBBAGBrSGCLAEBBDAdBgNV
HQ4EFgQUazqYi/nyU4na4K2yMh4JH+iqO3QwHwYDVR0jBBgwFoAUk+PYMiba1fFKpZFK4OpL4qIM
z+EwgY8GA1UdHwSBhzCBhDBAoD6gPIY6aHR0cDovL2NkcDEucGNhLmRmbi5kZS9nbG9iYWwtcm9v
dC1nMi1jYS9wdWIvY3JsL2NhY3JsLmNybDBAoD6gPIY6aHR0cDovL2NkcDIucGNhLmRmbi5kZS9n
bG9iYWwtcm9vdC1nMi1jYS9wdWIvY3JsL2NhY3JsLmNybDCB3QYIKwYBBQUHAQEEgdAwgc0wMwYI
KwYBBQUHMAGGJ2h0dHA6Ly9vY3NwLnBjYS5kZm4uZGUvT0NTUC1TZXJ2ZXIvT0NTUDBKBggrBgEF
BQcwAoY+aHR0cDovL2NkcDEucGNhLmRmbi5kZS9nbG9iYWwtcm9vdC1nMi1jYS9wdWIvY2FjZXJ0
L2NhY2VydC5jcnQwSgYIKwYBBQUHMAKGPmh0dHA6Ly9jZHAyLnBjYS5kZm4uZGUvZ2xvYmFsLXJv
b3QtZzItY2EvcHViL2NhY2VydC9jYWNlcnQuY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQCBeEWkTqR/
DlXwCbFqPnjMaDWpHPOVnj/z+N9rOHeJLI21rT7H8pTNoAauusyosa0zCLYkhmI2THhuUPDVbmCN
T1IxQ5dGdfBi5G5mUcFCMWdQ5UnnOR7Ln8qGSN4IFP8VSytmm6A4nwDO/afr0X9XLchMX9wQEZc+
lgQCXISoKTlslPwQkgZ7nu7YRrQbtQMMONncsKk/cQYLsgMHM8KNSGMlJTx6e1du94oFOO+4oK4v
9NsH1VuEGMGpuEvObJAaguS5Pfp38dIfMwK/U+d2+dwmJUFvL6Yb+qQTkPp8ftkLYF3sv8pBoGH7
EUkp2KgtdRXYShjqFu9VNCIaE40GMIIF4DCCBMigAwIBAgIMIRX9tDE2QqO3mVLXMA0GCSqGSIb3
DQEBCwUAMIGNMQswCQYDVQQGEwJERTFFMEMGA1UECgw8VmVyZWluIHp1ciBGb2VyZGVydW5nIGVp
bmVzIERldXRzY2hlbiBGb3JzY2h1bmdzbmV0emVzIGUuIFYuMRAwDgYDVQQLDAdERk4tUEtJMSUw
IwYDVQQDDBxERk4tVmVyZWluIEdsb2JhbCBJc3N1aW5nIENBMB4XDTE5MDYwNDE0MjkxMFoXDTIy
MDYwMzE0MjkxMFowfDELMAkGA1UEBhMCREUxIDAeBgNVBAoMF0ZhY2hob2Noc2NodWxlIE11ZW5z
dGVyMTIwMAYDVQQLDClGYWNoYmVyZWljaCBFbGVrdHJvdGVjaG5payB1bmQgSW5mb3JtYXRpazEX
MBUGA1UEAwwOTWljaGFlbCBUdWV4ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDM
r8qQcPxLFCxzPtXvRyM9KeQaxyMA8gwUNc7IIiATs6mRQFe5ib/mvwT9nc0bAa+94go6HJDiD3FJ
NkTo4u8aBsIcTt5pJtdBQLm88PLakbe3+fp/00//n7xxbTh7mAtFVCf25LxDCKkrdGk/+jglRq/R
VdwhZZ3VpYCrx8YfI/hIzdRL3+4I4z/mnQ8K0X8d2MVVPG+9nBEngdnYGez5f/8wIVOgEYYBc21k
yvMnVXLu2Ing+LwBd0gDG9Vasv87MNHCOZfJTNBlLhI2UDei/uNg9Zd4ynlMpPWZ7v0oiDWvmv8E
OuD4oric8heyD0OYK2FL4qcVC4dn4pnyulfHAgMBAAGjggJOMIICSjA+BgNVHSAENzA1MA8GDSsG
AQQBga0hgiwBAQQwEAYOKwYBBAGBrSGCLAEBBAQwEAYOKwYBBAGBrSGCLAIBBAQwCQYDVR0TBAIw
ADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQW
BBTxiodBVL/lA4p5iNesIsJRhhgd6zAfBgNVHSMEGDAWgBRrOpiL+fJTidrgrbIyHgkf6Ko7dDAg
BgNVHREEGTAXgRV0dWV4ZW5AZmgtbXVlbnN0ZXIuZGUwgY0GA1UdHwSBhTCBgjA/oD2gO4Y5aHR0
cDovL2NkcDEucGNhLmRmbi5kZS9kZm4tY2EtZ2xvYmFsLWcyL3B1Yi9jcmwvY2FjcmwuY3JsMD+g
PaA7hjlodHRwOi8vY2RwMi5wY2EuZGZuLmRlL2Rmbi1jYS1nbG9iYWwtZzIvcHViL2NybC9jYWNy
bC5jcmwwgdsGCCsGAQUFBwEBBIHOMIHLMDMGCCsGAQUFBzABhidodHRwOi8vb2NzcC5wY2EuZGZu
LmRlL09DU1AtU2VydmVyL09DU1AwSQYIKwYBBQUHMAKGPWh0dHA6Ly9jZHAxLnBjYS5kZm4uZGUv
ZGZuLWNhLWdsb2JhbC1nMi9wdWIvY2FjZXJ0L2NhY2VydC5jcnQwSQYIKwYBBQUHMAKGPWh0dHA6
Ly9jZHAyLnBjYS5kZm4uZGUvZGZuLWNhLWdsb2JhbC1nMi9wdWIvY2FjZXJ0L2NhY2VydC5jcnQw
DQYJKoZIhvcNAQELBQADggEBABs3VlmIZ1VF3HkaQdjInZYmamRabbdgJ7cz6m6o/agKL7+Vhwx7
1BaaYs2gMa5Nu/GJ3YfdqIsUlYtKdl58Yhp/89E6xBfJkItS+rE8RFdf2XgklGlx7GmsvdA3tId5
b6K6r9a5wpVN0epxY6K8wwpzEib6fJLcHylybQXZ7JSOaLRLp6WU3QPoyTT7FpvAe/0b2MSCbPX4
fc53PCn2aGgXuRFVQeCn1SP1BF3QW1ppkFhcF6G+0JcUxYFAXE6r/71WZBvUHqoG/th2hAwQnS+Y
KhUYh4SZQH3/ursXXJYXQ5vyIhkN1FZlmtWA8+ofdCnoqSTbiSX2Aa/kKbTapwgxggOdMIIDmQIB
ATCBnjCBjTELMAkGA1UEBhMCREUxRTBDBgNVBAoMPFZlcmVpbiB6dXIgRm9lcmRlcnVuZyBlaW5l
cyBEZXV0c2NoZW4gRm9yc2NodW5nc25ldHplcyBlLiBWLjEQMA4GA1UECwwHREZOLVBLSTElMCMG
A1UEAwwcREZOLVZlcmVpbiBHbG9iYWwgSXNzdWluZyBDQQIMIRX9tDE2QqO3mVLXMA0GCWCGSAFl
AwQCAQUAoIIBzzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMDA2
MDEyMTI4MzdaMC8GCSqGSIb3DQEJBDEiBCBt/7DmNUKJSYh37BAjjsbqUU9T+bIsUAAKgixeA62n
7zCBrwYJKwYBBAGCNxAEMYGhMIGeMIGNMQswCQYDVQQGEwJERTFFMEMGA1UECgw8VmVyZWluIHp1
ciBGb2VyZGVydW5nIGVpbmVzIERldXRzY2hlbiBGb3JzY2h1bmdzbmV0emVzIGUuIFYuMRAwDgYD
VQQLDAdERk4tUEtJMSUwIwYDVQQDDBxERk4tVmVyZWluIEdsb2JhbCBJc3N1aW5nIENBAgwhFf20
MTZCo7eZUtcwgbEGCyqGSIb3DQEJEAILMYGhoIGeMIGNMQswCQYDVQQGEwJERTFFMEMGA1UECgw8
VmVyZWluIHp1ciBGb2VyZGVydW5nIGVpbmVzIERldXRzY2hlbiBGb3JzY2h1bmdzbmV0emVzIGUu
IFYuMRAwDgYDVQQLDAdERk4tUEtJMSUwIwYDVQQDDBxERk4tVmVyZWluIEdsb2JhbCBJc3N1aW5n
IENBAgwhFf20MTZCo7eZUtcwDQYJKoZIhvcNAQEBBQAEggEAkNIWT8GHSJfXRHow5elvf6cFE7v5
VAsB5bH5Zpd0FG+el2t1DBCOFwKNBHVc2/GiFnNTB55k9wf4L5lnUMtCHA1oZlCI7KSaoKG+4oMN
/m0UooEeSXqXIDzxOsNAuxQNCuEYobHENxPoDzQw7NVHOc9rVjbZBVM1xYMFgExTVqWwW32Z1M1l
LlngTRlW1wUB4Ambiqi4srrcmiUloVyg0wOuY3bK7Tw8E9ZOHgMh9muqZMc1LGyRqMs7y/LcOvd/
9FoSFekLNDtoTpc/nENS5TsB37MIcMNpQFLEm2UVhafIdt8S+9Vbm6FkaOeuyrqnxD8XHfrqbsYk
Y+KQxYEA3QAAAAAAAA==
--Apple-Mail=_30A6D176-B5FA-4F13-A949-3CE33C73C3B8--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6FE2C649-2D81-4C9C-B821-D8226B6BB95C>