8

I have a WiFi Access Point connected to a Linux Router. The Router is itself connected to the Internet. For multiple reasons (mostly to control security and quality of service), I want to force all the users' traffic to go through the Linux router, even the traffic between users.

To do this, I disabled station-to-station communications in the AP (I use a D-Link DWL-7200 AP). Here's how I configured the AP:

ssh admin@accesspoint1
D-Link Access Point wlan1 -> set sta2sta disable
D-Link Access Point wlan1 -> reboot

This works fine: wireless users cannot communicate with each other anymore. At least not directly. My goal is to force the traffic up to the router and back.

To do that, I enabled proxy-arp in the Linux Router:

echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp

Here's the big picture.

                  10.0.0.0/8 subnet    
   ____________________|______________________
  /                                           \
  |                                           |

               (sta2sta disabled)
  UserA----------------AP---------------------Router-------------------Internet
10.0.0.55             /                   eth1     eth0
                     /                10.0.0.1     203.0.113.15
                    /        proxy-arp enabled
  UserB____________/
10.0.0.66

Here's what I hoped would happen if UserA pinged UserB:

  1. UserA tries to ping 10.0.0.66
  2. so UserA sends ARP broadcast saying "Who has 10.0.0.66?"
  3. Access point lets the request through to the router (but not to UserB, because sta2sta is disabled)
  4. the router receives the request, and because proxy-arp is enabled on eth1, it should answer "Send packets for 10.0.0.66 to me (router's MAC address)".
  5. the access point should receive the answer and relay it to UserA.
  6. then the UserA should send the actual ping packet to the router's MAC address
  7. the packet should go through the AP to the router
  8. The router should route it back to eth1, by changing the destination MAC address to that of UserB (doing an ARP request if needed), and changing the source MAC address to its own.
  9. The packet should reach the AP and be relayed to UserB.
  10. UserB should reply to the ping request.
  11. the reply should go through the AP to the router.
  12. the reply should be routed to UserA.
  13. and it should go through the AP and reach UserA.

Unfortunately, this whole dream fails at step 4, because the Linux router receives the ARP request but fails to answer it. From what I read on the Internet, it seems that this is normal: proxy-ARP is not really designed to be used in this kind of setup. To be more precise: the router does not answer ARP requests for hosts that are on the same interface as the ARP request came from. In this case, the ARP request comes from eth1, but it says "Who has IP 10.0.0.66?", and host 10.0.0.66 is on interface eth1.

I understand why this is a good default behaviour, because if sta2sta was not disabled in the AP, UserA would receive an ARP response from the router and another ARP response from UserB. But in my case, I believe it would make perfect sense to answer each and every ARP request, even for hosts on the same interface.

Is there any way I can work around this default proxy-arp behaviour?

2 Answers 2

8

What you want is actually possible, but requires a pretty recent Linux kernel (>= 2.6.34, or a backport).

The option you need is /proc/sys/net/ipv4/conf/*/proxy_arp_pvlan:

proxy_arp_pvlan - BOOLEAN
    Private VLAN proxy arp.
    Basically allow proxy arp replies back to the same interface
    (from which the ARP request/solicitation was received).

    This is done to support (ethernet) switch features, like RFC
    3069, where the individual ports are NOT allowed to
    communicate with each other, but they are allowed to talk to
    the upstream router.  As described in RFC 3069, it is possible
    to allow these hosts to communicate through the upstream
    router by proxy_arp'ing. Don't need to be used together with
    proxy_arp.

    This technology is known by different names:
      In RFC 3069 it is called VLAN Aggregation.
      Cisco and Allied Telesyn call it Private VLAN.
      Hewlett-Packard call it Source-Port filtering or port-isolation.
      Ericsson call it MAC-Forced Forwarding (RFC Draft).

The upstream commit adding this support is 65324144b50bc7022cc9b6ca8f4a536a957019e3.

0

I am not sure the Linux proxyarp implementation can easily be tweaked to accomplish your goal. Have you considered using a subnetting/routing approach?

Here is the idea: Allocate, say, a /24 address space for your wireless network. To match the example of your question, I'll use 10.0.0.0/24. Now carve up that /24 into 62 /30 subnets: 10.0.0.4/30, 10.0.0.8/30, 10.0.0.12/30, ... 10.0.0.248/30.

Each /30 has 2 usable IP addresses, one of which is assigned to a wireless client, and the other is assigned (aliased) to the eth1 interface of your Linux router. To be concrete, let's say we assign wireless clients addresses from this series: 10.0.0.6, 10.0.0.10, 10.0.0.14, ..., 10.0.0.250. And we alias the following series of IPs to eth1 on the router: 10.0.0.5, 10.0.0.9, 10.0.0.13, ..., 10.0.0.249.

To complete the configuration, each wireless client gets a netmask of 255.255.255.252 and a default gateway of 10.0.0.X-1 (where X is the last octet of the client's IP address). On the router, the ip command can be used to add the IP addresses to eth1, as follows:

ip addr add 10.0.0.5/30 broadcast 10.0.0.7 dev eth1
ip addr add 10.0.0.9/30 broadcast 10.0.0.11 dev eth1
ip addr add 10.0.0.13/30 broadcast 10.0.0.15 dev eth1
...
...
ip addr add 10.0.0.249/30 broadcast 10.0.0.251 dev eth1

Pros:

  • Accomplishes the desired goal: All wireless client traffic is forwarded through the router, and clients can contact each other.
  • ARP broadcasts happen rarely, since each client's first hop is always the router.

Cons:

  • Configuration is unconventional. A static setup (clients and router) can be done fairly easily, but a dynamic (DHCP) configuration will be very challenging to establish.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .