From: Ben Greear <greearb@xxxxxxxxxxxxxxx> This helps hostapd work better in VRF and other fancy network environments. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- hostapd/config_file.c | 2 ++ hostapd/hostapd.conf | 5 +++++ src/radius/radius_client.c | 20 ++++++++++++++++++++ src/radius/radius_client.h | 5 +++++ 4 files changed, 32 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 905402cf6..a2c8fbb79 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2727,6 +2727,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, return 1; } bss->radius->force_client_addr = 1; + } else if (os_strcmp(buf, "radius_client_dev") == 0) { + bss->radius->force_client_dev = os_strdup(pos); } else if (os_strcmp(buf, "auth_server_addr") == 0) { if (hostapd_config_read_radius_addr( &bss->radius->auth_servers, diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 769a59ae8..b5719f8e7 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1312,6 +1312,11 @@ own_ip_addr=127.0.0.1 # used, e.g., when the device has multiple IP addresses. #radius_client_addr=127.0.0.1 +# RADIUS client forced local interface. Helps run properly with VRF +# Default is none set. +# Example below binds to eth0 +#radius_client_dev=eth0 + # RADIUS authentication server #auth_server_addr=127.0.0.1 #auth_server_port=1812 diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c index 2b7a604ed..a2ed9d410 100644 --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c @@ -12,6 +12,7 @@ #include "radius.h" #include "radius_client.h" #include "eloop.h" +#include <net/if.h> /* Defaults for RADIUS retransmit values (exponential backoff) */ @@ -1159,6 +1160,25 @@ radius_change_server(struct radius_client_data *radius, return -1; } +#ifdef __linux__ + if (conf->force_client_dev && conf->force_client_dev[0]) { + struct ifreq ifr; + os_memset(&ifr, 0, sizeof(ifr)); + os_strlcpy(ifr.ifr_ifrn.ifrn_name, conf->force_client_dev, IFNAMSIZ); + if (setsockopt(sel_sock, SOL_SOCKET, SO_BINDTODEVICE, + (char *) &ifr, sizeof(ifr)) < 0) { + wpa_printf(MSG_ERROR, + "setsockopt[RADIUS CLIENT, SO_BINDTODEVICE]: %s", + strerror(errno)); + /* probably not critical error, continue on and hope for the best. */ + } + else { + wpa_printf(MSG_ERROR, + "Bound radius client socket to device: %s", conf->force_client_dev); + } + } +#endif + if (conf->force_client_addr) { switch (conf->client_addr.af) { case AF_INET: diff --git a/src/radius/radius_client.h b/src/radius/radius_client.h index 8ca0874db..4d050545b 100644 --- a/src/radius/radius_client.h +++ b/src/radius/radius_client.h @@ -174,6 +174,11 @@ struct hostapd_radius_servers { * force_client_addr - Whether to force client (local) address */ int force_client_addr; + + /** + * Will call SO_BINDTODEVICE on this if non null and non-empty string. + */ + char* force_client_dev; }; -- 2.14.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap