diff options
author | Jouni Malinen <jouni@codeaurora.org> | 2015-03-04 05:54:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-05 14:52:23 -0500 |
commit | 842a9ae08a25671db3d4f689eed68b4d64be15b5 (patch) | |
tree | e8159604c1e8cc0abb1868e21ba6f6a5cabad5f7 /net/bridge/br_input.c | |
parent | 787fb2bd42b9d798f4ed85b66e878222a9e28ae6 (diff) |
bridge: Extend Proxy ARP design to allow optional rules for Wi-Fi
This extends the design in commit 958501163ddd ("bridge: Add support for
IEEE 802.11 Proxy ARP") with optional set of rules that are needed to
meet the IEEE 802.11 and Hotspot 2.0 requirements for ProxyARP. The
previously added BR_PROXYARP behavior is left as-is and a new
BR_PROXYARP_WIFI alternative is added so that this behavior can be
configured from user space when required.
In addition, this enables proxyarp functionality for unicast ARP
requests for both BR_PROXYARP and BR_PROXYARP_WIFI since it is possible
to use unicast as well as broadcast for these frames.
The key differences in functionality:
BR_PROXYARP:
- uses the flag on the bridge port on which the request frame was
received to determine whether to reply
- block bridge port flooding completely on ports that enable proxy ARP
BR_PROXYARP_WIFI:
- uses the flag on the bridge port to which the target device of the
request belongs
- block bridge port flooding selectively based on whether the proxyarp
functionality replied
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_input.c')
-rw-r--r-- | net/bridge/br_input.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index e2aa7be3a847..052c5ebbc947 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -60,7 +60,7 @@ static int br_pass_frame_up(struct sk_buff *skb) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, | 62 | static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, |
63 | u16 vid) | 63 | u16 vid, struct net_bridge_port *p) |
64 | { | 64 | { |
65 | struct net_device *dev = br->dev; | 65 | struct net_device *dev = br->dev; |
66 | struct neighbour *n; | 66 | struct neighbour *n; |
@@ -68,6 +68,8 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, | |||
68 | u8 *arpptr, *sha; | 68 | u8 *arpptr, *sha; |
69 | __be32 sip, tip; | 69 | __be32 sip, tip; |
70 | 70 | ||
71 | BR_INPUT_SKB_CB(skb)->proxyarp_replied = false; | ||
72 | |||
71 | if (dev->flags & IFF_NOARP) | 73 | if (dev->flags & IFF_NOARP) |
72 | return; | 74 | return; |
73 | 75 | ||
@@ -105,9 +107,12 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br, | |||
105 | } | 107 | } |
106 | 108 | ||
107 | f = __br_fdb_get(br, n->ha, vid); | 109 | f = __br_fdb_get(br, n->ha, vid); |
108 | if (f) | 110 | if (f && ((p->flags & BR_PROXYARP) || |
111 | (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)))) { | ||
109 | arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip, | 112 | arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip, |
110 | sha, n->ha, sha); | 113 | sha, n->ha, sha); |
114 | BR_INPUT_SKB_CB(skb)->proxyarp_replied = true; | ||
115 | } | ||
111 | 116 | ||
112 | neigh_release(n); | 117 | neigh_release(n); |
113 | } | 118 | } |
@@ -153,12 +158,10 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
153 | 158 | ||
154 | dst = NULL; | 159 | dst = NULL; |
155 | 160 | ||
156 | if (is_broadcast_ether_addr(dest)) { | 161 | if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) |
157 | if (IS_ENABLED(CONFIG_INET) && | 162 | br_do_proxy_arp(skb, br, vid, p); |
158 | p->flags & BR_PROXYARP && | ||
159 | skb->protocol == htons(ETH_P_ARP)) | ||
160 | br_do_proxy_arp(skb, br, vid); | ||
161 | 163 | ||
164 | if (is_broadcast_ether_addr(dest)) { | ||
162 | skb2 = skb; | 165 | skb2 = skb; |
163 | unicast = false; | 166 | unicast = false; |
164 | } else if (is_multicast_ether_addr(dest)) { | 167 | } else if (is_multicast_ether_addr(dest)) { |