aboutsummaryrefslogtreecommitdiff
path: root/sys/net/route.c
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2020-04-23 08:04:20 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2020-04-23 08:04:20 +0000
commitaaad3c4fcaa558ec3b2c7db9bb26f2843585a122 (patch)
tree3e7477aad71b6fe5569c4af1c7b4e4a5dec00cc0 /sys/net/route.c
parent9e88f47c8f402b87fb36bdea673ad80a988b7d9d (diff)
downloadsrc-aaad3c4fcaa558ec3b2c7db9bb26f2843585a122.tar.gz
src-aaad3c4fcaa558ec3b2c7db9bb26f2843585a122.zip
Convert rtentry field accesses into nhop field accesses.
One of the goals of the new routing KPI defined in r359823 is to entirely hide`struct rtentry` from the consumers. It will allow to improve routing subsystem internals and deliver more features much faster. This commit is mostly mechanical change to eliminate direct struct rtentry field accesses. The only notable difference is AF_LINK gateway encoding. AF_LINK gw is used in routing stack for operations with interface routes and host loopback routes. In the former case it indicates _some_ non-NULL gateway, as the interface is the same as in rt_ifp in kernel and rtm_ifindex in rtsock reporting. In the latter case the interface index inside gateway was used by the IPv6 datapath to verify address scope for link-local interfaces. Kernel uses struct sockaddr_dl for this type of gateway. This structure allows for specifying rich interface data, such as mac address and interface name. However, this results in relatively large structure size - 52 bytes. Routing stack fils in only 2 fields - sdl_index and sdl_type, which reside in the first 8 bytes of the structure. In the new KPI, struct nhop_object tries to be cache-efficient, hence embodies gateway address inside the structure. In the AF_LINK case it stores stortened version of the structure - struct sockaddr_dl_short, which occupies 16 bytes. After D24340 changes, the data inside AF_LINK gateway will not be used in the kernel at all, leaving rtsock as the only potential concern. The difference in rtsock reporting: (old) got message of size 240 on Thu Apr 16 03:12:13 2020 RTM_ADD: Add Route: len 240, pid: 0, seq 0, errno 0, flags:<UP,DONE,PINNED> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.0.0 link#5 255.255.255.0 (new) got message of size 200 on Sun Apr 19 09:46:32 2020 RTM_ADD: Add Route: len 200, pid: 0, seq 0, errno 0, flags:<UP,DONE,PINNED> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.0.0 link#5 255.255.255.0 Note 40 bytes different (52-16 + alignment). However, gateway is still a valid AF_LINK gateway with proper data filled in. It is worth noting that these particular messages (interface routes) are mostly ignored by routing daemons: * bird/quagga/frr uses RTM_NEWADDR and ignores prefix route addition messages. * quagga/frr ignores routes without gateway More detailed overview on how rtsock messages are used by the routing daemons to reconstruct the kernel view, can be found in D22974. Differential Revision: https://reviews.freebsd.org/D24519
Notes
Notes: svn path=/head/; revision=360218
Diffstat (limited to 'sys/net/route.c')
-rw-r--r--sys/net/route.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 3359beb3e6cb..b68936d2c74f 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -827,6 +827,7 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
{
struct rt_metrics *rmx;
struct sockaddr *src, *dst;
+ struct nhop_object *nh;
int sa_len;
if (flags & NHR_COPY) {
@@ -858,7 +859,7 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
}
/* Copy gateway is set && dst is non-zero */
- src = rt->rt_gateway;
+ src = &rt->rt_nhop->gw_sa;
dst = info->rti_info[RTAX_GATEWAY];
if ((rt->rt_flags & RTF_GATEWAY) && src != NULL && dst != NULL){
if (src->sa_len > dst->sa_len)
@@ -874,20 +875,21 @@ rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags)
info->rti_addrs |= RTA_NETMASK;
}
if (rt->rt_flags & RTF_GATEWAY) {
- info->rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa;
info->rti_addrs |= RTA_GATEWAY;
}
}
+ nh = rt->rt_nhop;
rmx = info->rti_rmx;
if (rmx != NULL) {
info->rti_mflags |= RTV_MTU;
- rmx->rmx_mtu = rt->rt_mtu;
+ rmx->rmx_mtu = nh->nh_mtu;
}
- info->rti_flags = rt->rt_flags;
- info->rti_ifp = rt->rt_ifp;
- info->rti_ifa = rt->rt_ifa;
+ info->rti_flags = rt->rt_flags | nhop_get_rtflags(nh);
+ info->rti_ifp = nh->nh_ifp;
+ info->rti_ifa = nh->nh_ifa;
if (flags & NHR_REF) {
if_ref(info->rti_ifp);
ifa_ref(info->rti_ifa);
@@ -1021,7 +1023,7 @@ rt_checkdelroute(struct radix_node *rn, void *arg)
info->rti_info[RTAX_DST] = rt_key(rt);
info->rti_info[RTAX_NETMASK] = rt_mask(rt);
- info->rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa;
rt = rt_unlinkrte(di->rnh, info, &error);
if (rt == NULL) {
@@ -1216,7 +1218,7 @@ rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, int *perror)
* Ease the caller work by filling in remaining info
* from that particular entry.
*/
- info->rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa;
}
/*
@@ -1471,7 +1473,7 @@ rt_print(char *buf, int buflen, struct rtentry *rt)
if (rt->rt_flags & RTF_GATEWAY) {
buf[i++] = '>';
- i += p_sockaddr(buf + i, buflen - i, rt->rt_gateway);
+ i += p_sockaddr(buf + i, buflen - i, &rt->rt_nhop->gw_sa);
}
return (i);
@@ -1528,8 +1530,8 @@ rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info,
* one route in the chain.
*/
if (gw &&
- (rt->rt_gateway->sa_len != gw->sa_len ||
- memcmp(rt->rt_gateway, gw, gw->sa_len))) {
+ (rt->rt_nhop->gw_sa.sa_len != gw->sa_len ||
+ memcmp(&rt->rt_nhop->gw_sa, gw, gw->sa_len))) {
*perror = ESRCH;
return (NULL);
}
@@ -2078,7 +2080,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
char tempbuf[_SOCKADDR_TMPSIZE];
int didwork = 0;
int a_failure = 0;
- struct sockaddr_dl *sdl = NULL;
+ struct sockaddr_dl_short *sdl = NULL;
struct rib_head *rnh;
if (flags & RTF_HOST) {
@@ -2130,10 +2132,10 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
dst = (struct sockaddr *)tempbuf;
}
} else if (cmd == RTM_ADD) {
- sdl = (struct sockaddr_dl *)tempbuf;
- bzero(sdl, sizeof(struct sockaddr_dl));
+ sdl = (struct sockaddr_dl_short *)tempbuf;
+ bzero(sdl, sizeof(struct sockaddr_dl_short));
sdl->sdl_family = AF_LINK;
- sdl->sdl_len = sizeof(struct sockaddr_dl);
+ sdl->sdl_len = sizeof(struct sockaddr_dl_short);
sdl->sdl_type = ifa->ifa_ifp->if_type;
sdl->sdl_index = ifa->ifa_ifp->if_index;
}
@@ -2165,8 +2167,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
rt = RNTORT(rn);
/*
* for interface route the
- * rt->rt_gateway is sockaddr_intf
- * for cloning ARP entries, so
+ * rt->rt_gateway is sockaddr_dl, so
* rt_mpath_matchgate must use the
* interface address
*/