| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- From: Felix Fietkau <[email protected]>
- Date: Tue, 27 Jul 2021 20:28:58 +0200
- Subject: [PATCH] hostapd: make the snooping interface (for proxyarp)
- configurable
- Use the VLAN interface instead of the bridge, to ensure that hostapd receives
- untagged DHCP packets
- --- a/hostapd/config_file.c
- +++ b/hostapd/config_file.c
- @@ -2476,6 +2476,8 @@ static int hostapd_config_fill(struct ho
- os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
- } else if (os_strcmp(buf, "bridge_hairpin") == 0) {
- bss->bridge_hairpin = atoi(pos);
- + } else if (os_strcmp(buf, "snoop_iface") == 0) {
- + os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface));
- } 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) {
- --- a/src/ap/ap_config.h
- +++ b/src/ap/ap_config.h
- @@ -284,6 +284,7 @@ struct hostapd_bss_config {
- char iface[IFNAMSIZ + 1];
- char bridge[IFNAMSIZ + 1];
- char ft_iface[IFNAMSIZ + 1];
- + char snoop_iface[IFNAMSIZ + 1];
- char vlan_bridge[IFNAMSIZ + 1];
- char wds_bridge[IFNAMSIZ + 1];
- int bridge_hairpin; /* hairpin_mode on bridge members */
- --- a/src/ap/ap_drv_ops.h
- +++ b/src/ap/ap_drv_ops.h
- @@ -377,12 +377,12 @@ static inline int hostapd_drv_br_port_se
-
- static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd,
- enum drv_br_net_param param,
- - unsigned int val)
- + const char *ifname, 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);
- + return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val);
- }
-
- static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
- --- a/src/ap/x_snoop.c
- +++ b/src/ap/x_snoop.c
- @@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *ha
-
- hapd->x_snoop_initialized = true;
-
- - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE,
- + if (!conf->snoop_iface[0] &&
- + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE,
- 1)) {
- wpa_printf(MSG_DEBUG,
- "x_snoop: Failed to enable hairpin_mode on the bridge port");
- return -1;
- }
-
- - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) {
- + if (!conf->snoop_iface[0] &&
- + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) {
- wpa_printf(MSG_DEBUG,
- "x_snoop: Failed to enable proxyarp on the bridge port");
- return -1;
- }
-
- if (hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT,
- - 1)) {
- + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 1)) {
- wpa_printf(MSG_DEBUG,
- "x_snoop: Failed to enable accepting gratuitous ARP on the bridge");
- return -1;
- }
-
- #ifdef CONFIG_IPV6
- - if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
- + if (!conf->snoop_iface[0] &&
- + hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, NULL, 1)) {
- wpa_printf(MSG_DEBUG,
- "x_snoop: Failed to enable multicast snooping on the bridge");
- return -1;
- @@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_dat
- {
- struct hostapd_bss_config *conf = hapd->conf;
- struct l2_packet_data *l2;
- + const char *ifname = conf->bridge;
- +
- + if (conf->snoop_iface[0])
- + ifname = conf->snoop_iface;
-
- - l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
- + l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1);
- if (l2 == NULL) {
- wpa_printf(MSG_DEBUG,
- "x_snoop: Failed to initialize L2 packet processing %s",
- @@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send
-
- void x_snoop_deinit(struct hostapd_data *hapd)
- {
- + struct hostapd_bss_config *conf = hapd->conf;
- +
- if (!hapd->x_snoop_initialized)
- return;
- - hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0);
- + hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT,
- + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0);
- hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0);
- hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0);
- hapd->x_snoop_initialized = false;
- --- a/src/drivers/driver.h
- +++ b/src/drivers/driver.h
- @@ -4429,7 +4429,7 @@ struct wpa_driver_ops {
- * Returns: 0 on success, negative (<0) on failure
- */
- int (*br_set_net_param)(void *priv, enum drv_br_net_param param,
- - unsigned int val);
- + const char *ifname, unsigned int val);
-
- /**
- * get_wowlan - Get wake-on-wireless status
- --- a/src/drivers/driver_nl80211.c
- +++ b/src/drivers/driver_nl80211.c
- @@ -12853,7 +12853,7 @@ static const char * drv_br_net_param_str
-
-
- static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
- - unsigned int val)
- + const char *ifname, unsigned int val)
- {
- struct i802_bss *bss = priv;
- char path[128];
- @@ -12879,8 +12879,11 @@ static int wpa_driver_br_set_net_param(v
- return -EINVAL;
- }
-
- + if (!ifname)
- + ifname = bss->brname;
- +
- os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s",
- - ip_version, bss->brname, param_txt);
- + ip_version, ifname, param_txt);
-
- set_val:
- if (linux_write_system_file(path, val))
|