git: f262b06a57b0 - main - route: fix route get netlink translation.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 04 Apr 2023 08:42:41 UTC
The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=f262b06a57b03a2025bdc0ce628514cd68af73db commit f262b06a57b03a2025bdc0ce628514cd68af73db Author: Alexander V. Chernikov <melifaro@FreeBSD.org> AuthorDate: 2023-04-04 08:37:14 +0000 Commit: Alexander V. Chernikov <melifaro@FreeBSD.org> CommitDate: 2023-04-04 08:42:33 +0000 route: fix route get netlink translation. route.c uses newroute() to handle the "route get" command. The logic inside newroute() adds RTF_GATEWAY flag if "-interface" flag is not specified. That results in the inconsistent RTM_GET message with RTF_GATEWAY set but no RTAX_GATEWAY provided. Address this in the translation code by checking if the gateway is actually provided. --- sbin/route/route.c | 4 ++-- sbin/route/route_netlink.c | 48 +++++++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/sbin/route/route.c b/sbin/route/route.c index 947c97ce794a..4002cbe5867b 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -118,7 +118,7 @@ static int rtmsg_rtsock(int, int, int); static int flushroutes_fib_rtsock(int); static void monitor_rtsock(void); #else -int rtmsg_nl(int, int, int, struct sockaddr_storage *, struct rt_metrics *); +int rtmsg_nl(int, int, int, int, struct sockaddr_storage *, struct rt_metrics *); int flushroutes_fib_nl(int, int); void monitor_nl(int); #endif @@ -1524,7 +1524,7 @@ rtmsg(int cmd, int flags, int fib) #ifdef WITHOUT_NETLINK return (rtmsg_rtsock(cmd, flags, fib)); #else - errno = rtmsg_nl(cmd, flags, fib, so, &rt_metrics); + errno = rtmsg_nl(cmd, flags, fib, rtm_addrs, so, &rt_metrics); return (errno == 0 ? 0 : -1); #endif } diff --git a/sbin/route/route_netlink.c b/sbin/route/route_netlink.c index ce7da288496f..a3e9860244a9 100644 --- a/sbin/route/route_netlink.c +++ b/sbin/route/route_netlink.c @@ -33,7 +33,7 @@ void printb(int, const char *); extern const char routeflags[]; extern int verbose, debugonly; -int rtmsg_nl(int cmd, int rtm_flags, int fib, struct sockaddr_storage *so, +int rtmsg_nl(int cmd, int rtm_flags, int fib, int rtm_addrs, struct sockaddr_storage *so, struct rt_metrics *rt_metrics); int flushroutes_fib_nl(int fib, int af); void monitor_nl(int fib); @@ -125,8 +125,18 @@ nl_helper_free(struct nl_helper *h) snl_free(&h->ss_cmd); } +static struct sockaddr * +get_addr(struct sockaddr_storage *so, int rtm_addrs, int addr_type) +{ + struct sockaddr *sa = NULL; + + if (rtm_addrs & (1 << addr_type)) + sa = (struct sockaddr *)&so[addr_type]; + return (sa); +} + static int -rtmsg_nl_int(struct nl_helper *h, int cmd, int rtm_flags, int fib, +rtmsg_nl_int(struct nl_helper *h, int cmd, int rtm_flags, int fib, int rtm_addrs, struct sockaddr_storage *so, struct rt_metrics *rt_metrics) { struct snl_state *ss = &h->ss_cmd; @@ -154,9 +164,9 @@ rtmsg_nl_int(struct nl_helper *h, int cmd, int rtm_flags, int fib, exit(1); } - struct sockaddr *dst = (struct sockaddr *)&so[RTAX_DST]; - struct sockaddr *mask = (struct sockaddr *)&so[RTAX_NETMASK]; - struct sockaddr *gw = (struct sockaddr *)&so[RTAX_GATEWAY]; + struct sockaddr *dst = get_addr(so, rtm_addrs, RTAX_DST); + struct sockaddr *mask = get_addr(so, rtm_addrs, RTAX_NETMASK); + struct sockaddr *gw = get_addr(so, rtm_addrs, RTAX_GATEWAY); if (dst == NULL) return (EINVAL); @@ -210,16 +220,18 @@ rtmsg_nl_int(struct nl_helper *h, int cmd, int rtm_flags, int fib, snl_add_msg_attr_ip(&nw, RTA_DST, dst); snl_add_msg_attr_u32(&nw, RTA_TABLE, fib); - if (rtm_flags & RTF_GATEWAY) { - if (gw->sa_family == dst->sa_family) - snl_add_msg_attr_ip(&nw, RTA_GATEWAY, gw); - else - snl_add_msg_attr_ipvia(&nw, RTA_VIA, gw); - } else if (gw != NULL) { - /* Should be AF_LINK */ - struct sockaddr_dl *sdl = (struct sockaddr_dl *)gw; - if (sdl->sdl_index != 0) - snl_add_msg_attr_u32(&nw, RTA_OIF, sdl->sdl_index); + if (gw != NULL) { + if (rtm_flags & RTF_GATEWAY) { + if (gw->sa_family == dst->sa_family) + snl_add_msg_attr_ip(&nw, RTA_GATEWAY, gw); + else + snl_add_msg_attr_ipvia(&nw, RTA_VIA, gw); + } else { + /* Should be AF_LINK */ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)gw; + if (sdl->sdl_index != 0) + snl_add_msg_attr_u32(&nw, RTA_OIF, sdl->sdl_index); + } } if (rtm_flags != 0) @@ -259,13 +271,13 @@ rtmsg_nl_int(struct nl_helper *h, int cmd, int rtm_flags, int fib, } int -rtmsg_nl(int cmd, int rtm_flags, int fib, struct sockaddr_storage *so, - struct rt_metrics *rt_metrics) +rtmsg_nl(int cmd, int rtm_flags, int fib, int rtm_addrs, + struct sockaddr_storage *so, struct rt_metrics *rt_metrics) { struct nl_helper h = {}; nl_helper_init(&h); - int error = rtmsg_nl_int(&h, cmd, rtm_flags, fib, so, rt_metrics); + int error = rtmsg_nl_int(&h, cmd, rtm_flags, fib, rtm_addrs, so, rt_metrics); nl_helper_free(&h); return (error);