linux/net/bridge/br_input.c
<<
>>
Prefs
   1/*
   2 *      Handle incoming frames
   3 *      Linux ethernet bridge
   4 *
   5 *      Authors:
   6 *      Lennert Buytenhek               <buytenh@gnu.org>
   7 *
   8 *      This program is free software; you can redistribute it and/or
   9 *      modify it under the terms of the GNU General Public License
  10 *      as published by the Free Software Foundation; either version
  11 *      2 of the License, or (at your option) any later version.
  12 */
  13
  14#include <linux/slab.h>
  15#include <linux/kernel.h>
  16#include <linux/netdevice.h>
  17#include <linux/etherdevice.h>
  18#include <linux/netfilter_bridge.h>
  19#include <linux/export.h>
  20#include "br_private.h"
  21
  22/* Bridge group multicast address 802.1d (pg 51). */
  23const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
  24
  25/* Hook for brouter */
  26br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
  27EXPORT_SYMBOL(br_should_route_hook);
  28
  29static int br_pass_frame_up(struct sk_buff *skb)
  30{
  31        struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
  32        struct net_bridge *br = netdev_priv(brdev);
  33        struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
  34
  35        u64_stats_update_begin(&brstats->syncp);
  36        brstats->rx_packets++;
  37        brstats->rx_bytes += skb->len;
  38        u64_stats_update_end(&brstats->syncp);
  39
  40        indev = skb->dev;
  41        skb->dev = brdev;
  42
  43        return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
  44                       netif_receive_skb);
  45}
  46
  47/* note: already called with rcu_read_lock */
  48int br_handle_frame_finish(struct sk_buff *skb)
  49{
  50        const unsigned char *dest = eth_hdr(skb)->h_dest;
  51        struct net_bridge_port *p = br_port_get_rcu(skb->dev);
  52        struct net_bridge *br;
  53        struct net_bridge_fdb_entry *dst;
  54        struct net_bridge_mdb_entry *mdst;
  55        struct sk_buff *skb2;
  56
  57        if (!p || p->state == BR_STATE_DISABLED)
  58                goto drop;
  59
  60        /* insert into forwarding database after filtering to avoid spoofing */
  61        br = p->br;
  62        br_fdb_update(br, p, eth_hdr(skb)->h_source);
  63
  64        if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) &&
  65            br_multicast_rcv(br, p, skb))
  66                goto drop;
  67
  68        if (p->state == BR_STATE_LEARNING)
  69                goto drop;
  70
  71        BR_INPUT_SKB_CB(skb)->brdev = br->dev;
  72
  73        /* The packet skb2 goes to the local host (NULL to skip). */
  74        skb2 = NULL;
  75
  76        if (br->dev->flags & IFF_PROMISC)
  77                skb2 = skb;
  78
  79        dst = NULL;
  80
  81        if (is_broadcast_ether_addr(dest))
  82                skb2 = skb;
  83        else if (is_multicast_ether_addr(dest)) {
  84                mdst = br_mdb_get(br, skb);
  85                if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
  86                        if ((mdst && mdst->mglist) ||
  87                            br_multicast_is_router(br))
  88                                skb2 = skb;
  89                        br_multicast_forward(mdst, skb, skb2);
  90                        skb = NULL;
  91                        if (!skb2)
  92                                goto out;
  93                } else
  94                        skb2 = skb;
  95
  96                br->dev->stats.multicast++;
  97        } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) {
  98                skb2 = skb;
  99                /* Do not forward the packet since it's local. */
 100                skb = NULL;
 101        }
 102
 103        if (skb) {
 104                if (dst) {
 105                        dst->used = jiffies;
 106                        br_forward(dst->dst, skb, skb2);
 107                } else
 108                        br_flood_forward(br, skb, skb2);
 109        }
 110
 111        if (skb2)
 112                return br_pass_frame_up(skb2);
 113
 114out:
 115        return 0;
 116drop:
 117        kfree_skb(skb);
 118        goto out;
 119}
 120
 121/* note: already called with rcu_read_lock */
 122static int br_handle_local_finish(struct sk_buff *skb)
 123{
 124        struct net_bridge_port *p = br_port_get_rcu(skb->dev);
 125
 126        br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
 127        return 0;        /* process further */
 128}
 129
 130/* Does address match the link local multicast address.
 131 * 01:80:c2:00:00:0X
 132 */
 133static inline int is_link_local(const unsigned char *dest)
 134{
 135        __be16 *a = (__be16 *)dest;
 136        static const __be16 *b = (const __be16 *)br_group_address;
 137        static const __be16 m = cpu_to_be16(0xfff0);
 138
 139        return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
 140}
 141
 142/*
 143 * Return NULL if skb is handled
 144 * note: already called with rcu_read_lock
 145 */
 146rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
 147{
 148        struct net_bridge_port *p;
 149        struct sk_buff *skb = *pskb;
 150        const unsigned char *dest = eth_hdr(skb)->h_dest;
 151        br_should_route_hook_t *rhook;
 152
 153        if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
 154                return RX_HANDLER_PASS;
 155
 156        if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
 157                goto drop;
 158
 159        skb = skb_share_check(skb, GFP_ATOMIC);
 160        if (!skb)
 161                return RX_HANDLER_CONSUMED;
 162
 163        p = br_port_get_rcu(skb->dev);
 164
 165        if (unlikely(is_link_local(dest))) {
 166                /*
 167                 * See IEEE 802.1D Table 7-10 Reserved addresses
 168                 *
 169                 * Assignment                           Value
 170                 * Bridge Group Address         01-80-C2-00-00-00
 171                 * (MAC Control) 802.3          01-80-C2-00-00-01
 172                 * (Link Aggregation) 802.3     01-80-C2-00-00-02
 173                 * 802.1X PAE address           01-80-C2-00-00-03
 174                 *
 175                 * 802.1AB LLDP                 01-80-C2-00-00-0E
 176                 *
 177                 * Others reserved for future standardization
 178                 */
 179                switch (dest[5]) {
 180                case 0x00:      /* Bridge Group Address */
 181                        /* If STP is turned off,
 182                           then must forward to keep loop detection */
 183                        if (p->br->stp_enabled == BR_NO_STP)
 184                                goto forward;
 185                        break;
 186
 187                case 0x01:      /* IEEE MAC (Pause) */
 188                        goto drop;
 189
 190                default:
 191                        /* Allow selective forwarding for most other protocols */
 192                        if (p->br->group_fwd_mask & (1u << dest[5]))
 193                                goto forward;
 194                }
 195
 196                /* Deliver packet to local host only */
 197                if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
 198                            NULL, br_handle_local_finish)) {
 199                        return RX_HANDLER_CONSUMED; /* consumed by filter */
 200                } else {
 201                        *pskb = skb;
 202                        return RX_HANDLER_PASS; /* continue processing */
 203                }
 204        }
 205
 206forward:
 207        switch (p->state) {
 208        case BR_STATE_FORWARDING:
 209                rhook = rcu_dereference(br_should_route_hook);
 210                if (rhook) {
 211                        if ((*rhook)(skb)) {
 212                                *pskb = skb;
 213                                return RX_HANDLER_PASS;
 214                        }
 215                        dest = eth_hdr(skb)->h_dest;
 216                }
 217                /* fall through */
 218        case BR_STATE_LEARNING:
 219                if (ether_addr_equal(p->br->dev->dev_addr, dest))
 220                        skb->pkt_type = PACKET_HOST;
 221
 222                NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
 223                        br_handle_frame_finish);
 224                break;
 225        default:
 226drop:
 227                kfree_skb(skb);
 228        }
 229        return RX_HANDLER_CONSUMED;
 230}
 231
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.