linux-old/net/bridge/br_device.c
<<
>>
Prefs
   1/*
   2 *      Device handling code
   3 *      Linux ethernet bridge
   4 *
   5 *      Authors:
   6 *      Lennert Buytenhek               <buytenh@gnu.org>
   7 *
   8 *      $Id: br_device.c,v 1.5.2.1 2001/12/24 00:59:27 davem Exp $
   9 *
  10 *      This program is free software; you can redistribute it and/or
  11 *      modify it under the terms of the GNU General Public License
  12 *      as published by the Free Software Foundation; either version
  13 *      2 of the License, or (at your option) any later version.
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/netdevice.h>
  18#include <linux/if_bridge.h>
  19#include <asm/uaccess.h>
  20#include "br_private.h"
  21
  22static int br_dev_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  23{
  24        unsigned long args[4];
  25        unsigned long *data;
  26
  27        if (cmd != SIOCDEVPRIVATE)
  28                return -EOPNOTSUPP;
  29
  30        data = (unsigned long *)rq->ifr_data;
  31        if (copy_from_user(args, data, 4*sizeof(unsigned long)))
  32                return -EFAULT;
  33
  34        return br_ioctl(dev->priv, args[0], args[1], args[2], args[3]);
  35}
  36
  37static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
  38{
  39        struct net_bridge *br;
  40
  41        br = dev->priv;
  42
  43        return &br->statistics;
  44}
  45
  46static int __br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
  47{
  48        struct net_bridge *br;
  49        unsigned char *dest;
  50        struct net_bridge_fdb_entry *dst;
  51
  52        br = dev->priv;
  53        br->statistics.tx_packets++;
  54        br->statistics.tx_bytes += skb->len;
  55
  56        dest = skb->mac.raw = skb->data;
  57        skb_pull(skb, ETH_HLEN);
  58
  59        if (dest[0] & 1) {
  60                br_flood_deliver(br, skb, 0);
  61                return 0;
  62        }
  63
  64        if ((dst = br_fdb_get(br, dest)) != NULL) {
  65                br_deliver(dst->dst, skb);
  66                br_fdb_put(dst);
  67                return 0;
  68        }
  69
  70        br_flood_deliver(br, skb, 0);
  71        return 0;
  72}
  73
  74int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
  75{
  76        struct net_bridge *br;
  77        int ret;
  78
  79        br = dev->priv;
  80        read_lock(&br->lock);
  81        ret = __br_dev_xmit(skb, dev);
  82        read_unlock(&br->lock);
  83
  84        return ret;
  85}
  86
  87static int br_dev_open(struct net_device *dev)
  88{
  89        struct net_bridge *br;
  90
  91        netif_start_queue(dev);
  92
  93        br = dev->priv;
  94        read_lock(&br->lock);
  95        br_stp_enable_bridge(br);
  96        read_unlock(&br->lock);
  97
  98        return 0;
  99}
 100
 101static void br_dev_set_multicast_list(struct net_device *dev)
 102{
 103}
 104
 105static int br_dev_stop(struct net_device *dev)
 106{
 107        struct net_bridge *br;
 108
 109        br = dev->priv;
 110        read_lock(&br->lock);
 111        br_stp_disable_bridge(br);
 112        read_unlock(&br->lock);
 113
 114        netif_stop_queue(dev);
 115
 116        return 0;
 117}
 118
 119static int br_dev_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
 120{
 121        return -1;
 122}
 123
 124void br_dev_setup(struct net_device *dev)
 125{
 126        memset(dev->dev_addr, 0, ETH_ALEN);
 127
 128        dev->do_ioctl = br_dev_do_ioctl;
 129        dev->get_stats = br_dev_get_stats;
 130        dev->hard_start_xmit = br_dev_xmit;
 131        dev->open = br_dev_open;
 132        dev->set_multicast_list = br_dev_set_multicast_list;
 133        dev->stop = br_dev_stop;
 134        dev->accept_fastpath = br_dev_accept_fastpath;
 135        dev->tx_queue_len = 0;
 136        dev->set_mac_address = NULL;
 137}
 138
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.