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 diasabled */
  30static inline int should_deliver(const struct net_bridge_port *p,
  31                                 const struct sk_buff *skb)
  32{
  33        return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
  34                br_allowed_egress(p->br, nbp_get_vlan_info(p), skb) &&
  35                p->state == BR_STATE_FORWARDING);
  36}
  37
  38static inline unsigned int packet_length(const struct sk_buff *skb)
  39{
  40        return skb->len - (skb->protocol == htons(ETH_P_8021Q) ? VLAN_HLEN : 0);
  41}
  42
  43int br_dev_queue_push_xmit(struct sk_buff *skb)
  44{
  45        /* ip_fragment doesn't copy the MAC header */
  46        if (nf_bridge_maybe_copy_header(skb) ||
  47            (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))) {
  48                kfree_skb(skb);
  49        } else {
  50                skb_push(skb, ETH_HLEN);
  51                br_drop_fake_rtable(skb);
  52                dev_queue_xmit(skb);
  53        }
  54
  55        return 0;
  56}
  57
  58int br_forward_finish(struct sk_buff *skb)
  59{
  60        return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
  61                       br_dev_queue_push_xmit);
  62
  63}
  64
  65static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
  66{
  67        skb = br_handle_vlan(to->br, nbp_get_vlan_info(to), skb);
  68        if (!skb)
  69                return;
  70
  71        skb->dev = to->dev;
  72
  73        if (unlikely(netpoll_tx_running(to->br->dev))) {
  74                if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
  75                        kfree_skb(skb);
  76                else {
  77                        skb_push(skb, ETH_HLEN);
  78                        br_netpoll_send_skb(to, skb);
  79                }
  80                return;
  81        }
  82
  83        NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
  84                br_forward_finish);
  85}
  86
  87static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
  88{
  89        struct net_device *indev;
  90
  91        if (skb_warn_if_lro(skb)) {
  92                kfree_skb(skb);
  93                return;
  94        }
  95
  96        skb = br_handle_vlan(to->br, nbp_get_vlan_info(to), skb);
  97        if (!skb)
  98                return;
  99
 100        indev = skb->dev;
 101        skb->dev = to->dev;
 102        skb_forward_csum(skb);
 103
 104        NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
 105                br_forward_finish);
 106}
 107
 108/* called with rcu_read_lock */
 109void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 110{
 111        if (to && should_deliver(to, skb)) {
 112                __br_deliver(to, skb);
 113                return;
 114        }
 115
 116        kfree_skb(skb);
 117}
 118
 119/* called with rcu_read_lock */
 120void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
 121{
 122        if (should_deliver(to, skb)) {
 123                if (skb0)
 124                        deliver_clone(to, skb, __br_forward);
 125                else
 126                        __br_forward(to, skb);
 127                return;
 128        }
 129
 130        if (!skb0)
 131                kfree_skb(skb);
 132}
 133
 134static int deliver_clone(const struct net_bridge_port *prev,
 135                         struct sk_buff *skb,
 136                         void (*__packet_hook)(const struct net_bridge_port *p,
 137                                               struct sk_buff *skb))
 138{
 139        struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
 140
 141        skb = skb_clone(skb, GFP_ATOMIC);
 142        if (!skb) {
 143                dev->stats.tx_dropped++;
 144                return -ENOMEM;
 145        }
 146
 147        __packet_hook(prev, skb);
 148        return 0;
 149}
 150
 151static struct net_bridge_port *maybe_deliver(
 152        struct net_bridge_port *prev, struct net_bridge_port *p,
 153        struct sk_buff *skb,
 154        void (*__packet_hook)(const struct net_bridge_port *p,
 155                              struct sk_buff *skb))
 156{
 157        int err;
 158
 159        if (!should_deliver(p, skb))
 160                return prev;
 161
 162        if (!prev)
 163                goto out;
 164
 165        err = deliver_clone(prev, skb, __packet_hook);
 166        if (err)
 167                return ERR_PTR(err);
 168
 169out:
 170        return p;
 171}
 172
 173/* called under bridge lock */
 174static void br_flood(struct net_bridge *br, struct sk_buff *skb,
 175                     struct sk_buff *skb0,
 176                     void (*__packet_hook)(const struct net_bridge_port *p,
 177                                           struct sk_buff *skb),
 178                     bool unicast)
 179{
 180        struct net_bridge_port *p;
 181        struct net_bridge_port *prev;
 182
 183        prev = NULL;
 184
 185        list_for_each_entry_rcu(p, &br->port_list, list) {
 186                /* Do not flood unicast traffic to ports that turn it off */
 187                if (unicast && !(p->flags & BR_FLOOD))
 188                        continue;
 189                prev = maybe_deliver(prev, p, skb, __packet_hook);
 190                if (IS_ERR(prev))
 191                        goto out;
 192        }
 193
 194        if (!prev)
 195                goto out;
 196
 197        if (skb0)
 198                deliver_clone(prev, skb, __packet_hook);
 199        else
 200                __packet_hook(prev, skb);
 201        return;
 202
 203out:
 204        if (!skb0)
 205                kfree_skb(skb);
 206}
 207
 208
 209/* called with rcu_read_lock */
 210void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast)
 211{
 212        br_flood(br, skb, NULL, __br_deliver, unicast);
 213}
 214
 215/* called under bridge lock */
 216void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
 217                      struct sk_buff *skb2, bool unicast)
 218{
 219        br_flood(br, skb, skb2, __br_forward, unicast);
 220}
 221
 222#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 223/* called with rcu_read_lock */
 224static void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
 225                               struct sk_buff *skb, struct sk_buff *skb0,
 226                               void (*__packet_hook)(
 227                                        const struct net_bridge_port *p,
 228                                        struct sk_buff *skb))
 229{
 230        struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
 231        struct net_bridge *br = netdev_priv(dev);
 232        struct net_bridge_port *prev = NULL;
 233        struct net_bridge_port_group *p;
 234        struct hlist_node *rp;
 235
 236        rp = rcu_dereference(hlist_first_rcu(&br->router_list));
 237        p = mdst ? rcu_dereference(mdst->ports) : NULL;
 238        while (p || rp) {
 239                struct net_bridge_port *port, *lport, *rport;
 240
 241                lport = p ? p->port : NULL;
 242                rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) :
 243                             NULL;
 244
 245                port = (unsigned long)lport > (unsigned long)rport ?
 246                       lport : rport;
 247
 248                prev = maybe_deliver(prev, port, skb, __packet_hook);
 249                if (IS_ERR(prev))
 250                        goto out;
 251
 252                if ((unsigned long)lport >= (unsigned long)port)
 253                        p = rcu_dereference(p->next);
 254                if ((unsigned long)rport >= (unsigned long)port)
 255                        rp = rcu_dereference(hlist_next_rcu(rp));
 256        }
 257
 258        if (!prev)
 259                goto out;
 260
 261        if (skb0)
 262                deliver_clone(prev, skb, __packet_hook);
 263        else
 264                __packet_hook(prev, skb);
 265        return;
 266
 267out:
 268        if (!skb0)
 269                kfree_skb(skb);
 270}
 271
 272/* called with rcu_read_lock */
 273void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
 274                          struct sk_buff *skb)
 275{
 276        br_multicast_flood(mdst, skb, NULL, __br_deliver);
 277}
 278
 279/* called with rcu_read_lock */
 280void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
 281                          struct sk_buff *skb, struct sk_buff *skb2)
 282{
 283        br_multicast_flood(mdst, skb, skb2, __br_forward);
 284}
 285#endif
 286