linux/net/bridge/br_forward.c
<<
>>
Prefs
   1/*
   2 *      Forwarding decision
   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/err.h>
  15#include <linux/slab.h>
  16#include <linux/kernel.h>
  17#include <linux/netdevice.h>
  18#include <linux/netpoll.h>
  19#include <linux/skbuff.h>
  20#include <linux/if_vlan.h>
  21#include <linux/netfilter_bridge.h>
  22#include "br_private.h"
  23
  24static int deliver_clone(const struct net_bridge_port *prev,
  25                         struct sk_buff *skb,
  26                         void (*__packet_hook)(const struct net_bridge_port *p,
  27                                               struct sk_buff *skb));
  28
  29/* Don't forward packets to originating port or forwarding disabled */
  30static inline int should_deliver(const struct net_bridge_port *p,
  31                                 const struct sk_buff *skb)
  32{
  33        struct net_bridge_vlan_group *vg;
  34
  35        vg = nbp_vlan_group_rcu(p);
  36        return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
  37                br_allowed_egress(vg, skb) && p->state == BR_STATE_FORWARDING;
  38}
  39
  40int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
  41{
  42        if (!is_skb_forwardable(skb->dev, skb))
  43                goto drop;
  44
  45        skb_push(skb, ETH_HLEN);
  46        br_drop_fake_rtable(skb);
  47
  48        if (skb->ip_summed == CHECKSUM_PARTIAL &&
  49            (skb->protocol == htons(ETH_P_8021Q) ||
  50             skb->protocol == htons(ETH_P_8021AD))) {
  51                int depth;
  52
  53                if (!__vlan_get_protocol(skb, skb->protocol, &depth))
  54                        goto drop;
  55
  56                skb_set_network_header(skb, depth);
  57        }
  58
  59        dev_queue_xmit(skb);
  60
  61        return 0;
  62
  63drop:
  64        kfree_skb(skb);
  65        return 0;
  66}
  67EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);
  68
  69int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
  70{
  71        return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING,
  72                       net, sk, skb, NULL, skb->dev,
  73                       br_dev_queue_push_xmit);
  74
  75}
  76EXPORT_SYMBOL_GPL(br_forward_finish);
  77
  78static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
  79{
  80        struct net_bridge_vlan_group *vg;
  81
  82        vg = nbp_vlan_group_rcu(to);
  83        skb = br_handle_vlan(to->br, vg, skb);
  84        if (!skb)
  85                return;
  86
  87        skb->dev = to->dev;
  88
  89        if (unlikely(netpoll_tx_running(to->br->dev))) {
  90                if (!is_skb_forwardable(skb->dev, skb))
  91                        kfree_skb(skb);
  92                else {
  93                        skb_push(skb, ETH_HLEN);
  94                        br_netpoll_send_skb(to, skb);
  95                }
  96                return;
  97        }
  98
  99        NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT,
 100                dev_net(skb->dev), NULL, skb,NULL, skb->dev,
 101                br_forward_finish);
 102}
 103
 104static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
 105{
 106        struct net_bridge_vlan_group *vg;
 107        struct net_device *indev;
 108
 109        if (skb_warn_if_lro(skb)) {
 110                kfree_skb(skb);
 111                return;
 112        }
 113
 114        vg = nbp_vlan_group_rcu(to);
 115        skb = br_handle_vlan(to->br, vg, skb);
 116        if (!skb)
 117                return;
 118
 119        indev = skb->dev;
 120        skb->dev = to->dev;
 121        skb_forward_csum(skb);
 122
 123        NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD,
 124                dev_net(indev), NULL, skb, indev, skb->dev,
 125                br_forward_finish);
 126}
 127
 128/* called with rcu_read_lock */
 129void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 130{
 131        if (to && should_deliver(to, skb)) {
 132                __br_deliver(to, skb);
 133                return;
 134        }
 135
 136        kfree_skb(skb);
 137}
 138EXPORT_SYMBOL_GPL(br_deliver);
 139
 140/* called with rcu_read_lock */
 141void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
 142{
 143        if (to && should_deliver(to, skb)) {
 144                if (skb0)
 145                        deliver_clone(to, skb, __br_forward);
 146                else
 147                        __br_forward(to, skb);
 148                return;
 149        }
 150
 151        if (!skb0)
 152                kfree_skb(skb);
 153}
 154
 155static int deliver_clone(const struct net_bridge_port *prev,
 156                         struct sk_buff *skb,
 157                         void (*__packet_hook)(const struct net_bridge_port *p,
 158                                               struct sk_buff *skb))
 159{
 160        struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
 161
 162        skb = skb_clone(skb, GFP_ATOMIC);
 163        if (!skb) {
 164                dev->stats.tx_dropped++;
 165                return -ENOMEM;
 166        }
 167
 168        __packet_hook(prev, skb);
 169        return 0;
 170}
 171
 172static struct net_bridge_port *maybe_deliver(
 173        struct net_bridge_port *prev, struct net_bridge_port *p,
 174        struct sk_buff *skb,
 175        void (*__packet_hook)(const struct net_bridge_port *p,
 176                              struct sk_buff *skb))
 177{
 178        int err;
 179
 180        if (!should_deliver(p, skb))
 181                return prev;
 182
 183        if (!prev)
 184                goto out;
 185
 186        err = deliver_clone(prev, skb, __packet_hook);
 187        if (err)
 188                return ERR_PTR(err);
 189
 190out:
 191        return p;
 192}
 193
 194/* called under bridge lock */
 195static void br_flood(struct net_bridge *br, struct sk_buff *skb,
 196                     struct sk_buff *skb0,
 197                     void (*__packet_hook)(const struct net_bridge_port *p,
 198                                           struct sk_buff *skb),
 199                     bool unicast)
 200{
 201        struct net_bridge_port *p;
 202        struct net_bridge_port *prev;
 203
 204        prev = NULL;
 205
 206        list_for_each_entry_rcu(p, &br->port_list, list) {
 207                /* Do not flood unicast traffic to ports that turn it off */
 208                if (unicast && !(p->flags & BR_FLOOD))
 209                        continue;
 210
 211                /* Do not flood to ports that enable proxy ARP */
 212                if (p->flags & BR_PROXYARP)
 213                        continue;
 214                if ((p->flags & BR_PROXYARP_WIFI) &&
 215                    BR_INPUT_SKB_CB(skb)->proxyarp_replied)
 216                        continue;
 217
 218                prev = maybe_deliver(prev, p, skb, __packet_hook);
 219                if (IS_ERR(prev))
 220                        goto out;
 221        }
 222
 223        if (!prev)
 224                goto out;
 225
 226        if (skb0)
 227                deliver_clone(prev, skb, __packet_hook);
 228        else
 229                __packet_hook(prev, skb);
 230        return;
 231
 232out:
 233        if (!skb0)
 234                kfree_skb(skb);
 235}
 236
 237
 238/* called with rcu_read_lock */
 239void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast)
 240{
 241        br_flood(br, skb, NULL, __br_deliver, unicast);
 242}
 243
 244/* called under bridge lock */
 245void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
 246                      struct sk_buff *skb2, bool unicast)
 247{
 248        br_flood(br, skb, skb2, __br_forward, unicast);
 249}
 250
 251#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 252/* called with rcu_read_lock */
 253static void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
 254                               struct sk_buff *skb, struct sk_buff *skb0,
 255                               void (*__packet_hook)(
 256                                        const struct net_bridge_port *p,
 257                                        struct sk_buff *skb))
 258{
 259        struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
 260        struct net_bridge *br = netdev_priv(dev);
 261        struct net_bridge_port *prev = NULL;
 262        struct net_bridge_port_group *p;
 263        struct hlist_node *rp;
 264
 265        rp = rcu_dereference(hlist_first_rcu(&br->router_list));
 266        p = mdst ? rcu_dereference(mdst->ports) : NULL;
 267        while (p || rp) {
 268                struct net_bridge_port *port, *lport, *rport;
 269
 270                lport = p ? p->port : NULL;
 271                rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) :
 272                             NULL;
 273
 274                port = (unsigned long)lport > (unsigned long)rport ?
 275                       lport : rport;
 276
 277                prev = maybe_deliver(prev, port, skb, __packet_hook);
 278                if (IS_ERR(prev))
 279                        goto out;
 280
 281                if ((unsigned long)lport >= (unsigned long)port)
 282                        p = rcu_dereference(p->next);
 283                if ((unsigned long)rport >= (unsigned long)port)
 284                        rp = rcu_dereference(hlist_next_rcu(rp));
 285        }
 286
 287        if (!prev)
 288                goto out;
 289
 290        if (skb0)
 291                deliver_clone(prev, skb, __packet_hook);
 292        else
 293                __packet_hook(prev, skb);
 294        return;
 295
 296out:
 297        if (!skb0)
 298                kfree_skb(skb);
 299}
 300
 301/* called with rcu_read_lock */
 302void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
 303                          struct sk_buff *skb)
 304{
 305        br_multicast_flood(mdst, skb, NULL, __br_deliver);
 306}
 307
 308/* called with rcu_read_lock */
 309void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
 310                          struct sk_buff *skb, struct sk_buff *skb2)
 311{
 312        br_multicast_flood(mdst, skb, skb2, __br_forward);
 313}
 314#endif
 315