diff --git a/sys/net/route.h b/sys/net/route.h --- a/sys/net/route.h +++ b/sys/net/route.h @@ -29,54 +29,11 @@ * SUCH DAMAGE. * * @(#)route.h 8.4 (Berkeley) 1/9/95 - * $FreeBSD$ */ #ifndef _NET_ROUTE_H_ #define _NET_ROUTE_H_ -#include - -/* - * Kernel resident routing tables. - * - * The routing tables are initialized when interface addresses - * are set by making entries for all directly connected interfaces. - */ - -/* - * Struct route consiste of a destination address, - * a route entry pointer, link-layer prepend data pointer along - * with its length. - */ -struct route { - struct nhop_object *ro_nh; - struct llentry *ro_lle; - /* - * ro_prepend and ro_plen are only used for bpf to pass in a - * preformed header. They are not cacheable. - */ - char *ro_prepend; - uint16_t ro_plen; - uint16_t ro_flags; - uint16_t ro_mtu; /* saved ro_rt mtu */ - uint16_t spare; - struct sockaddr ro_dst; -}; - -#define RT_L2_ME_BIT 2 /* dst L2 addr is our address */ -#define RT_MAY_LOOP_BIT 3 /* dst may require loop copy */ -#define RT_HAS_HEADER_BIT 4 /* mbuf already have its header prepended */ - -#define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */ -#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */ -#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */ - -#define RT_REJECT 0x0020 /* Destination is reject */ -#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */ -#define RT_HAS_GW 0x0080 /* Destination has GW */ -#define RT_LLE_CACHE 0x0100 /* Cache link layer */ - struct rt_metrics { u_long rmx_locks; /* Kernel must leave these values alone */ u_long rmx_mtu; /* MTU for this path */ @@ -105,58 +62,8 @@ #define RT_DEFAULT_WEIGHT 1 #define RT_MAX_WEIGHT 16777215 /* 3 bytes */ -/* - * Keep a generation count of routing table, incremented on route addition, - * so we can invalidate caches. This is accessed without a lock, as precision - * is not required. - */ -typedef volatile u_int rt_gen_t; /* tree generation (for adds) */ -#define RT_GEN(fibnum, af) rt_tables_get_gen(fibnum, af) - #define RT_DEFAULT_FIB 0 /* Explicitly mark fib=0 restricted cases */ #define RT_ALL_FIBS -1 /* Announce event for every fib */ -#ifdef _KERNEL -VNET_DECLARE(uint32_t, _rt_numfibs); /* number of existing route tables */ -#define V_rt_numfibs VNET(_rt_numfibs) -/* temporary compat arg */ -#define rt_numfibs V_rt_numfibs -VNET_DECLARE(u_int, rt_add_addr_allfibs); /* Announce interfaces to all fibs */ -#define V_rt_add_addr_allfibs VNET(rt_add_addr_allfibs) - -/* Calculate flowid for locally-originated packets */ -#define V_fib_hash_outbound VNET(fib_hash_outbound) -VNET_DECLARE(u_int, fib_hash_outbound); - -/* Outbound flowid generation rules */ -#ifdef RSS - -#define fib4_calc_packet_hash xps_proto_software_hash_v4 -#define fib6_calc_packet_hash xps_proto_software_hash_v6 -#define CALC_FLOWID_OUTBOUND_SENDTO true - -#ifdef ROUTE_MPATH -#define CALC_FLOWID_OUTBOUND V_fib_hash_outbound -#else -#define CALC_FLOWID_OUTBOUND false -#endif - -#else /* !RSS */ - -#define fib4_calc_packet_hash fib4_calc_software_hash -#define fib6_calc_packet_hash fib6_calc_software_hash - -#ifdef ROUTE_MPATH -#define CALC_FLOWID_OUTBOUND_SENDTO V_fib_hash_outbound -#define CALC_FLOWID_OUTBOUND V_fib_hash_outbound -#else -#define CALC_FLOWID_OUTBOUND_SENDTO false -#define CALC_FLOWID_OUTBOUND false -#endif - -#endif /* RSS */ - - -#endif /* _KERNEL */ /* * We distinguish between routes to hosts and routes to networks, @@ -204,29 +111,6 @@ (RTF_PROTO1 | RTF_PROTO2 | RTF_PROTO3 | RTF_BLACKHOLE | \ RTF_REJECT | RTF_STATIC | RTF_STICKY) -/* - * fib_ nexthop API flags. - */ - -/* Consumer-visible nexthop info flags */ -#define NHF_MULTIPATH 0x0008 /* Nexhop is a nexthop group */ -#define NHF_REJECT 0x0010 /* RTF_REJECT */ -#define NHF_BLACKHOLE 0x0020 /* RTF_BLACKHOLE */ -#define NHF_REDIRECT 0x0040 /* RTF_DYNAMIC|RTF_MODIFIED */ -#define NHF_DEFAULT 0x0080 /* Default route */ -#define NHF_BROADCAST 0x0100 /* RTF_BROADCAST */ -#define NHF_GATEWAY 0x0200 /* RTF_GATEWAY */ -#define NHF_HOST 0x0400 /* RTF_HOST */ - -/* Nexthop request flags */ -#define NHR_NONE 0x00 /* empty flags field */ -#define NHR_REF 0x01 /* reference nexhop */ -#define NHR_NODEFAULT 0x02 /* uRPF: do not consider default route */ - -/* Control plane route request flags */ -#define NHR_COPY 0x100 /* Copy rte data */ -#define NHR_UNLOCKED 0x200 /* Do not lock table */ - /* * Routing statistics. */ @@ -335,24 +219,6 @@ #define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */ #define RTAX_MAX 8 /* size of array to allocate */ -struct rtentry; -struct nhop_object; -typedef int rib_filter_f_t(const struct rtentry *, const struct nhop_object *, - void *); - -struct rt_addrinfo { - int rti_addrs; /* Route RTF_ flags */ - int rti_flags; /* Route RTF_ flags */ - struct sockaddr *rti_info[RTAX_MAX]; /* Sockaddr data */ - struct ifaddr *rti_ifa; /* value of rt_ifa addr */ - struct ifnet *rti_ifp; /* route interface */ - rib_filter_f_t *rti_filter; /* filter function */ - void *rti_filterdata; /* filter parameters */ - u_long rti_mflags; /* metrics RTV_ flags */ - u_long rti_spare; /* Will be used for fib */ - struct rt_metrics *rti_rmx; /* Pointer to route metrics */ -}; - /* * This macro returns the size of a struct sockaddr when passed * through a routing socket. Basically we round up sa_len to @@ -370,46 +236,14 @@ #ifdef _KERNEL -#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \ - || (ifp)->if_link_state == LINK_STATE_UP) - -#define RO_NHFREE(_ro) do { \ - if ((_ro)->ro_nh) { \ - NH_FREE((_ro)->ro_nh); \ - (_ro)->ro_nh = NULL; \ - } \ -} while (0) - -#define RO_INVALIDATE_CACHE(ro) do { \ - if ((ro)->ro_lle != NULL) { \ - LLE_FREE((ro)->ro_lle); \ - (ro)->ro_lle = NULL; \ - } \ - if ((ro)->ro_nh != NULL) { \ - NH_FREE((ro)->ro_nh); \ - (ro)->ro_nh = NULL; \ - } \ - } while (0) - -#define RO_GET_FAMILY(ro, dst) ((ro) != NULL && \ - (ro)->ro_flags & RT_HAS_GW \ - ? (ro)->ro_dst.sa_family : (dst)->sa_family) - -/* - * Validate a cached route based on a supplied cookie. If there is an - * out-of-date cache, simply free it. Update the generation number - * for the new allocation - */ -#define NH_VALIDATE(ro, cookiep, fibnum) do { \ - rt_gen_t cookie = RT_GEN(fibnum, (ro)->ro_dst.sa_family); \ - if (*(cookiep) != cookie) { \ - RO_INVALIDATE_CACHE(ro); \ - *(cookiep) = cookie; \ - } \ -} while (0) +#include struct ifmultiaddr; struct rib_head; +struct rt_addrinfo; +struct rtentry; +struct ifnet; +struct nhop_object; void rt_ieee80211msg(struct ifnet *, int, void *, size_t); void rt_ifmsg(struct ifnet *, int); @@ -438,11 +272,7 @@ */ int rtioctl_fib(u_long, caddr_t, u_int); -/* New API */ -void rib_flush_routes_family(int family); -struct nhop_object *rib_lookup(uint32_t fibnum, const struct sockaddr *dst, - uint32_t flags, uint32_t flowid); -const char *rib_print_family(int family); -#endif + +#endif /* _KERNEL */ #endif diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h --- a/sys/net/route/nhop.h +++ b/sys/net/route/nhop.h @@ -145,6 +145,26 @@ /* -- 128 bytes -- */ }; +/* Consumer-visible nexthop info flags */ +#define NHF_MULTIPATH 0x0008 /* Nexhop is a nexthop group */ +#define NHF_REJECT 0x0010 /* RTF_REJECT */ +#define NHF_BLACKHOLE 0x0020 /* RTF_BLACKHOLE */ +#define NHF_REDIRECT 0x0040 /* RTF_DYNAMIC|RTF_MODIFIED */ +#define NHF_DEFAULT 0x0080 /* Default route */ +#define NHF_BROADCAST 0x0100 /* RTF_BROADCAST */ +#define NHF_GATEWAY 0x0200 /* RTF_GATEWAY */ +#define NHF_HOST 0x0400 /* RTF_HOST */ + +/* Nexthop request flags */ +#define NHR_NONE 0x00 /* empty flags field */ +#define NHR_REF 0x01 /* reference nexhop */ +#define NHR_NODEFAULT 0x02 /* uRPF: do not consider default route */ + +/* Control plane route request flags */ +#define NHR_COPY 0x100 /* Copy rte data */ +#define NHR_UNLOCKED 0x200 /* Do not lock table */ + + /* * Nhop validness. * diff --git a/sys/net/route/nhop.c b/sys/net/route/nhop.c --- a/sys/net/route/nhop.c +++ b/sys/net/route/nhop.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h --- a/sys/net/route/route_ctl.h +++ b/sys/net/route/route_ctl.h @@ -35,6 +35,10 @@ #ifndef _NET_ROUTE_ROUTE_CTL_H_ #define _NET_ROUTE_ROUTE_CTL_H_ +VNET_DECLARE(u_int, rt_add_addr_allfibs); /* Announce interfaces to all fibs */ +#define V_rt_add_addr_allfibs VNET(rt_add_addr_allfibs) + + struct rib_cmd_info { uint8_t rc_cmd; /* RTM_ADD|RTM_DEL|RTM_CHANGE */ uint8_t spare[3]; @@ -52,6 +56,9 @@ uint32_t rnd_weight; }; + +typedef int rib_filter_f_t(const struct rtentry *rt, const struct nhop_object *nh, + void *arg); int rib_add_route_px(uint32_t fibnum, struct sockaddr *dst, int plen, struct route_nhop_data *rnd, int op_flags, struct rib_cmd_info *rc); int rib_del_route_px(uint32_t fibnum, struct sockaddr *dst, int plen, @@ -67,6 +74,19 @@ #define RTM_F_APPEND 0x08 #define RTM_F_FORCE 0x10 +struct rt_addrinfo { + int rti_addrs; /* Route RTF_ flags */ + int rti_flags; /* Route RTF_ flags */ + struct sockaddr *rti_info[RTAX_MAX]; /* Sockaddr data */ + struct ifaddr *rti_ifa; /* value of rt_ifa addr */ + struct ifnet *rti_ifp; /* route interface */ + rib_filter_f_t *rti_filter; /* filter function */ + void *rti_filterdata; /* filter parameters */ + u_long rti_mflags; /* metrics RTV_ flags */ + u_long rti_spare; /* Will be used for fib */ + struct rt_metrics *rti_rmx; /* Pointer to route metrics */ +}; + int rib_add_route(uint32_t fibnum, struct rt_addrinfo *info, struct rib_cmd_info *rc); int rib_del_route(uint32_t fibnum, struct rt_addrinfo *info, @@ -82,6 +102,11 @@ int rib_add_default_route(uint32_t fibnum, int family, struct ifnet *ifp, struct sockaddr *gw, struct rib_cmd_info *rc); +void rib_flush_routes_family(int family); +struct nhop_object *rib_lookup(uint32_t fibnum, const struct sockaddr *dst, + uint32_t flags, uint32_t flowid); +const char *rib_print_family(int family); + typedef void route_notification_t(const struct rib_cmd_info *rc, void *); void rib_decompose_notification(const struct rib_cmd_info *rc, route_notification_t *cb, void *cbdata); diff --git a/sys/net/route/route_fib.h b/sys/net/route/route_fib.h new file mode 100644 --- /dev/null +++ b/sys/net/route/route_fib.h @@ -0,0 +1,161 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2023 Alexander V. Chernikov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * This header file contains public functions and structures used for + * the datapath. + */ + +#ifndef _NET_ROUTE_ROUTE_FIB_H_ +#define _NET_ROUTE_ROUTE_FIB_H_ + +#ifdef _KERNEL + +#include + +/* + * Keep a generation count of routing table, incremented on route addition, + * so we can invalidate caches. This is accessed without a lock, as precision + * is not required. + */ +typedef volatile u_int rt_gen_t; /* tree generation (for adds) */ +#define RT_GEN(fibnum, af) rt_tables_get_gen(fibnum, af) + +/* + * Struct route consiste of a destination address, + * a route entry pointer, link-layer prepend data pointer along + * with its length. + */ +struct route { + struct nhop_object *ro_nh; + struct llentry *ro_lle; + /* + * ro_prepend and ro_plen are only used for bpf to pass in a + * preformed header. They are not cacheable. + */ + char *ro_prepend; + uint16_t ro_plen; + uint16_t ro_flags; + uint16_t ro_mtu; /* saved ro_rt mtu */ + uint16_t spare; + struct sockaddr ro_dst; +}; + +#define RT_L2_ME_BIT 2 /* dst L2 addr is our address */ +#define RT_MAY_LOOP_BIT 3 /* dst may require loop copy */ +#define RT_HAS_HEADER_BIT 4 /* mbuf already have its header prepended */ + +#define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */ +#define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */ +#define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */ + +#define RT_REJECT 0x0020 /* Destination is reject */ +#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */ +#define RT_HAS_GW 0x0080 /* Destination has GW */ +#define RT_LLE_CACHE 0x0100 /* Cache link layer */ + +/* Calculate flowid for locally-originated packets */ +#define V_fib_hash_outbound VNET(fib_hash_outbound) +VNET_DECLARE(u_int, fib_hash_outbound); + +/* Outbound flowid generation rules */ +#ifdef RSS + +#define fib4_calc_packet_hash xps_proto_software_hash_v4 +#define fib6_calc_packet_hash xps_proto_software_hash_v6 +#define CALC_FLOWID_OUTBOUND_SENDTO true + +#ifdef ROUTE_MPATH +#define CALC_FLOWID_OUTBOUND V_fib_hash_outbound +#else +#define CALC_FLOWID_OUTBOUND false +#endif + +#else /* !RSS */ + +#define fib4_calc_packet_hash fib4_calc_software_hash +#define fib6_calc_packet_hash fib6_calc_software_hash + +#ifdef ROUTE_MPATH +#define CALC_FLOWID_OUTBOUND_SENDTO V_fib_hash_outbound +#define CALC_FLOWID_OUTBOUND V_fib_hash_outbound +#else +#define CALC_FLOWID_OUTBOUND_SENDTO false +#define CALC_FLOWID_OUTBOUND false +#endif + +#endif /* RSS */ + + +#endif /* _KERNEL */ + +#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \ + || (ifp)->if_link_state == LINK_STATE_UP) + +#define RO_NHFREE(_ro) do { \ + if ((_ro)->ro_nh) { \ + NH_FREE((_ro)->ro_nh); \ + (_ro)->ro_nh = NULL; \ + } \ +} while (0) + +#define RO_INVALIDATE_CACHE(ro) do { \ + if ((ro)->ro_lle != NULL) { \ + LLE_FREE((ro)->ro_lle); \ + (ro)->ro_lle = NULL; \ + } \ + if ((ro)->ro_nh != NULL) { \ + NH_FREE((ro)->ro_nh); \ + (ro)->ro_nh = NULL; \ + } \ + } while (0) + +#define RO_GET_FAMILY(ro, dst) ((ro) != NULL && \ + (ro)->ro_flags & RT_HAS_GW \ + ? (ro)->ro_dst.sa_family : (dst)->sa_family) + +/* + * Validate a cached route based on a supplied cookie. If there is an + * out-of-date cache, simply free it. Update the generation number + * for the new allocation + */ +#define NH_VALIDATE(ro, cookiep, fibnum) do { \ + rt_gen_t cookie = RT_GEN(fibnum, (ro)->ro_dst.sa_family); \ + if (*(cookiep) != cookie) { \ + RO_INVALIDATE_CACHE(ro); \ + *(cookiep) = cookie; \ + } \ +} while (0) + +VNET_DECLARE(uint32_t, _rt_numfibs); /* number of existing route tables */ +#define V_rt_numfibs VNET(_rt_numfibs) +/* temporary compat arg */ +#define rt_numfibs V_rt_numfibs + +#endif diff --git a/sys/net/route/route_tables.c b/sys/net/route/route_tables.c --- a/sys/net/route/route_tables.c +++ b/sys/net/route/route_tables.c @@ -54,6 +54,7 @@ #include #include +#include #include /* Kernel config default option. */ diff --git a/sys/netinet/in_fib_dxr.c b/sys/netinet/in_fib_dxr.c --- a/sys/netinet/in_fib_dxr.c +++ b/sys/netinet/in_fib_dxr.c @@ -65,6 +65,7 @@ #include #include #include +#include #define DXR_TRIE_BITS 20 diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -97,6 +97,7 @@ #include #include #include +#include #include #include #include