From 90a4a3692209ab55cca643cad035a816404fff7c Mon Sep 17 00:00:00 2001 From: Sebastian Benoit Date: Fri, 10 May 2019 16:51:14 +0000 Subject: Make it possible to switch between wireless and physical interfacs (again?): when adding the default route, set it with the interface address of the interface we are configuring. This way its possible to have two default routes (from two running dhclient processes) in the routing table. Since wireless interfaces have a higher prio value, when a physical interface is connected it will be prefered (for new connections). ok krw@ mumble yes mumble claudio@ --- sbin/dhclient/kroute.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'sbin') diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c index 462e67487af..79e7436151a 100644 --- a/sbin/dhclient/kroute.c +++ b/sbin/dhclient/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.161 2019/02/23 13:37:34 krw Exp $ */ +/* $OpenBSD: kroute.c,v 1.162 2019/05/10 16:51:13 benno Exp $ */ /* * Copyright 2012 Kenneth R Westerback @@ -60,7 +60,7 @@ void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); unsigned int route_in_rtstatic(struct rt_msghdr *, uint8_t *, unsigned int); void flush_routes(int, int, int, uint8_t *, unsigned int); void add_route(char *, int, int, struct in_addr, struct in_addr, - struct in_addr, int); + struct in_addr, struct in_addr, int); void set_routes(char *, int, int, int, struct in_addr, struct in_addr, uint8_t *, unsigned int); @@ -370,13 +370,14 @@ flush_routes(int index, int routefd, int rdomain, */ void add_route(char *name, int rdomain, int routefd, struct in_addr dest, - struct in_addr netmask, struct in_addr gateway, int flags) + struct in_addr netmask, struct in_addr gateway, struct in_addr ifa, + int flags) { char destbuf[INET_ADDRSTRLEN]; char maskbuf[INET_ADDRSTRLEN]; struct iovec iov[5]; struct rt_msghdr rtm; - struct sockaddr_in sadest, sagateway, samask; + struct sockaddr_in sadest, sagateway, samask, saifa; int index, iovcnt = 0; index = if_nametoindex(name); @@ -429,6 +430,19 @@ add_route(char *name, int rdomain, int routefd, struct in_addr dest, iov[iovcnt].iov_base = &samask; iov[iovcnt++].iov_len = sizeof(samask); + if (ifa.s_addr != INADDR_ANY) { + /* Add the ifa */ + memset(&saifa, 0, sizeof(saifa)); + saifa.sin_len = sizeof(saifa); + saifa.sin_family = AF_INET; + saifa.sin_addr.s_addr = ifa.s_addr; + + rtm.rtm_msglen += sizeof(saifa); + iov[iovcnt].iov_base = &saifa; + iov[iovcnt++].iov_len = sizeof(saifa); + rtm.rtm_addrs |= RTA_IFA; + } + if (writev(routefd, iov, iovcnt) == -1) { if (errno != EEXIST || log_getverbose() != 0) { strlcpy(destbuf, inet_ntoa(dest), @@ -476,7 +490,7 @@ set_routes(char *name, int index, int rdomain, int routefd, struct in_addr addr, * -iface $addr */ add_route(name, rdomain, routefd, dest, netmask, - addr, RTF_STATIC | RTF_CLONING); + addr, any, RTF_STATIC | RTF_CLONING); } else if (netmask.s_addr == INADDR_ANY) { /* * DEFAULT ROUTE @@ -501,7 +515,8 @@ set_routes(char *name, int index, int rdomain, int routefd, struct in_addr addr, * */ add_route(name, rdomain, routefd, gateway, - broadcast, addr, RTF_STATIC | RTF_CLONING); + broadcast, addr, any, + RTF_STATIC | RTF_CLONING); } if (memcmp(&gateway, &addr, sizeof(addr)) == 0) { @@ -511,15 +526,16 @@ set_routes(char *name, int index, int rdomain, int routefd, struct in_addr addr, * route add default -iface $addr */ add_route(name, rdomain, routefd, any, any, - gateway, RTF_STATIC); + gateway, any, RTF_STATIC); } else { /* * DEFAULT ROUTE IS VIA GATEWAY * - * route add default $gateway + * route add default $gateway -ifa $addr + * */ add_route(name, rdomain, routefd, any, any, - gateway, RTF_STATIC | RTF_GATEWAY); + gateway, addr, RTF_STATIC | RTF_GATEWAY); } } else { /* @@ -528,7 +544,7 @@ set_routes(char *name, int index, int rdomain, int routefd, struct in_addr addr, * route add -net $dest -netmask $netmask $gateway */ add_route(name, rdomain, routefd, dest, netmask, - gateway, RTF_STATIC | RTF_GATEWAY); + gateway, any, RTF_STATIC | RTF_GATEWAY); } } } -- cgit v1.2.3