]>
Commit | Line | Data |
---|---|---|
92379080 EQ |
1 | From: Felix Fietkau <nbd@nbd.name> |
2 | Date: Tue, 27 Jul 2021 20:28:58 +0200 | |
3 | Subject: [PATCH] hostapd: make the snooping interface (for proxyarp) | |
4 | configurable | |
5 | ||
6 | Use the VLAN interface instead of the bridge, to ensure that hostapd receives | |
7 | untagged DHCP packets | |
8 | ||
9 | --- a/hostapd/config_file.c | |
10 | +++ b/hostapd/config_file.c | |
11 | @@ -2451,6 +2451,8 @@ static int hostapd_config_fill(struct ho | |
12 | os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge)); | |
13 | } else if (os_strcmp(buf, "bridge_hairpin") == 0) { | |
14 | bss->bridge_hairpin = atoi(pos); | |
15 | + } else if (os_strcmp(buf, "snoop_iface") == 0) { | |
16 | + os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface)); | |
17 | } else if (os_strcmp(buf, "vlan_bridge") == 0) { | |
18 | os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge)); | |
19 | } else if (os_strcmp(buf, "wds_bridge") == 0) { | |
7b46377a FF |
20 | --- a/src/ap/ap_config.h |
21 | +++ b/src/ap/ap_config.h | |
94037ab6 | 22 | @@ -284,6 +284,7 @@ struct hostapd_bss_config { |
7b46377a FF |
23 | char iface[IFNAMSIZ + 1]; |
24 | char bridge[IFNAMSIZ + 1]; | |
25 | char ft_iface[IFNAMSIZ + 1]; | |
26 | + char snoop_iface[IFNAMSIZ + 1]; | |
27 | char vlan_bridge[IFNAMSIZ + 1]; | |
28 | char wds_bridge[IFNAMSIZ + 1]; | |
304423a4 | 29 | int bridge_hairpin; /* hairpin_mode on bridge members */ |
92379080 EQ |
30 | --- a/src/ap/ap_drv_ops.h |
31 | +++ b/src/ap/ap_drv_ops.h | |
32 | @@ -366,12 +366,12 @@ static inline int hostapd_drv_br_port_se | |
33 | ||
34 | static inline int hostapd_drv_br_set_net_param(struct hostapd_data *hapd, | |
35 | enum drv_br_net_param param, | |
36 | - unsigned int val) | |
37 | + const char *ifname, unsigned int val) | |
38 | { | |
39 | if (hapd->driver == NULL || hapd->drv_priv == NULL || | |
40 | hapd->driver->br_set_net_param == NULL) | |
41 | return -1; | |
42 | - return hapd->driver->br_set_net_param(hapd->drv_priv, param, val); | |
43 | + return hapd->driver->br_set_net_param(hapd->drv_priv, param, ifname, val); | |
44 | } | |
45 | ||
46 | static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd, | |
7b46377a FF |
47 | --- a/src/ap/x_snoop.c |
48 | +++ b/src/ap/x_snoop.c | |
36a9f844 | 49 | @@ -33,28 +33,31 @@ int x_snoop_init(struct hostapd_data *ha |
94037ab6 DB |
50 | |
51 | hapd->x_snoop_initialized = true; | |
17d19a7d FF |
52 | |
53 | - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, | |
54 | + if (!conf->snoop_iface[0] && | |
55 | + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, | |
56 | 1)) { | |
57 | wpa_printf(MSG_DEBUG, | |
58 | "x_snoop: Failed to enable hairpin_mode on the bridge port"); | |
59 | return -1; | |
60 | } | |
61 | ||
62 | - if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { | |
63 | + if (!conf->snoop_iface[0] && | |
64 | + hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) { | |
65 | wpa_printf(MSG_DEBUG, | |
66 | "x_snoop: Failed to enable proxyarp on the bridge port"); | |
67 | return -1; | |
36a9f844 FF |
68 | } |
69 | ||
70 | if (hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, | |
71 | - 1)) { | |
72 | + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 1)) { | |
73 | wpa_printf(MSG_DEBUG, | |
74 | "x_snoop: Failed to enable accepting gratuitous ARP on the bridge"); | |
75 | return -1; | |
17d19a7d FF |
76 | } |
77 | ||
78 | #ifdef CONFIG_IPV6 | |
79 | - if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) { | |
80 | + if (!conf->snoop_iface[0] && | |
36a9f844 | 81 | + hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, NULL, 1)) { |
17d19a7d FF |
82 | wpa_printf(MSG_DEBUG, |
83 | "x_snoop: Failed to enable multicast snooping on the bridge"); | |
84 | return -1; | |
94037ab6 | 85 | @@ -73,8 +76,12 @@ x_snoop_get_l2_packet(struct hostapd_dat |
7b46377a FF |
86 | { |
87 | struct hostapd_bss_config *conf = hapd->conf; | |
88 | struct l2_packet_data *l2; | |
89 | + const char *ifname = conf->bridge; | |
36a9f844 | 90 | + |
7b46377a FF |
91 | + if (conf->snoop_iface[0]) |
92 | + ifname = conf->snoop_iface; | |
36a9f844 FF |
93 | |
94 | - l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1); | |
f1b98fa4 | 95 | + l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1); |
7b46377a | 96 | if (l2 == NULL) { |
f1b98fa4 FF |
97 | wpa_printf(MSG_DEBUG, |
98 | "x_snoop: Failed to initialize L2 packet processing %s", | |
36a9f844 FF |
99 | @@ -127,9 +134,12 @@ void x_snoop_mcast_to_ucast_convert_send |
100 | ||
101 | void x_snoop_deinit(struct hostapd_data *hapd) | |
102 | { | |
103 | + struct hostapd_bss_config *conf = hapd->conf; | |
104 | + | |
105 | if (!hapd->x_snoop_initialized) | |
106 | return; | |
107 | - hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, 0); | |
108 | + hostapd_drv_br_set_net_param(hapd, DRV_BR_NET_PARAM_GARP_ACCEPT, | |
109 | + conf->snoop_iface[0] ? conf->snoop_iface : NULL, 0); | |
110 | hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 0); | |
111 | hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE, 0); | |
112 | hapd->x_snoop_initialized = false; | |
36a9f844 FF |
113 | --- a/src/drivers/driver.h |
114 | +++ b/src/drivers/driver.h | |
24d0e746 | 115 | @@ -4275,7 +4275,7 @@ struct wpa_driver_ops { |
36a9f844 FF |
116 | * Returns: 0 on success, negative (<0) on failure |
117 | */ | |
118 | int (*br_set_net_param)(void *priv, enum drv_br_net_param param, | |
119 | - unsigned int val); | |
120 | + const char *ifname, unsigned int val); | |
121 | ||
122 | /** | |
123 | * get_wowlan - Get wake-on-wireless status | |
124 | --- a/src/drivers/driver_nl80211.c | |
125 | +++ b/src/drivers/driver_nl80211.c | |
24d0e746 | 126 | @@ -12376,7 +12376,7 @@ static const char * drv_br_net_param_str |
36a9f844 FF |
127 | |
128 | ||
129 | static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param, | |
130 | - unsigned int val) | |
131 | + const char *ifname, unsigned int val) | |
132 | { | |
133 | struct i802_bss *bss = priv; | |
134 | char path[128]; | |
24d0e746 | 135 | @@ -12402,8 +12402,11 @@ static int wpa_driver_br_set_net_param(v |
36a9f844 FF |
136 | return -EINVAL; |
137 | } | |
138 | ||
139 | + if (!ifname) | |
140 | + ifname = bss->brname; | |
141 | + | |
142 | os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s", | |
143 | - ip_version, bss->brname, param_txt); | |
144 | + ip_version, ifname, param_txt); | |
145 | ||
146 | set_val: | |
147 | if (linux_write_system_file(path, val)) |