On Mon, 12 Mar 2018 23:42:48 +0100
Rafał Miłecki <zaj...@gmail.com> wrote:

> 2) Blame bridge + mcast-to-ucast + hairpin for 802.11f incompatibility
> 
> If we agree that 802.11f support in FullMAC firmware is acceptable, then
> we have to make sure Linux's bridge doesn't break it by passing 802.11f
> (broadcast) frames back to the source interface. That would require a
> check like in below diff + proper code for handling such packets. I'm
> afraid I'm not familiar with bridge code enough to complete that.
> 
> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
> index edae702..9e5d6ea 100644
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> @@ -126,6 +126,27 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct 
> net_bridge *br,
>       }
>   }
> 
> +static bool br_skb_is_iapp_add_packet(struct sk_buff *skb)
> +{
> +     const u8 iapp_add_packet[6] __aligned(2) = {
> +             0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,
> +     };
> +#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
> +     const u16 *a = (const u16 *)skb->data;
> +     const u16 *b = (const u16 *)iapp_add_packet;
> +#endif
> +
> +     if (skb->len != 6)
> +             return false;
> +
> +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
> +     return !(((*(const u32 *)skb->data) ^ (*(const u32 *)iapp_add_packet)) |
> +              ((*(const u16 *)(skb->data + 4)) ^ (*(const u16 
> *)(iapp_add_packet + 4))));
> +#else
> +     return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));
> +#endif
> +}
> +
>   /* note: already called with rcu_read_lock */
>   int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff 
> *skb)
>   {
> @@ -155,6 +176,8 @@ int br_handle_frame_finish(struct net *net, struct sock 
> *sk, struct sk_buff *skb
>       if (is_multicast_ether_addr(dest)) {
>               /* by definition the broadcast is also a multicast address */
>               if (is_broadcast_ether_addr(dest)) {
> +                     if (br_skb_is_iapp_add_packet(skb))
> +                             pr_warn("This packet should not be passed back 
> to the source interface!\n");
>                       pkt_type = BR_PKT_BROADCAST;
>                       local_rcv = true;
>               } else {


Don't like bridge doing special case code for magic received values directly in 
input path.
Really needs to be generic which is why I suggested ebtables.

Reply via email to