RADIUS client: Support SO_BINDTODEVICE

Allow the RADIUS client socket to be bound to a specific netdev. This
helps hostapd work better in VRF and other fancy network environments.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Andreas Tobler <andreas.tobler at onway.ch>
This commit is contained in:
Ben Greear 2020-05-13 13:48:12 -07:00 committed by Jouni Malinen
parent 3a05f89edc
commit 827b43b3ca
5 changed files with 39 additions and 5 deletions

View file

@ -779,6 +779,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
conf->radius->num_auth_servers);
hostapd_config_free_radius(conf->radius->acct_servers,
conf->radius->num_acct_servers);
os_free(conf->radius->force_client_dev);
}
hostapd_config_free_radius_attr(conf->radius_auth_req_attr);
hostapd_config_free_radius_attr(conf->radius_acct_req_attr);

View file

@ -7,6 +7,7 @@
*/
#include "includes.h"
#include <net/if.h>
#include "common.h"
#include "radius.h"
@ -1168,6 +1169,29 @@ radius_change_server(struct radius_client_data *radius,
return -1;
}
/* Force a reconnect by disconnecting the socket first */
if (connect(sel_sock, (struct sockaddr *) &disconnect_addr,
sizeof(disconnect_addr)) < 0)
wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno));
#ifdef __linux__
if (conf->force_client_dev && conf->force_client_dev[0]) {
if (setsockopt(sel_sock, SOL_SOCKET, SO_BINDTODEVICE,
conf->force_client_dev,
os_strlen(conf->force_client_dev)) < 0) {
wpa_printf(MSG_ERROR,
"RADIUS: setsockopt[SO_BINDTODEVICE]: %s",
strerror(errno));
/* Probably not a critical error; continue on and hope
* for the best. */
} else {
wpa_printf(MSG_DEBUG,
"RADIUS: Bound client socket to device: %s",
conf->force_client_dev);
}
}
#endif /* __linux__ */
if (conf->force_client_addr) {
switch (conf->client_addr.af) {
case AF_INET:
@ -1200,11 +1224,6 @@ radius_change_server(struct radius_client_data *radius,
}
}
/* Force a reconnect by disconnecting the socket first */
if (connect(sel_sock, (struct sockaddr *) &disconnect_addr,
sizeof(disconnect_addr)) < 0)
wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno));
if (connect(sel_sock, addr, addrlen) < 0) {
wpa_printf(MSG_INFO, "connect[radius]: %s", strerror(errno));
return -1;

View file

@ -174,6 +174,11 @@ struct hostapd_radius_servers {
* force_client_addr - Whether to force client (local) address
*/
int force_client_addr;
/**
* force_client_dev - Bind the socket to a specified interface, if set
*/
char *force_client_dev;
};