svn commit: r368317 - head/sys/net/route
Alexander V. Chernikov
melifaro at FreeBSD.org
Thu Dec 3 22:23:58 UTC 2020
Author: melifaro
Date: Thu Dec 3 22:23:57 2020
New Revision: 368317
URL: https://svnweb.freebsd.org/changeset/base/368317
Log:
Add IPv4/IPv6 rtentry prefix accessors.
Multiple consumers like ipfw, netflow or new route lookup algorithms
need to get the prefix data out of struct rtentry.
Instead of providing direct access to the rtentry, create IPv4/IPv6
accessors to abstract struct rtentry internals and avoid including
internal routing headers for external consumers.
While here, move struct route_nhop_data to the public header, so external
customers can actually use lookup functions returning rt&nhop data.
Differential Revision: https://reviews.freebsd.org/D27416
Modified:
head/sys/net/route/route_ctl.c
head/sys/net/route/route_ctl.h
head/sys/net/route/route_var.h
Modified: head/sys/net/route/route_ctl.c
==============================================================================
--- head/sys/net/route/route_ctl.c Thu Dec 3 22:06:08 2020 (r368316)
+++ head/sys/net/route/route_ctl.c Thu Dec 3 22:23:57 2020 (r368317)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <net/route/nhop.h>
#include <net/route/nhop_var.h>
#include <netinet/in.h>
+#include <netinet6/scope6_var.h>
#include <vm/uma.h>
@@ -235,6 +236,132 @@ get_info_weight(const struct rt_addrinfo *info, uint32
return (weight);
}
+
+bool
+rt_is_host(const struct rtentry *rt)
+{
+
+ return (rt->rte_flags & RTF_HOST);
+}
+
+/*
+ * Returns pointer to nexthop or nexthop group
+ * associated with @rt
+ */
+struct nhop_object *
+rt_get_raw_nhop(const struct rtentry *rt)
+{
+
+ return (rt->rt_nhop);
+}
+
+#ifdef INET
+/*
+ * Stores IPv4 address and prefix length of @rt inside
+ * @paddr and @plen.
+ * @pscopeid is currently always set to 0.
+ */
+void
+rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr,
+ int *plen, uint32_t *pscopeid)
+{
+ const struct sockaddr_in *dst;
+
+ dst = (const struct sockaddr_in *)rt_key_const(rt);
+ KASSERT((dst->sin_family == AF_INET),
+ ("rt family is %d, not inet", dst->sin_family));
+ *paddr = dst->sin_addr;
+ dst = (const struct sockaddr_in *)rt_mask_const(rt);
+ if (dst == NULL)
+ *plen = 32;
+ else
+ *plen = bitcount32(dst->sin_addr.s_addr);
+ *pscopeid = 0;
+}
+
+/*
+ * Stores IPv4 address and prefix mask of @rt inside
+ * @paddr and @pmask. Sets mask to INADDR_ANY for host routes.
+ * @pscopeid is currently always set to 0.
+ */
+void
+rt_get_inet_prefix_pmask(const struct rtentry *rt, struct in_addr *paddr,
+ struct in_addr *pmask, uint32_t *pscopeid)
+{
+ const struct sockaddr_in *dst;
+
+ dst = (const struct sockaddr_in *)rt_key_const(rt);
+ KASSERT((dst->sin_family == AF_INET),
+ ("rt family is %d, not inet", dst->sin_family));
+ *paddr = dst->sin_addr;
+ dst = (const struct sockaddr_in *)rt_mask_const(rt);
+ if (dst == NULL)
+ pmask->s_addr = INADDR_BROADCAST;
+ else
+ *pmask = dst->sin_addr;
+ *pscopeid = 0;
+}
+#endif
+
+#ifdef INET6
+static int
+inet6_get_plen(const struct in6_addr *addr)
+{
+
+ return (bitcount32(addr->s6_addr32[0]) + bitcount32(addr->s6_addr32[1]) +
+ bitcount32(addr->s6_addr32[2]) + bitcount32(addr->s6_addr32[3]));
+}
+
+/*
+ * Stores IPv6 address and prefix length of @rt inside
+ * @paddr and @plen. Addresses are returned in de-embedded form.
+ * Scopeid is set to 0 for non-LL addresses.
+ */
+void
+rt_get_inet6_prefix_plen(const struct rtentry *rt, struct in6_addr *paddr,
+ int *plen, uint32_t *pscopeid)
+{
+ const struct sockaddr_in6 *dst;
+
+ dst = (const struct sockaddr_in6 *)rt_key_const(rt);
+ KASSERT((dst->sin6_family == AF_INET6),
+ ("rt family is %d, not inet6", dst->sin6_family));
+ if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr))
+ in6_splitscope(&dst->sin6_addr, paddr, pscopeid);
+ else
+ *paddr = dst->sin6_addr;
+ dst = (const struct sockaddr_in6 *)rt_mask_const(rt);
+ if (dst == NULL)
+ *plen = 128;
+ else
+ *plen = inet6_get_plen(&dst->sin6_addr);
+}
+
+/*
+ * Stores IPv6 address and prefix mask of @rt inside
+ * @paddr and @pmask. Addresses are returned in de-embedded form.
+ * Scopeid is set to 0 for non-LL addresses.
+ */
+void
+rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr,
+ struct in6_addr *pmask, uint32_t *pscopeid)
+{
+ const struct sockaddr_in6 *dst;
+
+ dst = (const struct sockaddr_in6 *)rt_key_const(rt);
+ KASSERT((dst->sin6_family == AF_INET6),
+ ("rt family is %d, not inet", dst->sin6_family));
+ if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr))
+ in6_splitscope(&dst->sin6_addr, paddr, pscopeid);
+ else
+ *paddr = dst->sin6_addr;
+ dst = (const struct sockaddr_in6 *)rt_mask_const(rt);
+ if (dst == NULL)
+ memset(pmask, 0xFF, sizeof(struct in6_addr));
+ else
+ *pmask = dst->sin6_addr;
+}
+#endif
static void
rt_set_expire_info(struct rtentry *rt, const struct rt_addrinfo *info)
Modified: head/sys/net/route/route_ctl.h
==============================================================================
--- head/sys/net/route/route_ctl.h Thu Dec 3 22:06:08 2020 (r368316)
+++ head/sys/net/route/route_ctl.h Thu Dec 3 22:23:57 2020 (r368317)
@@ -82,18 +82,44 @@ void rib_foreach_table_walk(int family, bool wlock, ri
rib_walk_hook_f_t *hook_f, void *arg);
void rib_foreach_table_walk_del(int family, rib_filter_f_t *filter_f, void *arg);
-struct route_nhop_data;
+struct nhop_object;
+struct nhgrp_object;
+struct route_nhop_data {
+ union {
+ struct nhop_object *rnd_nhop;
+ struct nhgrp_object *rnd_nhgrp;
+ };
+ uint32_t rnd_weight;
+};
+
const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family,
const struct sockaddr *dst, const struct sockaddr *netmask,
struct route_nhop_data *rnd);
const struct rtentry *rib_lookup_lpm(uint32_t fibnum, int family,
const struct sockaddr *dst, struct route_nhop_data *rnd);
+/* rtentry accessors */
+bool rt_is_host(const struct rtentry *rt);
+struct nhop_object *rt_get_raw_nhop(const struct rtentry *rt);
+#ifdef INET
+struct in_addr;
+void rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr,
+ int *plen, uint32_t *pscopeid);
+void rt_get_inet_prefix_pmask(const struct rtentry *rt, struct in_addr *paddr,
+ struct in_addr *pmask, uint32_t *pscopeid);
+#endif
+#ifdef INET6
+struct in6_addr;
+void rt_get_inet6_prefix_plen(const struct rtentry *rt, struct in6_addr *paddr,
+ int *plen, uint32_t *pscopeid);
+void rt_get_inet6_prefix_pmask(const struct rtentry *rt, struct in6_addr *paddr,
+ struct in6_addr *pmask, uint32_t *pscopeid);
+#endif
+
/* Nexthops */
uint32_t nhops_get_count(struct rib_head *rh);
/* Multipath */
-struct nhgrp_object;
struct weightened_nhop;
struct weightened_nhop *nhgrp_get_nhops(struct nhgrp_object *nhg,
Modified: head/sys/net/route/route_var.h
==============================================================================
--- head/sys/net/route/route_var.h Thu Dec 3 22:06:08 2020 (r368316)
+++ head/sys/net/route/route_var.h Thu Dec 3 22:23:57 2020 (r368317)
@@ -205,14 +205,7 @@ void tmproutes_init(struct rib_head *rh);
void tmproutes_destroy(struct rib_head *rh);
/* route_ctl.c */
-struct route_nhop_data {
- union {
- struct nhop_object *rnd_nhop;
- struct nhgrp_object *rnd_nhgrp;
- };
- uint32_t rnd_weight;
-};
-
+struct route_nhop_data;
int change_route_nhop(struct rib_head *rnh, struct rtentry *rt,
struct rt_addrinfo *info, struct route_nhop_data *rnd,
struct rib_cmd_info *rc);
More information about the svn-src-head
mailing list