br_device.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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. #include <linux/kernel.h>
  16. #include <linux/netdevice.h>
  17. #include <linux/if_bridge.h>
  18. #include <asm/uaccess.h>
  19. #include "br_private.h"
  20. static int br_dev_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  21. {
  22. unsigned long args[4];
  23. unsigned long *data;
  24. if (cmd != SIOCDEVPRIVATE)
  25. return -EOPNOTSUPP;
  26. data = (unsigned long *)rq->ifr_data;
  27. if (copy_from_user(args, data, 4*sizeof(unsigned long)))
  28. return -EFAULT;
  29. return br_ioctl(dev->priv, args[0], args[1], args[2], args[3]);
  30. }
  31. static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
  32. {
  33. struct net_bridge *br;
  34. br = dev->priv;
  35. return &br->statistics;
  36. }
  37. static int __br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
  38. {
  39. struct net_bridge *br;
  40. unsigned char *dest;
  41. struct net_bridge_fdb_entry *dst;
  42. br = dev->priv;
  43. br->statistics.tx_packets++;
  44. br->statistics.tx_bytes += skb->len;
  45. dest = skb->mac.raw = skb->data;
  46. skb_pull(skb, ETH_HLEN);
  47. if (dest[0] & 1) {
  48. br_flood_deliver(br, skb, 0);
  49. return 0;
  50. }
  51. if ((dst = br_fdb_get(br, dest)) != NULL) {
  52. br_deliver(dst->dst, skb);
  53. br_fdb_put(dst);
  54. return 0;
  55. }
  56. br_flood_deliver(br, skb, 0);
  57. return 0;
  58. }
  59. int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
  60. {
  61. struct net_bridge *br;
  62. int ret;
  63. br = dev->priv;
  64. read_lock(&br->lock);
  65. ret = __br_dev_xmit(skb, dev);
  66. read_unlock(&br->lock);
  67. return ret;
  68. }
  69. static int br_dev_open(struct net_device *dev)
  70. {
  71. struct net_bridge *br;
  72. netif_start_queue(dev);
  73. br = dev->priv;
  74. read_lock(&br->lock);
  75. br_stp_enable_bridge(br);
  76. read_unlock(&br->lock);
  77. return 0;
  78. }
  79. static void br_dev_set_multicast_list(struct net_device *dev)
  80. {
  81. }
  82. static int br_dev_stop(struct net_device *dev)
  83. {
  84. struct net_bridge *br;
  85. br = dev->priv;
  86. read_lock(&br->lock);
  87. br_stp_disable_bridge(br);
  88. read_unlock(&br->lock);
  89. netif_stop_queue(dev);
  90. return 0;
  91. }
  92. static int br_dev_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
  93. {
  94. return -1;
  95. }
  96. void br_dev_setup(struct net_device *dev)
  97. {
  98. memset(dev->dev_addr, 0, ETH_ALEN);
  99. dev->do_ioctl = br_dev_do_ioctl;
  100. dev->get_stats = br_dev_get_stats;
  101. dev->hard_start_xmit = br_dev_xmit;
  102. dev->open = br_dev_open;
  103. dev->set_multicast_list = br_dev_set_multicast_list;
  104. dev->stop = br_dev_stop;
  105. dev->accept_fastpath = br_dev_accept_fastpath;
  106. dev->tx_queue_len = 0;
  107. dev->set_mac_address = NULL;
  108. }