diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 472a91df2..2e208d3f6 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2316,6 +2316,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, sizeof(conf->bss[0]->iface)); } else if (os_strcmp(buf, "bridge") == 0) { os_strlcpy(bss->bridge, pos, sizeof(bss->bridge)); + } else if (os_strcmp(buf, "bridge_hairpin") == 0) { + bss->bridge_hairpin = atoi(pos); } else if (os_strcmp(buf, "vlan_bridge") == 0) { os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); } else if (os_strcmp(buf, "wds_bridge") == 0) { @@ -4467,6 +4469,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, #endif /* CONFIG_FILS */ } else if (os_strcmp(buf, "multicast_to_unicast") == 0) { bss->multicast_to_unicast = atoi(pos); + } else if (os_strcmp(buf, "bridge_multicast_to_unicast") == 0) { + bss->bridge_multicast_to_unicast = atoi(pos); } else if (os_strcmp(buf, "broadcast_deauth") == 0) { bss->broadcast_deauth = atoi(pos); } else if (os_strcmp(buf, "notify_mgmt_frames") == 0) { diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index dfe259c30..7036c15d5 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -284,6 +284,7 @@ struct hostapd_bss_config { char bridge[IFNAMSIZ + 1]; char vlan_bridge[IFNAMSIZ + 1]; char wds_bridge[IFNAMSIZ + 1]; + int bridge_hairpin; /* hairpin_mode on bridge members */ enum hostapd_logger_level logger_syslog_level, logger_stdout_level; @@ -748,6 +749,7 @@ struct hostapd_bss_config { #endif /* CONFIG_FILS */ int multicast_to_unicast; + int bridge_multicast_to_unicast; int broadcast_deauth; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 58492e51e..c3fd91e43 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1435,6 +1435,22 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first, return -1; } + if (conf->bridge[0]) { + /* Set explicitly configured bridge parameters that might have + * been lost if the interface has been removed out of the + * bridge. */ + + /* multicast to unicast on bridge ports */ + if (conf->bridge_multicast_to_unicast) + hostapd_drv_br_port_set_attr( + hapd, DRV_BR_PORT_ATTR_MCAST2UCAST, 1); + + /* hairpin mode */ + if (conf->bridge_hairpin) + hostapd_drv_br_port_set_attr( + hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 1); + } + if (conf->proxy_arp) { if (x_snoop_init(hapd)) { wpa_printf(MSG_ERROR, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 46182552d..b205744d0 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -2647,6 +2647,7 @@ struct macsec_init_params { enum drv_br_port_attr { DRV_BR_PORT_ATTR_PROXYARP, DRV_BR_PORT_ATTR_HAIRPIN_MODE, + DRV_BR_PORT_ATTR_MCAST2UCAST, }; enum drv_br_net_param { diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 4db29f1d5..75825bd94 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -11615,6 +11615,8 @@ static const char * drv_br_port_attr_str(enum drv_br_port_attr attr) return "proxyarp_wifi"; case DRV_BR_PORT_ATTR_HAIRPIN_MODE: return "hairpin_mode"; + case DRV_BR_PORT_ATTR_MCAST2UCAST: + return "multicast_to_unicast"; } return NULL;