diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h index 7cea317a0..e9f6618c9 100644 --- a/src/ap/ap_drv_ops.h +++ b/src/ap/ap_drv_ops.h @@ -310,6 +310,16 @@ static inline int hostapd_drv_br_port_set_attr(struct hostapd_data *hapd, return hapd->driver->br_port_set_attr(hapd->drv_priv, attr, val); } +static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, + enum drv_br_net_param param, + unsigned int val) +{ + if (hapd->driver == NULL || hapd->drv_priv == NULL || + hapd->driver->br_set_net_param == NULL) + return -1; + return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); +} + static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, int vendor_id, int subcmd, const u8 *data, size_t data_len, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 4c9bbc8a8..4645e9a04 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1378,6 +1378,10 @@ enum drv_br_port_attr { DRV_BR_PORT_ATTR_HAIRPIN_MODE, }; +enum drv_br_net_param { + DRV_BR_NET_PARAM_GARP_ACCEPT, +}; + /** * struct wpa_driver_ops - Driver interface API definition @@ -2633,6 +2637,15 @@ struct wpa_driver_ops { int (*br_port_set_attr)(void *priv, enum drv_br_port_attr attr, unsigned int val); + /** + * br_port_set_attr - Set a bridge network parameter + * @param: Bridge parameter to set + * @val: Value to be set + * Returns: 0 on success, negative (<0) on failure + */ + int (*br_set_net_param)(void *priv, enum drv_br_net_param param, + unsigned int val); + /** * set_wowlan - Set wake-on-wireless triggers * @priv: Private driver interface data diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index d40a44aeb..68afcf01e 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9035,6 +9035,47 @@ static int wpa_driver_br_port_set_attr(void *priv, enum drv_br_port_attr attr, } +static const char * drv_br_net_param_str(enum drv_br_net_param param) +{ + switch (param) { + case DRV_BR_NET_PARAM_GARP_ACCEPT: + return "arp_accept"; + } + + return NULL; +} + + +static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, + unsigned int val) +{ + struct i802_bss *bss = priv; + char path[128]; + const char *param_txt; + int ip_version = 4; + + param_txt = drv_br_net_param_str(param); + if (param_txt == NULL) + return -EINVAL; + + switch (param) { + case DRV_BR_NET_PARAM_GARP_ACCEPT: + ip_version = 4; + break; + default: + return -EINVAL; + } + + os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s", + ip_version, bss->brname, param_txt); + + if (linux_write_system_file(path, val)) + return -1; + + return 0; +} + + const struct wpa_driver_ops wpa_driver_nl80211_ops = { .name = "nl80211", .desc = "Linux nl80211/cfg80211", @@ -9136,4 +9177,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .br_add_ip_neigh = wpa_driver_br_add_ip_neigh, .br_delete_ip_neigh = wpa_driver_br_delete_ip_neigh, .br_port_set_attr = wpa_driver_br_port_set_attr, + .br_set_net_param = wpa_driver_br_set_net_param, };