Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Dec 2020 11:26:41 +0100
From:      Mateusz Guzik <mjguzik@gmail.com>
To:        "Alexander V. Chernikov" <melifaro@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r368571 - head/sys/netpfil/ipfw
Message-ID:  <CAGudoHF_cgoDF574EFWntSLRdAiXOvORe6LE0o0uYFnOeA7rAA@mail.gmail.com>
In-Reply-To: <202012112357.0BBNvUn0069609@repo.freebsd.org>
References:  <202012112357.0BBNvUn0069609@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
This breaks LINT-NOINET6:

linking kernel
ld: error: undefined symbol: fib6_lookup_rt
>>> referenced by ip_fw_table_algo.c
>>>               ip_fw_table_algo.o:(ta_find_kfib_tentry)
>>> did you mean: fib4_lookup_rt


On 12/12/20, Alexander V. Chernikov <melifaro@freebsd.org> wrote:
> Author: melifaro
> Date: Fri Dec 11 23:57:30 2020
> New Revision: 368571
> URL: https://svnweb.freebsd.org/changeset/base/368571
>
> Log:
>   ipfw kfib algo: Use rt accessors instead of accessing rib/rtentry
> directly.
>
>   This removes assumptions on prefix storage and rtentry layout
>    from an external code.
>
>   Differential Revision:	https://reviews.freebsd.org/D27450
>
> Modified:
>   head/sys/netpfil/ipfw/ip_fw_table_algo.c
>
> Modified: head/sys/netpfil/ipfw/ip_fw_table_algo.c
> ==============================================================================
> --- head/sys/netpfil/ipfw/ip_fw_table_algo.c	Fri Dec 11 22:52:20
> 2020	(r368570)
> +++ head/sys/netpfil/ipfw/ip_fw_table_algo.c	Fri Dec 11 23:57:30
> 2020	(r368571)
> @@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$");
>  #include <net/radix.h>
>  #include <net/route.h>
>  #include <net/route/nhop.h>
> -#include <net/route/route_var.h>
> +#include <net/route/route_ctl.h>
>
>  #include <netinet/in.h>
>  #include <netinet/in_fib.h>
> @@ -3781,11 +3781,10 @@ static int ta_init_kfib(struct ip_fw_chain *ch, void
> *
>  static void ta_destroy_kfib(void *ta_state, struct table_info *ti);
>  static void ta_dump_kfib_tinfo(void *ta_state, struct table_info *ti,
>      ipfw_ta_tinfo *tinfo);
> -static int contigmask(uint8_t *p, int len);
>  static int ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void
> *e,
>      ipfw_obj_tentry *tent);
> -static int ta_dump_kfib_tentry_int(struct sockaddr *paddr,
> -    struct sockaddr *pmask, ipfw_obj_tentry *tent);
> +static int ta_dump_kfib_tentry_int(int familt, const struct rtentry *rt,
> +    ipfw_obj_tentry *tent);
>  static int ta_find_kfib_tentry(void *ta_state, struct table_info *ti,
>      ipfw_obj_tentry *tent);
>  static void ta_foreach_kfib(void *ta_state, struct table_info *ti,
> @@ -3900,84 +3899,35 @@ ta_dump_kfib_tinfo(void *ta_state, struct table_info
> *
>  	tinfo->flags = IPFW_TATFLAGS_AFDATA;
>  	tinfo->taclass4 = IPFW_TACLASS_RADIX;
>  	tinfo->count4 = 0;
> -	tinfo->itemsize4 = sizeof(struct rtentry);
> +	tinfo->itemsize4 = 128; /* table is readonly, value does not matter */
>  	tinfo->taclass6 = IPFW_TACLASS_RADIX;
>  	tinfo->count6 = 0;
> -	tinfo->itemsize6 = sizeof(struct rtentry);
> +	tinfo->itemsize6 = 128;
>  }
>
>  static int
> -contigmask(uint8_t *p, int len)
> -{
> -	int i, n;
> -
> -	for (i = 0; i < len ; i++)
> -		if ( (p[i/8] & (1 << (7 - (i%8)))) == 0) /* first bit unset */
> -			break;
> -	for (n= i + 1; n < len; n++)
> -		if ( (p[n/8] & (1 << (7 - (n % 8)))) != 0)
> -			return (-1); /* mask not contiguous */
> -	return (i);
> -}
> -
> -static int
> -ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
> +ta_dump_kfib_tentry_int(int family, const struct rtentry *rt,
>      ipfw_obj_tentry *tent)
>  {
> -	struct rtentry *rte;
> +	uint32_t scopeid;
> +	int plen;
>
> -	rte = (struct rtentry *)e;
> -
> -	return ta_dump_kfib_tentry_int(rt_key(rte), rt_mask(rte), tent);
> -}
> -
> -static int
> -ta_dump_kfib_tentry_int(struct sockaddr *paddr, struct sockaddr *pmask,
> -    ipfw_obj_tentry *tent)
> -{
>  #ifdef INET
> -	struct sockaddr_in *addr, *mask;
> -#endif
> -#ifdef INET6
> -	struct sockaddr_in6 *addr6, *mask6;
> -#endif
> -	int len;
> -
> -	len = 0;
> -
> -	/* Guess IPv4/IPv6 radix by sockaddr family */
> -#ifdef INET
> -	if (paddr->sa_family == AF_INET) {
> -		addr = (struct sockaddr_in *)paddr;
> -		mask = (struct sockaddr_in *)pmask;
> -		tent->k.addr.s_addr = addr->sin_addr.s_addr;
> -		len = 32;
> -		if (mask != NULL)
> -			len = contigmask((uint8_t *)&mask->sin_addr, 32);
> -		if (len == -1)
> -			len = 0;
> -		tent->masklen = len;
> +	if (family == AF_INET) {
> +		rt_get_inet_prefix_plen(rt, &tent->k.addr, &plen, &scopeid);
> +		tent->masklen = plen;
>  		tent->subtype = AF_INET;
> -		tent->v.kidx = 0; /* Do we need to put GW here? */
> +		tent->v.kidx = 0;
>  	}
>  #endif
> -#ifdef INET6
> -	if (paddr->sa_family == AF_INET6) {
> -		addr6 = (struct sockaddr_in6 *)paddr;
> -		mask6 = (struct sockaddr_in6 *)pmask;
> -		memcpy(&tent->k.addr6, &addr6->sin6_addr,
> -		    sizeof(struct in6_addr));
> -		len = 128;
> -		if (mask6 != NULL)
> -			len = contigmask((uint8_t *)&mask6->sin6_addr, 128);
> -		if (len == -1)
> -			len = 0;
> -		tent->masklen = len;
> +#ifdef INET
> +	if (family == AF_INET6) {
> +		rt_get_inet6_prefix_plen(rt, &tent->k.addr6, &plen, &scopeid);
> +		tent->masklen = plen;
>  		tent->subtype = AF_INET6;
>  		tent->v.kidx = 0;
>  	}
>  #endif
> -
>  	return (0);
>  }
>
> @@ -3985,66 +3935,61 @@ static int
>  ta_find_kfib_tentry(void *ta_state, struct table_info *ti,
>      ipfw_obj_tentry *tent)
>  {
> -	struct rt_addrinfo info;
> -	struct sockaddr_in6 key6, dst6, mask6;
> -	struct sockaddr *dst, *key, *mask;
> +	struct rtentry *rt;
> +	struct route_nhop_data rnd;
> +	struct epoch_tracker et;
> +	int error;
>
> -	/* Prepare sockaddr for prefix/mask and info */
> -	bzero(&dst6, sizeof(dst6));
> -	dst6.sin6_len = sizeof(dst6);
> -	dst = (struct sockaddr *)&dst6;
> -	bzero(&mask6, sizeof(mask6));
> -	mask6.sin6_len = sizeof(mask6);
> -	mask = (struct sockaddr *)&mask6;
> -
> -	bzero(&info, sizeof(info));
> -	info.rti_info[RTAX_DST] = dst;
> -	info.rti_info[RTAX_NETMASK] = mask;
> -
> -	/* Prepare the lookup key */
> -	bzero(&key6, sizeof(key6));
> -	key6.sin6_family = tent->subtype;
> -	key = (struct sockaddr *)&key6;
> -
> +	NET_EPOCH_ENTER(et);
>  	if (tent->subtype == AF_INET) {
> -		((struct sockaddr_in *)&key6)->sin_addr = tent->k.addr;
> -		key6.sin6_len = sizeof(struct sockaddr_in);
> +		rt = fib4_lookup_rt(ti->data, tent->k.addr, 0, 0, &rnd);
>  	} else {
> -		key6.sin6_addr = tent->k.addr6;
> -		key6.sin6_len = sizeof(struct sockaddr_in6);
> +		rt = fib6_lookup_rt(ti->data, &tent->k.addr6, 0, 0, &rnd);
>  	}
> +	if (rt != NULL)
> +		error = ta_dump_kfib_tentry_int(tent->subtype, rt, tent);
> +	else
> +		error = ENOENT;
> +	NET_EPOCH_EXIT(et);
>
> -	if (rib_lookup_info(ti->data, key, 0, 0, &info) != 0)
> -		return (ENOENT);
> -	if ((info.rti_addrs & RTA_NETMASK) == 0)
> -		mask = NULL;
> +	return (error);
> +}
>
> -	ta_dump_kfib_tentry_int(dst, mask, tent);
> +struct kfib_dump_arg {
> +	struct rtentry *rt;
> +	int		family;
> +	ta_foreach_f	*f;
> +	void		*arg;
> +};
>
> -	return (0);
> +static int
> +ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
> +    ipfw_obj_tentry *tent)
> +{
> +	struct kfib_dump_arg *karg = (struct kfib_dump_arg *)e;
> +
> +	return (ta_dump_kfib_tentry_int(karg->family, karg->rt, tent));
>  }
>
> +static int
> +walk_wrapper_f(struct rtentry *rt, void *arg)
> +{
> +	struct kfib_dump_arg *karg = (struct kfib_dump_arg *)arg;
> +
> +	karg->rt = rt;
> +	return (karg->f(karg, karg->arg));
> +}
> +
>  static void
>  ta_foreach_kfib(void *ta_state, struct table_info *ti, ta_foreach_f *f,
>      void *arg)
>  {
> -	RIB_RLOCK_TRACKER;
> -	struct rib_head *rh;
> -	int error;
> +	struct kfib_dump_arg karg = { .f = f, .arg = arg };
>
> -	rh = rt_tables_get_rnh(ti->data, AF_INET);
> -	if (rh != NULL) {
> -		RIB_RLOCK(rh);
> -		error = rh->rnh_walktree(&rh->head, (walktree_f_t *)f, arg);
> -		RIB_RUNLOCK(rh);
> -	}
> -
> -	rh = rt_tables_get_rnh(ti->data, AF_INET6);
> -	if (rh != NULL) {
> -		RIB_RLOCK(rh);
> -		error = rh->rnh_walktree(&rh->head, (walktree_f_t *)f, arg);
> -		RIB_RUNLOCK(rh);
> -	}
> +	karg.family = AF_INET;
> +	rib_walk(ti->data, AF_INET, false, walk_wrapper_f, &karg);
> +	karg.family = AF_INET6;
> +	rib_walk(ti->data, AF_INET6, false, walk_wrapper_f, &karg);
>  }
>
>  struct table_algo addr_kfib = {
> _______________________________________________
> svn-src-all@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
>


-- 
Mateusz Guzik <mjguzik gmail.com>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGudoHF_cgoDF574EFWntSLRdAiXOvORe6LE0o0uYFnOeA7rAA>