diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c index 815ba2558..5caf5f2c0 100644 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016 Tobias Brunner + * Copyright (C) 2009-2024 Tobias Brunner * * Copyright (C) secunet Security Networks AG * @@ -1443,6 +1443,35 @@ static void add_rt_ifname(struct rt_msghdr *hdr, int type, char *name) } } +/** + * Append an interface address sockaddr_dl to routing message + */ +static void add_rt_ifaddr(struct rt_msghdr *hdr, int type, char *name) +{ + struct ifaddrs *ifap, *ifa; + struct sockaddr_dl *sdl; + + if (getifaddrs(&ifap) < 0) + { + return; + } + + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) + { + if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_LINK || + !streq(name, ifa->ifa_name)) + { + continue; + } + sdl = (struct sockaddr_dl*)ifa->ifa_addr; + memcpy((char*)hdr + hdr->rtm_msglen, sdl, sdl->sdl_len); + hdr->rtm_msglen += SA_LEN(sdl->sdl_len); + hdr->rtm_addrs |= type; + break; + } + freeifaddrs(ifap); +} + /** * Add or remove a route */ @@ -1519,6 +1548,10 @@ static status_t manage_route(private_kernel_pfroute_net_t *this, int op, { add_rt_addr(&msg.hdr, RTA_GATEWAY, gateway); } + else if (if_name) + { + add_rt_ifaddr(&msg.hdr, RTA_GATEWAY, if_name); + } break; default: break;