740-snoop_iface.patch 5.1 KB

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