Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.27-rc5 182 lines 4.2 kB view raw
1/* 2 * Device handling code 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/kernel.h> 15#include <linux/netdevice.h> 16#include <linux/etherdevice.h> 17#include <linux/ethtool.h> 18 19#include <asm/uaccess.h> 20#include "br_private.h" 21 22/* net device transmit always called with no BH (preempt_disabled) */ 23int br_dev_xmit(struct sk_buff *skb, struct net_device *dev) 24{ 25 struct net_bridge *br = netdev_priv(dev); 26 const unsigned char *dest = skb->data; 27 struct net_bridge_fdb_entry *dst; 28 29 dev->stats.tx_packets++; 30 dev->stats.tx_bytes += skb->len; 31 32 skb_reset_mac_header(skb); 33 skb_pull(skb, ETH_HLEN); 34 35 if (dest[0] & 1) 36 br_flood_deliver(br, skb); 37 else if ((dst = __br_fdb_get(br, dest)) != NULL) 38 br_deliver(dst->dst, skb); 39 else 40 br_flood_deliver(br, skb); 41 42 return 0; 43} 44 45static int br_dev_open(struct net_device *dev) 46{ 47 struct net_bridge *br = netdev_priv(dev); 48 49 br_features_recompute(br); 50 netif_start_queue(dev); 51 br_stp_enable_bridge(br); 52 53 return 0; 54} 55 56static void br_dev_set_multicast_list(struct net_device *dev) 57{ 58} 59 60static int br_dev_stop(struct net_device *dev) 61{ 62 br_stp_disable_bridge(netdev_priv(dev)); 63 64 netif_stop_queue(dev); 65 66 return 0; 67} 68 69static int br_change_mtu(struct net_device *dev, int new_mtu) 70{ 71 struct net_bridge *br = netdev_priv(dev); 72 if (new_mtu < 68 || new_mtu > br_min_mtu(br)) 73 return -EINVAL; 74 75 dev->mtu = new_mtu; 76 77#ifdef CONFIG_BRIDGE_NETFILTER 78 /* remember the MTU in the rtable for PMTU */ 79 br->fake_rtable.u.dst.metrics[RTAX_MTU - 1] = new_mtu; 80#endif 81 82 return 0; 83} 84 85/* Allow setting mac address to any valid ethernet address. */ 86static int br_set_mac_address(struct net_device *dev, void *p) 87{ 88 struct net_bridge *br = netdev_priv(dev); 89 struct sockaddr *addr = p; 90 91 if (!is_valid_ether_addr(addr->sa_data)) 92 return -EINVAL; 93 94 spin_lock_bh(&br->lock); 95 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 96 br_stp_change_bridge_id(br, addr->sa_data); 97 br->flags |= BR_SET_MAC_ADDR; 98 spin_unlock_bh(&br->lock); 99 100 return 0; 101} 102 103static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info) 104{ 105 strcpy(info->driver, "bridge"); 106 strcpy(info->version, BR_VERSION); 107 strcpy(info->fw_version, "N/A"); 108 strcpy(info->bus_info, "N/A"); 109} 110 111static int br_set_sg(struct net_device *dev, u32 data) 112{ 113 struct net_bridge *br = netdev_priv(dev); 114 115 if (data) 116 br->feature_mask |= NETIF_F_SG; 117 else 118 br->feature_mask &= ~NETIF_F_SG; 119 120 br_features_recompute(br); 121 return 0; 122} 123 124static int br_set_tso(struct net_device *dev, u32 data) 125{ 126 struct net_bridge *br = netdev_priv(dev); 127 128 if (data) 129 br->feature_mask |= NETIF_F_TSO; 130 else 131 br->feature_mask &= ~NETIF_F_TSO; 132 133 br_features_recompute(br); 134 return 0; 135} 136 137static int br_set_tx_csum(struct net_device *dev, u32 data) 138{ 139 struct net_bridge *br = netdev_priv(dev); 140 141 if (data) 142 br->feature_mask |= NETIF_F_NO_CSUM; 143 else 144 br->feature_mask &= ~NETIF_F_ALL_CSUM; 145 146 br_features_recompute(br); 147 return 0; 148} 149 150static struct ethtool_ops br_ethtool_ops = { 151 .get_drvinfo = br_getinfo, 152 .get_link = ethtool_op_get_link, 153 .get_tx_csum = ethtool_op_get_tx_csum, 154 .set_tx_csum = br_set_tx_csum, 155 .get_sg = ethtool_op_get_sg, 156 .set_sg = br_set_sg, 157 .get_tso = ethtool_op_get_tso, 158 .set_tso = br_set_tso, 159 .get_ufo = ethtool_op_get_ufo, 160 .get_flags = ethtool_op_get_flags, 161}; 162 163void br_dev_setup(struct net_device *dev) 164{ 165 random_ether_addr(dev->dev_addr); 166 ether_setup(dev); 167 168 dev->do_ioctl = br_dev_ioctl; 169 dev->hard_start_xmit = br_dev_xmit; 170 dev->open = br_dev_open; 171 dev->set_multicast_list = br_dev_set_multicast_list; 172 dev->change_mtu = br_change_mtu; 173 dev->destructor = free_netdev; 174 SET_ETHTOOL_OPS(dev, &br_ethtool_ops); 175 dev->stop = br_dev_stop; 176 dev->tx_queue_len = 0; 177 dev->set_mac_address = br_set_mac_address; 178 dev->priv_flags = IFF_EBRIDGE; 179 180 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 181 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX; 182}