diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index f6863fbcf334851d60c1c3315cab22cbfe264f5e..1db774cf9dc2f9526bc4497bdd74a9eecb73c005 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -61,6 +61,7 @@ #define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */ #define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */ #define ETH_P_WCCP 0x883E /* Web-cache coordination protocol * defined in draft-wilson-wrec-wccp-v2-00.txt */ diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 364e0ba4415824df9b5e2141c56b96c4b530cbac..5662567c8aed112722c0163a8e9a32e639ea1b8b 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -131,9 +131,14 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) goto drop; - if (unlikely(is_link_local(dest))) + if (unlikely(is_link_local(dest))) { + /* Pause frames shouldn't be passed up by driver anyway */ + if (skb->protocol == htons(ETH_P_PAUSE)) + goto drop; + return (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, NULL, br_handle_local_finish) == 0) ? skb : NULL; + } switch (p->state) { case BR_STATE_FORWARDING: