Commit afab4c80 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/network-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents d6266c68 399f8927
...@@ -642,8 +642,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG) ...@@ -642,8 +642,7 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
(pdev->device == PCI_DEVICE_ID_SGI_ACENIC))) (pdev->device == PCI_DEVICE_ID_SGI_ACENIC)))
continue; continue;
dev = init_etherdev(NULL, sizeof(struct ace_private)); dev = alloc_etherdev(sizeof(struct ace_private));
if (dev == NULL) { if (dev == NULL) {
printk(KERN_ERR "acenic: Unable to allocate " printk(KERN_ERR "acenic: Unable to allocate "
"net_device structure!\n"); "net_device structure!\n");
...@@ -653,13 +652,6 @@ int __devinit acenic_probe (ACE_PROBE_ARG) ...@@ -653,13 +652,6 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev); SET_NETDEV_DEV(dev, &pdev->dev);
if (!dev->priv)
dev->priv = kmalloc(sizeof(*ap), GFP_KERNEL);
if (!dev->priv) {
printk(KERN_ERR "acenic: Unable to allocate memory\n");
return -ENOMEM;
}
ap = dev->priv; ap = dev->priv;
ap->pdev = pdev; ap->pdev = pdev;
...@@ -739,6 +731,12 @@ int __devinit acenic_probe (ACE_PROBE_ARG) ...@@ -739,6 +731,12 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
break; break;
} }
if (register_netdev(dev)) {
printk(KERN_ERR "acenic: device registration failed\n");
kfree(dev);
continue;
}
switch(pdev->vendor) { switch(pdev->vendor) {
case PCI_VENDOR_ID_ALTEON: case PCI_VENDOR_ID_ALTEON:
if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) { if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) {
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
*/ */
static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, struct net_device *alloc_netdev(int sizeof_priv, const char *mask,
void (*setup)(struct net_device *)) void (*setup)(struct net_device *))
{ {
struct net_device *dev; struct net_device *dev;
...@@ -96,6 +96,7 @@ static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, ...@@ -96,6 +96,7 @@ static struct net_device *alloc_netdev(int sizeof_priv, const char *mask,
return dev; return dev;
} }
EXPORT_SYMBOL(alloc_netdev);
static struct net_device *init_alloc_dev(int sizeof_priv) static struct net_device *init_alloc_dev(int sizeof_priv)
{ {
......
...@@ -2676,7 +2676,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, ...@@ -2676,7 +2676,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
*/ */
if (pdev->vendor == PCI_VENDOR_ID_SUN && if (pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_GEM && pdev->device == PCI_DEVICE_ID_SUN_GEM &&
!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) { !pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) {
pci_using_dac = 1; pci_using_dac = 1;
} else { } else {
err = pci_set_dma_mask(pdev, (u64) 0xffffffff); err = pci_set_dma_mask(pdev, (u64) 0xffffffff);
......
...@@ -805,14 +805,14 @@ struct gem_txd { ...@@ -805,14 +805,14 @@ struct gem_txd {
u64 buffer; u64 buffer;
}; };
#define TXDCTRL_BUFSZ 0x0000000000007fff /* Buffer Size */ #define TXDCTRL_BUFSZ 0x0000000000007fffULL /* Buffer Size */
#define TXDCTRL_CSTART 0x00000000001f8000 /* CSUM Start Offset */ #define TXDCTRL_CSTART 0x00000000001f8000ULL /* CSUM Start Offset */
#define TXDCTRL_COFF 0x000000001fe00000 /* CSUM Stuff Offset */ #define TXDCTRL_COFF 0x000000001fe00000ULL /* CSUM Stuff Offset */
#define TXDCTRL_CENAB 0x0000000020000000 /* CSUM Enable */ #define TXDCTRL_CENAB 0x0000000020000000ULL /* CSUM Enable */
#define TXDCTRL_EOF 0x0000000040000000 /* End of Frame */ #define TXDCTRL_EOF 0x0000000040000000ULL /* End of Frame */
#define TXDCTRL_SOF 0x0000000080000000 /* Start of Frame */ #define TXDCTRL_SOF 0x0000000080000000ULL /* Start of Frame */
#define TXDCTRL_INTME 0x0000000100000000 /* "Interrupt Me" */ #define TXDCTRL_INTME 0x0000000100000000ULL /* "Interrupt Me" */
#define TXDCTRL_NOCRC 0x0000000200000000 /* No CRC Present */ #define TXDCTRL_NOCRC 0x0000000200000000ULL /* No CRC Present */
/* GEM requires that RX descriptors are provided four at a time, /* GEM requires that RX descriptors are provided four at a time,
* aligned. Also, the RX ring may not wrap around. This means that * aligned. Also, the RX ring may not wrap around. This means that
...@@ -840,13 +840,13 @@ struct gem_rxd { ...@@ -840,13 +840,13 @@ struct gem_rxd {
u64 buffer; u64 buffer;
}; };
#define RXDCTRL_TCPCSUM 0x000000000000ffff /* TCP Pseudo-CSUM */ #define RXDCTRL_TCPCSUM 0x000000000000ffffULL /* TCP Pseudo-CSUM */
#define RXDCTRL_BUFSZ 0x000000007fff0000 /* Buffer Size */ #define RXDCTRL_BUFSZ 0x000000007fff0000ULL /* Buffer Size */
#define RXDCTRL_OWN 0x0000000080000000 /* GEM owns this entry */ #define RXDCTRL_OWN 0x0000000080000000ULL /* GEM owns this entry */
#define RXDCTRL_HASHVAL 0x0ffff00000000000 /* Hash Value */ #define RXDCTRL_HASHVAL 0x0ffff00000000000ULL /* Hash Value */
#define RXDCTRL_HPASS 0x1000000000000000 /* Passed Hash Filter */ #define RXDCTRL_HPASS 0x1000000000000000ULL /* Passed Hash Filter */
#define RXDCTRL_ALTMAC 0x2000000000000000 /* Matched ALT MAC */ #define RXDCTRL_ALTMAC 0x2000000000000000ULL /* Matched ALT MAC */
#define RXDCTRL_BAD 0x4000000000000000 /* Frame has bad CRC */ #define RXDCTRL_BAD 0x4000000000000000ULL /* Frame has bad CRC */
#define RXDCTRL_FRESH(gp) \ #define RXDCTRL_FRESH(gp) \
((((RX_BUF_ALLOC_SIZE(gp) - RX_OFFSET) << 16) & RXDCTRL_BUFSZ) | \ ((((RX_BUF_ALLOC_SIZE(gp) - RX_OFFSET) << 16) & RXDCTRL_BUFSZ) | \
......
...@@ -32,10 +32,6 @@ ...@@ -32,10 +32,6 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#ifndef PCI_DMA_BUS_IS_PHYS
#define PCI_DMA_BUS_IS_PHYS 1
#endif
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#define TG3_VLAN_TAG_USED 1 #define TG3_VLAN_TAG_USED 1
#else #else
...@@ -55,8 +51,8 @@ ...@@ -55,8 +51,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.5" #define DRV_MODULE_VERSION "1.6"
#define DRV_MODULE_RELDATE "March 21, 2003" #define DRV_MODULE_RELDATE "June 11, 2003"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
...@@ -2234,73 +2230,17 @@ static void tg3_tx_timeout(struct net_device *dev) ...@@ -2234,73 +2230,17 @@ static void tg3_tx_timeout(struct net_device *dev)
schedule_work(&tp->reset_task); schedule_work(&tp->reset_task);
} }
#if !PCI_DMA_BUS_IS_PHYS
static void tg3_set_txd_addr(struct tg3 *tp, int entry, dma_addr_t mapping)
{
if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) {
struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry];
txd->addr_hi = ((u64) mapping >> 32);
txd->addr_lo = ((u64) mapping & 0xffffffff);
} else {
unsigned long txd;
txd = (tp->regs +
NIC_SRAM_WIN_BASE +
NIC_SRAM_TX_BUFFER_DESC);
txd += (entry * TXD_SIZE);
if (sizeof(dma_addr_t) != sizeof(u32))
writel(((u64) mapping >> 32),
txd + TXD_ADDR + TG3_64BIT_REG_HIGH);
writel(((u64) mapping & 0xffffffff),
txd + TXD_ADDR + TG3_64BIT_REG_LOW);
}
}
#endif
static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
u32 guilty_entry, int guilty_len, u32 guilty_entry, int guilty_len,
u32 last_plus_one, u32 *start, u32 mss) u32 last_plus_one, u32 *start, u32 mss)
{ {
struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
dma_addr_t new_addr; dma_addr_t new_addr;
u32 entry = *start; u32 entry = *start;
int i; int i;
#if !PCI_DMA_BUS_IS_PHYS
/* IOMMU, just map the guilty area again which is guaranteed to
* use different addresses.
*/
i = 0;
while (entry != guilty_entry) {
entry = NEXT_TX(entry);
i++;
}
if (i == 0) {
new_addr = pci_map_single(tp->pdev, skb->data, guilty_len,
PCI_DMA_TODEVICE);
} else {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
new_addr = pci_map_page(tp->pdev,
frag->page, frag->page_offset,
guilty_len, PCI_DMA_TODEVICE);
}
pci_unmap_single(tp->pdev, pci_unmap_addr(&tp->tx_buffers[guilty_entry],
mapping),
guilty_len, PCI_DMA_TODEVICE);
tg3_set_txd_addr(tp, guilty_entry, new_addr);
pci_unmap_addr_set(&tp->tx_buffers[guilty_entry], mapping,
new_addr);
*start = last_plus_one;
#else
/* Oh well, no IOMMU, have to allocate a whole new SKB. */
struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
if (!new_skb) { if (!new_skb) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
return -1; return -1;
...@@ -2337,7 +2277,6 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, ...@@ -2337,7 +2277,6 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
} }
dev_kfree_skb(skb); dev_kfree_skb(skb);
#endif
return 0; return 0;
} }
......
...@@ -122,12 +122,6 @@ int tun_net_init(struct net_device *dev) ...@@ -122,12 +122,6 @@ int tun_net_init(struct net_device *dev)
DBG(KERN_INFO "%s: tun_net_init\n", tun->name); DBG(KERN_INFO "%s: tun_net_init\n", tun->name);
SET_MODULE_OWNER(dev);
dev->open = tun_net_open;
dev->hard_start_xmit = tun_net_xmit;
dev->stop = tun_net_close;
dev->get_stats = tun_net_stats;
switch (tun->flags & TUN_TYPE_MASK) { switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV: case TUN_TUN_DEV:
/* Point-to-Point TUN Device */ /* Point-to-Point TUN Device */
...@@ -199,14 +193,14 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, ...@@ -199,14 +193,14 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
skb_reserve(skb, 2); skb_reserve(skb, 2);
memcpy_fromiovec(skb_put(skb, len), iv, len); memcpy_fromiovec(skb_put(skb, len), iv, len);
skb->dev = &tun->dev; skb->dev = tun->dev;
switch (tun->flags & TUN_TYPE_MASK) { switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV: case TUN_TUN_DEV:
skb->mac.raw = skb->data; skb->mac.raw = skb->data;
skb->protocol = pi.proto; skb->protocol = pi.proto;
break; break;
case TUN_TAP_DEV: case TUN_TAP_DEV:
skb->protocol = eth_type_trans(skb, &tun->dev); skb->protocol = eth_type_trans(skb, tun->dev);
break; break;
}; };
...@@ -325,7 +319,7 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv, ...@@ -325,7 +319,7 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
schedule(); schedule();
continue; continue;
} }
netif_start_queue(&tun->dev); netif_start_queue(tun->dev);
ret = tun_put_user(tun, skb, (struct iovec *) iv, len); ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
...@@ -347,6 +341,24 @@ static ssize_t tun_chr_read(struct file * file, char * buf, ...@@ -347,6 +341,24 @@ static ssize_t tun_chr_read(struct file * file, char * buf,
return tun_chr_readv(file, &iv, 1, pos); return tun_chr_readv(file, &iv, 1, pos);
} }
static void tun_setup(struct net_device *dev)
{
struct tun_struct *tun = dev->priv;
skb_queue_head_init(&tun->readq);
init_waitqueue_head(&tun->read_wait);
tun->owner = -1;
dev->init = tun_net_init;
tun->name = dev->name;
SET_MODULE_OWNER(dev);
dev->open = tun_net_open;
dev->hard_start_xmit = tun_net_xmit;
dev->stop = tun_net_close;
dev->get_stats = tun_net_stats;
dev->destructor = (void (*)(struct net_device *))kfree;
}
static int tun_set_iff(struct file *file, struct ifreq *ifr) static int tun_set_iff(struct file *file, struct ifreq *ifr)
{ {
struct tun_struct *tun; struct tun_struct *tun;
...@@ -367,30 +379,18 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr) ...@@ -367,30 +379,18 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
return -EPERM; return -EPERM;
} else { } else {
char *name; char *name;
unsigned long flags = 0;
/* Allocate new device */
if (!(tun = kmalloc(sizeof(struct tun_struct), GFP_KERNEL)) )
return -ENOMEM;
memset(tun, 0, sizeof(struct tun_struct));
skb_queue_head_init(&tun->readq);
init_waitqueue_head(&tun->read_wait);
tun->owner = -1;
tun->dev.init = tun_net_init;
tun->dev.priv = tun;
SET_MODULE_OWNER(&tun->dev);
err = -EINVAL; err = -EINVAL;
/* Set dev type */ /* Set dev type */
if (ifr->ifr_flags & IFF_TUN) { if (ifr->ifr_flags & IFF_TUN) {
/* TUN device */ /* TUN device */
tun->flags |= TUN_TUN_DEV; flags |= TUN_TUN_DEV;
name = "tun%d"; name = "tun%d";
} else if (ifr->ifr_flags & IFF_TAP) { } else if (ifr->ifr_flags & IFF_TAP) {
/* TAP device */ /* TAP device */
tun->flags |= TUN_TAP_DEV; flags |= TUN_TAP_DEV;
name = "tap%d"; name = "tap%d";
} else } else
goto failed; goto failed;
...@@ -398,12 +398,27 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr) ...@@ -398,12 +398,27 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
if (*ifr->ifr_name) if (*ifr->ifr_name)
name = ifr->ifr_name; name = ifr->ifr_name;
if ((err = dev_alloc_name(&tun->dev, name)) < 0) dev = alloc_netdev(sizeof(struct tun_struct), name,
goto failed; tun_setup);
if ((err = register_netdevice(&tun->dev))) if (!dev)
return -ENOMEM;
tun = dev->priv;
tun->flags = flags;
if (strchr(dev->name, '%')) {
err = dev_alloc_name(dev, dev->name);
if (err < 0) {
kfree(dev);
goto failed;
}
}
if ((err = register_netdevice(tun->dev))) {
kfree(dev);
goto failed; goto failed;
}
tun->name = tun->dev.name;
} }
DBG(KERN_INFO "%s: tun_set_iff\n", tun->name); DBG(KERN_INFO "%s: tun_set_iff\n", tun->name);
...@@ -419,9 +434,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr) ...@@ -419,9 +434,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
strcpy(ifr->ifr_name, tun->name); strcpy(ifr->ifr_name, tun->name);
return 0; return 0;
failed:
failed:
kfree(tun);
return err; return err;
} }
...@@ -548,10 +561,8 @@ static int tun_chr_close(struct inode *inode, struct file *file) ...@@ -548,10 +561,8 @@ static int tun_chr_close(struct inode *inode, struct file *file)
/* Drop read queue */ /* Drop read queue */
skb_queue_purge(&tun->readq); skb_queue_purge(&tun->readq);
if (!(tun->flags & TUN_PERSIST)) { if (!(tun->flags & TUN_PERSIST))
dev_close(&tun->dev); unregister_netdevice(tun->dev);
unregister_netdevice(&tun->dev);
}
rtnl_unlock(); rtnl_unlock();
...@@ -574,11 +585,10 @@ static struct file_operations tun_fops = { ...@@ -574,11 +585,10 @@ static struct file_operations tun_fops = {
.fasync = tun_chr_fasync .fasync = tun_chr_fasync
}; };
static struct miscdevice tun_miscdev= static struct miscdevice tun_miscdev = {
{ .minor = TUN_MINOR,
TUN_MINOR, .name = "net/tun",
"net/tun", .fops = &tun_fops
&tun_fops
}; };
int __init tun_init(void) int __init tun_init(void)
......
...@@ -40,7 +40,6 @@ extern int eth_header_parse(struct sk_buff *skb, ...@@ -40,7 +40,6 @@ extern int eth_header_parse(struct sk_buff *skb,
unsigned char *haddr); unsigned char *haddr);
extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_priv); extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_priv);
extern struct net_device *alloc_etherdev(int sizeof_priv); extern struct net_device *alloc_etherdev(int sizeof_priv);
static inline void eth_copy_and_sum (struct sk_buff *dest, unsigned char *src, int len, int base) static inline void eth_copy_and_sum (struct sk_buff *dest, unsigned char *src, int len, int base)
{ {
memcpy (dest->data, src, len); memcpy (dest->data, src, len);
......
...@@ -40,7 +40,7 @@ struct tun_struct { ...@@ -40,7 +40,7 @@ struct tun_struct {
wait_queue_head_t read_wait; wait_queue_head_t read_wait;
struct sk_buff_head readq; struct sk_buff_head readq;
struct net_device dev; struct net_device *dev;
struct net_device_stats stats; struct net_device_stats stats;
struct fasync_struct *fasync; struct fasync_struct *fasync;
......
...@@ -816,6 +816,8 @@ extern void tr_setup(struct net_device *dev); ...@@ -816,6 +816,8 @@ extern void tr_setup(struct net_device *dev);
extern void fc_setup(struct net_device *dev); extern void fc_setup(struct net_device *dev);
extern void fc_freedev(struct net_device *dev); extern void fc_freedev(struct net_device *dev);
/* Support for loadable net-drivers */ /* Support for loadable net-drivers */
extern struct net_device *alloc_netdev(int sizeof_priv, const char *name,
void (*setup)(struct net_device *));
extern int register_netdev(struct net_device *dev); extern int register_netdev(struct net_device *dev);
extern void unregister_netdev(struct net_device *dev); extern void unregister_netdev(struct net_device *dev);
/* Functions used for multicast support */ /* Functions used for multicast support */
......
...@@ -111,7 +111,7 @@ struct arpt_counters ...@@ -111,7 +111,7 @@ struct arpt_counters
#define ARPT_INV_ARPHRD 0x0080 /* Invert the sense of ARP HRD. */ #define ARPT_INV_ARPHRD 0x0080 /* Invert the sense of ARP HRD. */
#define ARPT_INV_ARPPRO 0x0100 /* Invert the sense of ARP PRO. */ #define ARPT_INV_ARPPRO 0x0100 /* Invert the sense of ARP PRO. */
#define ARPT_INV_ARPHLN 0x0200 /* Invert the sense of ARP HLN. */ #define ARPT_INV_ARPHLN 0x0200 /* Invert the sense of ARP HLN. */
#define ARPT_INV_MASK 0x007F /* All possible flag bits mask. */ #define ARPT_INV_MASK 0x03FF /* All possible flag bits mask. */
/* This structure defines each of the firewall rules. Consists of 3 /* This structure defines each of the firewall rules. Consists of 3
parts which are 1) general ARP header stuff 2) match specific parts which are 1) general ARP header stuff 2) match specific
......
...@@ -334,6 +334,33 @@ static int unregister_vlan_device(const char *vlan_IF_name) ...@@ -334,6 +334,33 @@ static int unregister_vlan_device(const char *vlan_IF_name)
return ret; return ret;
} }
static void vlan_setup(struct net_device *new_dev)
{
SET_MODULE_OWNER(new_dev);
/* new_dev->ifindex = 0; it will be set when added to
* the global list.
* iflink is set as well.
*/
new_dev->get_stats = vlan_dev_get_stats;
/* Make this thing known as a VLAN device */
new_dev->priv_flags |= IFF_802_1Q_VLAN;
/* Set us up to have no queue, as the underlying Hardware device
* can do all the queueing we could want.
*/
new_dev->tx_queue_len = 0;
/* set up method calls */
new_dev->change_mtu = vlan_dev_change_mtu;
new_dev->open = vlan_dev_open;
new_dev->stop = vlan_dev_stop;
new_dev->set_mac_address = vlan_dev_set_mac_address;
new_dev->set_multicast_list = vlan_dev_set_multicast_list;
new_dev->destructor = (void (*)(struct net_device *)) kfree;
}
/* Attach a VLAN device to a mac address (ie Ethernet Card). /* Attach a VLAN device to a mac address (ie Ethernet Card).
* Returns the device that was created, or NULL if there was * Returns the device that was created, or NULL if there was
* an error of some kind. * an error of some kind.
...@@ -344,8 +371,8 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -344,8 +371,8 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
struct vlan_group *grp; struct vlan_group *grp;
struct net_device *new_dev; struct net_device *new_dev;
struct net_device *real_dev; /* the ethernet device */ struct net_device *real_dev; /* the ethernet device */
int malloc_size = 0;
int r; int r;
char name[IFNAMSIZ];
#ifdef VLAN_DEBUG #ifdef VLAN_DEBUG
printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n", printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n",
...@@ -403,21 +430,6 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -403,21 +430,6 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
goto out_unlock; goto out_unlock;
} }
malloc_size = (sizeof(struct net_device));
new_dev = (struct net_device *) kmalloc(malloc_size, GFP_KERNEL);
VLAN_MEM_DBG("net_device malloc, addr: %p size: %i\n",
new_dev, malloc_size);
if (new_dev == NULL)
goto out_unlock;
memset(new_dev, 0, malloc_size);
/* Set us up to have no queue, as the underlying Hardware device
* can do all the queueing we could want.
*/
new_dev->tx_queue_len = 0;
/* Gotta set up the fields for the device. */ /* Gotta set up the fields for the device. */
#ifdef VLAN_DEBUG #ifdef VLAN_DEBUG
printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n", printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n",
...@@ -426,54 +438,44 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -426,54 +438,44 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
switch (vlan_name_type) { switch (vlan_name_type) {
case VLAN_NAME_TYPE_RAW_PLUS_VID: case VLAN_NAME_TYPE_RAW_PLUS_VID:
/* name will look like: eth1.0005 */ /* name will look like: eth1.0005 */
sprintf(new_dev->name, "%s.%.4i", real_dev->name, VLAN_ID); snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, VLAN_ID);
break; break;
case VLAN_NAME_TYPE_PLUS_VID_NO_PAD: case VLAN_NAME_TYPE_PLUS_VID_NO_PAD:
/* Put our vlan.VID in the name. /* Put our vlan.VID in the name.
* Name will look like: vlan5 * Name will look like: vlan5
*/ */
sprintf(new_dev->name, "vlan%i", VLAN_ID); snprintf(name, IFNAMSIZ, "vlan%i", VLAN_ID);
break; break;
case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD: case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD:
/* Put our vlan.VID in the name. /* Put our vlan.VID in the name.
* Name will look like: eth0.5 * Name will look like: eth0.5
*/ */
sprintf(new_dev->name, "%s.%i", real_dev->name, VLAN_ID); snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, VLAN_ID);
break; break;
case VLAN_NAME_TYPE_PLUS_VID: case VLAN_NAME_TYPE_PLUS_VID:
/* Put our vlan.VID in the name. /* Put our vlan.VID in the name.
* Name will look like: vlan0005 * Name will look like: vlan0005
*/ */
default: default:
sprintf(new_dev->name, "vlan%.4i", VLAN_ID); snprintf(name, IFNAMSIZ, "vlan%.4i", VLAN_ID);
}; };
new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name,
vlan_setup);
if (new_dev == NULL)
goto out_unlock;
#ifdef VLAN_DEBUG #ifdef VLAN_DEBUG
printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name); printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
#endif #endif
/* set up method calls */
new_dev->init = vlan_dev_init;
new_dev->destructor = vlan_dev_destruct;
SET_MODULE_OWNER(new_dev);
/* new_dev->ifindex = 0; it will be set when added to
* the global list.
* iflink is set as well.
*/
new_dev->get_stats = vlan_dev_get_stats;
/* IFF_BROADCAST|IFF_MULTICAST; ??? */ /* IFF_BROADCAST|IFF_MULTICAST; ??? */
new_dev->flags = real_dev->flags; new_dev->flags = real_dev->flags;
new_dev->flags &= ~IFF_UP; new_dev->flags &= ~IFF_UP;
/* Make this thing known as a VLAN device */
new_dev->priv_flags |= IFF_802_1Q_VLAN;
/* need 4 bytes for extra VLAN header info, /* need 4 bytes for extra VLAN header info,
* hope the underlying device can handle it. * hope the underlying device can handle it.
*/ */
new_dev->mtu = real_dev->mtu; new_dev->mtu = real_dev->mtu;
new_dev->change_mtu = vlan_dev_change_mtu;
/* TODO: maybe just assign it to be ETHERNET? */ /* TODO: maybe just assign it to be ETHERNET? */
new_dev->type = real_dev->type; new_dev->type = real_dev->type;
...@@ -484,24 +486,14 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -484,24 +486,14 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
new_dev->hard_header_len += VLAN_HLEN; new_dev->hard_header_len += VLAN_HLEN;
} }
new_dev->priv = kmalloc(sizeof(struct vlan_dev_info),
GFP_KERNEL);
VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n", VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n",
new_dev->priv, new_dev->priv,
sizeof(struct vlan_dev_info)); sizeof(struct vlan_dev_info));
if (new_dev->priv == NULL)
goto out_free_newdev;
memset(new_dev->priv, 0, sizeof(struct vlan_dev_info));
memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len); memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len);
memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len); memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len);
new_dev->addr_len = real_dev->addr_len; new_dev->addr_len = real_dev->addr_len;
new_dev->open = vlan_dev_open;
new_dev->stop = vlan_dev_stop;
if (real_dev->features & NETIF_F_HW_VLAN_TX) { if (real_dev->features & NETIF_F_HW_VLAN_TX) {
new_dev->hard_header = real_dev->hard_header; new_dev->hard_header = real_dev->hard_header;
new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
...@@ -512,8 +504,6 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -512,8 +504,6 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
new_dev->rebuild_header = vlan_dev_rebuild_header; new_dev->rebuild_header = vlan_dev_rebuild_header;
} }
new_dev->hard_header_parse = real_dev->hard_header_parse; new_dev->hard_header_parse = real_dev->hard_header_parse;
new_dev->set_mac_address = vlan_dev_set_mac_address;
new_dev->set_multicast_list = vlan_dev_set_multicast_list;
VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */ VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
VLAN_DEV_INFO(new_dev)->real_dev = real_dev; VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
...@@ -526,7 +516,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -526,7 +516,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
#endif #endif
if (register_netdevice(new_dev)) if (register_netdevice(new_dev))
goto out_free_newdev_priv; goto out_free_newdev;
/* So, got the sucker initialized, now lets place /* So, got the sucker initialized, now lets place
* it into our local structure. * it into our local structure.
...@@ -572,9 +562,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -572,9 +562,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
out_free_unregister: out_free_unregister:
unregister_netdev(new_dev); unregister_netdev(new_dev);
goto out_put_dev;
out_free_newdev_priv:
kfree(new_dev->priv);
out_free_newdev: out_free_newdev:
kfree(new_dev); kfree(new_dev);
......
...@@ -65,8 +65,6 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); ...@@ -65,8 +65,6 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
int vlan_dev_set_mac_address(struct net_device *dev, void* addr); int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
int vlan_dev_open(struct net_device* dev); int vlan_dev_open(struct net_device* dev);
int vlan_dev_stop(struct net_device* dev); int vlan_dev_stop(struct net_device* dev);
int vlan_dev_init(struct net_device* dev);
void vlan_dev_destruct(struct net_device* dev);
int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val); int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
......
...@@ -766,28 +766,6 @@ int vlan_dev_stop(struct net_device *dev) ...@@ -766,28 +766,6 @@ int vlan_dev_stop(struct net_device *dev)
vlan_flush_mc_list(dev); vlan_flush_mc_list(dev);
return 0; return 0;
} }
int vlan_dev_init(struct net_device *dev)
{
/* TODO: figure this out, maybe do nothing?? */
return 0;
}
void vlan_dev_destruct(struct net_device *dev)
{
if (dev) {
vlan_flush_mc_list(dev);
if (dev->priv) {
if (VLAN_DEV_INFO(dev)->dent)
BUG();
kfree(dev->priv);
dev->priv = NULL;
}
kfree(dev);
}
}
/** Taken from Gleb + Lennert's VLAN code, and modified... */ /** Taken from Gleb + Lennert's VLAN code, and modified... */
void vlan_dev_set_multicast_list(struct net_device *vlan_dev) void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
{ {
......
...@@ -110,10 +110,6 @@ static int br_dev_accept_fastpath(struct net_device *dev, struct dst_entry *dst) ...@@ -110,10 +110,6 @@ static int br_dev_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
return -1; return -1;
} }
static void br_dev_destruct(struct net_device *dev)
{
kfree(dev->priv);
}
void br_dev_setup(struct net_device *dev) void br_dev_setup(struct net_device *dev)
{ {
...@@ -124,10 +120,13 @@ void br_dev_setup(struct net_device *dev) ...@@ -124,10 +120,13 @@ void br_dev_setup(struct net_device *dev)
dev->hard_start_xmit = br_dev_xmit; dev->hard_start_xmit = br_dev_xmit;
dev->open = br_dev_open; dev->open = br_dev_open;
dev->set_multicast_list = br_dev_set_multicast_list; dev->set_multicast_list = br_dev_set_multicast_list;
dev->destructor = br_dev_destruct; dev->destructor = (void (*)(struct net_device *))kfree;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
dev->stop = br_dev_stop; dev->stop = br_dev_stop;
dev->accept_fastpath = br_dev_accept_fastpath; dev->accept_fastpath = br_dev_accept_fastpath;
dev->tx_queue_len = 0; dev->tx_queue_len = 0;
dev->set_mac_address = NULL; dev->set_mac_address = NULL;
dev->priv_flags = IFF_EBRIDGE;
ether_setup(dev);
} }
...@@ -78,17 +78,14 @@ static struct net_bridge *new_nb(const char *name) ...@@ -78,17 +78,14 @@ static struct net_bridge *new_nb(const char *name)
struct net_bridge *br; struct net_bridge *br;
struct net_device *dev; struct net_device *dev;
if ((br = kmalloc(sizeof(*br), GFP_KERNEL)) == NULL) dev = alloc_netdev(sizeof(struct net_bridge), name,
br_dev_setup);
if (!dev)
return NULL; return NULL;
memset(br, 0, sizeof(*br)); br = dev->priv;
dev = &br->dev; br->dev = dev;
strlcpy(dev->name, name, sizeof(dev->name));
dev->priv = br;
dev->priv_flags = IFF_EBRIDGE;
ether_setup(dev);
br_dev_setup(dev);
br->lock = SPIN_LOCK_UNLOCKED; br->lock = SPIN_LOCK_UNLOCKED;
INIT_LIST_HEAD(&br->port_list); INIT_LIST_HEAD(&br->port_list);
...@@ -159,9 +156,9 @@ int br_add_bridge(const char *name) ...@@ -159,9 +156,9 @@ int br_add_bridge(const char *name)
if ((br = new_nb(name)) == NULL) if ((br = new_nb(name)) == NULL)
return -ENOMEM; return -ENOMEM;
ret = register_netdev(&br->dev); ret = register_netdev(br->dev);
if (ret) if (ret)
kfree(br); kfree(br->dev);
return ret; return ret;
} }
...@@ -219,7 +216,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) ...@@ -219,7 +216,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
br_stp_recalculate_bridge_id(br); br_stp_recalculate_bridge_id(br);
br_fdb_insert(br, p, dev->dev_addr, 1); br_fdb_insert(br, p, dev->dev_addr, 1);
if ((br->dev.flags & IFF_UP) && (dev->flags & IFF_UP)) if ((br->dev->flags & IFF_UP) && (dev->flags & IFF_UP))
br_stp_enable_port(p); br_stp_enable_port(p);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
......
...@@ -40,7 +40,7 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb) ...@@ -40,7 +40,7 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
br->statistics.rx_bytes += skb->len; br->statistics.rx_bytes += skb->len;
indev = skb->dev; indev = skb->dev;
skb->dev = &br->dev; skb->dev = br->dev;
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
br_pass_frame_up_finish); br_pass_frame_up_finish);
...@@ -67,7 +67,7 @@ int br_handle_frame_finish(struct sk_buff *skb) ...@@ -67,7 +67,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
br = p->br; br = p->br;
passedup = 0; passedup = 0;
if (br->dev.flags & IFF_PROMISC) { if (br->dev->flags & IFF_PROMISC) {
struct sk_buff *skb2; struct sk_buff *skb2;
skb2 = skb_clone(skb, GFP_ATOMIC); skb2 = skb_clone(skb, GFP_ATOMIC);
...@@ -140,7 +140,7 @@ int br_handle_frame(struct sk_buff *skb) ...@@ -140,7 +140,7 @@ int br_handle_frame(struct sk_buff *skb)
return -1; return -1;
} }
if (!memcmp(p->br->dev.dev_addr, dest, ETH_ALEN)) if (!memcmp(p->br->dev->dev_addr, dest, ETH_ALEN))
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
sizeof(struct bridge_skb_cb))) sizeof(struct bridge_skb_cb)))
#define has_bridge_parent(device) ((device)->br_port != NULL) #define has_bridge_parent(device) ((device)->br_port != NULL)
#define bridge_parent(device) (&((device)->br_port->br->dev)) #define bridge_parent(device) ((device)->br_port->br->dev)
/* We need these fake structures to make netfilter happy -- /* We need these fake structures to make netfilter happy --
* lots of places assume that skb->dst != NULL, which isn't * lots of places assume that skb->dst != NULL, which isn't
......
...@@ -52,7 +52,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v ...@@ -52,7 +52,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
if (br->dev.flags & IFF_UP) { if (br->dev->flags & IFF_UP) {
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
br_stp_disable_port(p); br_stp_disable_port(p);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
...@@ -60,7 +60,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v ...@@ -60,7 +60,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
break; break;
case NETDEV_UP: case NETDEV_UP:
if (!(br->dev.flags & IFF_UP)) { if (!(br->dev->flags & IFF_UP)) {
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
br_stp_enable_port(p); br_stp_enable_port(p);
spin_unlock_bh(&br->lock); spin_unlock_bh(&br->lock);
......
...@@ -81,7 +81,7 @@ struct net_bridge ...@@ -81,7 +81,7 @@ struct net_bridge
{ {
spinlock_t lock; spinlock_t lock;
struct list_head port_list; struct list_head port_list;
struct net_device dev; struct net_device *dev;
struct net_device_stats statistics; struct net_device_stats statistics;
rwlock_t hash_lock; rwlock_t hash_lock;
struct hlist_head hash[BR_HASH_SIZE]; struct hlist_head hash[BR_HASH_SIZE];
......
...@@ -26,7 +26,7 @@ static const char *br_port_state_names[] = { ...@@ -26,7 +26,7 @@ static const char *br_port_state_names[] = {
void br_log_state(const struct net_bridge_port *p) void br_log_state(const struct net_bridge_port *p)
{ {
pr_info("%s: port %d(%s) entering %s state\n", pr_info("%s: port %d(%s) entering %s state\n",
p->br->dev.name, p->port_no, p->dev->name, p->br->dev->name, p->port_no, p->dev->name,
br_port_state_names[p->state]); br_port_state_names[p->state]);
} }
...@@ -130,7 +130,7 @@ void br_become_root_bridge(struct net_bridge *br) ...@@ -130,7 +130,7 @@ void br_become_root_bridge(struct net_bridge *br)
br_topology_change_detection(br); br_topology_change_detection(br);
del_timer(&br->tcn_timer); del_timer(&br->tcn_timer);
if (br->dev.flags & IFF_UP) { if (br->dev->flags & IFF_UP) {
br_config_bpdu_generation(br); br_config_bpdu_generation(br);
mod_timer(&br->hello_timer, jiffies + br->hello_time); mod_timer(&br->hello_timer, jiffies + br->hello_time);
} }
...@@ -289,10 +289,10 @@ static inline void br_topology_change_acknowledged(struct net_bridge *br) ...@@ -289,10 +289,10 @@ static inline void br_topology_change_acknowledged(struct net_bridge *br)
/* called under bridge lock */ /* called under bridge lock */
void br_topology_change_detection(struct net_bridge *br) void br_topology_change_detection(struct net_bridge *br)
{ {
if (!(br->dev.flags & IFF_UP)) if (!(br->dev->flags & IFF_UP))
return; return;
pr_info("%s: topology change detected", br->dev.name); pr_info("%s: topology change detected", br->dev->name);
if (br_is_root_bridge(br)) { if (br_is_root_bridge(br)) {
printk(", propagating"); printk(", propagating");
br->topology_change = 1; br->topology_change = 1;
...@@ -446,7 +446,7 @@ void br_received_tcn_bpdu(struct net_bridge_port *p) ...@@ -446,7 +446,7 @@ void br_received_tcn_bpdu(struct net_bridge_port *p)
{ {
if (br_is_designated_port(p)) { if (br_is_designated_port(p)) {
pr_info("%s: received tcn bpdu on port %i(%s)\n", pr_info("%s: received tcn bpdu on port %i(%s)\n",
p->br->dev.name, p->port_no, p->dev->name); p->br->dev->name, p->port_no, p->dev->name);
br_topology_change_detection(p->br); br_topology_change_detection(p->br);
br_topology_change_acknowledge(p); br_topology_change_acknowledge(p);
......
...@@ -145,7 +145,7 @@ void br_stp_handle_bpdu(struct sk_buff *skb) ...@@ -145,7 +145,7 @@ void br_stp_handle_bpdu(struct sk_buff *skb)
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
if (p->state == BR_STATE_DISABLED if (p->state == BR_STATE_DISABLED
|| !(br->dev.flags & IFF_UP) || !(br->dev->flags & IFF_UP)
|| !br->stp_enabled || !br->stp_enabled
|| memcmp(buf, header, 6)) || memcmp(buf, header, 6))
goto out; goto out;
......
...@@ -93,7 +93,7 @@ void br_stp_disable_port(struct net_bridge_port *p) ...@@ -93,7 +93,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
br = p->br; br = p->br;
printk(KERN_INFO "%s: port %i(%s) entering %s state\n", printk(KERN_INFO "%s: port %i(%s) entering %s state\n",
br->dev.name, p->port_no, p->dev->name, "disabled"); br->dev->name, p->port_no, p->dev->name, "disabled");
wasroot = br_is_root_bridge(br); wasroot = br_is_root_bridge(br);
br_become_designated_port(p); br_become_designated_port(p);
...@@ -124,7 +124,7 @@ static void br_stp_change_bridge_id(struct net_bridge *br, unsigned char *addr) ...@@ -124,7 +124,7 @@ static void br_stp_change_bridge_id(struct net_bridge *br, unsigned char *addr)
memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN); memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN);
memcpy(br->bridge_id.addr, addr, ETH_ALEN); memcpy(br->bridge_id.addr, addr, ETH_ALEN);
memcpy(br->dev.dev_addr, addr, ETH_ALEN); memcpy(br->dev->dev_addr, addr, ETH_ALEN);
list_for_each_entry(p, &br->port_list, list) { list_for_each_entry(p, &br->port_list, list) {
if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN)) if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN))
......
...@@ -38,9 +38,9 @@ static void br_hello_timer_expired(unsigned long arg) ...@@ -38,9 +38,9 @@ static void br_hello_timer_expired(unsigned long arg)
{ {
struct net_bridge *br = (struct net_bridge *)arg; struct net_bridge *br = (struct net_bridge *)arg;
pr_debug("%s: hello timer expired\n", br->dev.name); pr_debug("%s: hello timer expired\n", br->dev->name);
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
if (br->dev.flags & IFF_UP) { if (br->dev->flags & IFF_UP) {
br_config_bpdu_generation(br); br_config_bpdu_generation(br);
br->hello_timer.expires = jiffies + br->hello_time; br->hello_timer.expires = jiffies + br->hello_time;
...@@ -61,7 +61,7 @@ static void br_message_age_timer_expired(unsigned long arg) ...@@ -61,7 +61,7 @@ static void br_message_age_timer_expired(unsigned long arg)
pr_info("%s: neighbor %.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x lost on port %d(%s)\n", pr_info("%s: neighbor %.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x lost on port %d(%s)\n",
br->dev.name, br->dev->name,
id->prio[0], id->prio[1], id->prio[0], id->prio[1],
id->addr[0], id->addr[1], id->addr[2], id->addr[0], id->addr[1], id->addr[2],
id->addr[3], id->addr[4], id->addr[5], id->addr[3], id->addr[4], id->addr[5],
...@@ -89,7 +89,7 @@ static void br_forward_delay_timer_expired(unsigned long arg) ...@@ -89,7 +89,7 @@ static void br_forward_delay_timer_expired(unsigned long arg)
struct net_bridge *br = p->br; struct net_bridge *br = p->br;
pr_debug("%s: %d(%s) forward delay timer\n", pr_debug("%s: %d(%s) forward delay timer\n",
br->dev.name, p->port_no, p->dev->name); br->dev->name, p->port_no, p->dev->name);
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
if (p->state == BR_STATE_LISTENING) { if (p->state == BR_STATE_LISTENING) {
p->state = BR_STATE_LEARNING; p->state = BR_STATE_LEARNING;
...@@ -108,9 +108,9 @@ static void br_tcn_timer_expired(unsigned long arg) ...@@ -108,9 +108,9 @@ static void br_tcn_timer_expired(unsigned long arg)
{ {
struct net_bridge *br = (struct net_bridge *) arg; struct net_bridge *br = (struct net_bridge *) arg;
pr_debug("%s: tcn timer expired\n", br->dev.name); pr_debug("%s: tcn timer expired\n", br->dev->name);
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
if (br->dev.flags & IFF_UP) { if (br->dev->flags & IFF_UP) {
br_transmit_tcn(br); br_transmit_tcn(br);
br->tcn_timer.expires = jiffies + br->bridge_hello_time; br->tcn_timer.expires = jiffies + br->bridge_hello_time;
...@@ -123,7 +123,7 @@ static void br_topology_change_timer_expired(unsigned long arg) ...@@ -123,7 +123,7 @@ static void br_topology_change_timer_expired(unsigned long arg)
{ {
struct net_bridge *br = (struct net_bridge *) arg; struct net_bridge *br = (struct net_bridge *) arg;
pr_debug("%s: topo change timer expired\n", br->dev.name); pr_debug("%s: topo change timer expired\n", br->dev->name);
spin_lock_bh(&br->lock); spin_lock_bh(&br->lock);
br->topology_change_detected = 0; br->topology_change_detected = 0;
br->topology_change = 0; br->topology_change = 0;
...@@ -135,7 +135,7 @@ static void br_hold_timer_expired(unsigned long arg) ...@@ -135,7 +135,7 @@ static void br_hold_timer_expired(unsigned long arg)
struct net_bridge_port *p = (struct net_bridge_port *) arg; struct net_bridge_port *p = (struct net_bridge_port *) arg;
pr_debug("%s: %d(%s) hold timer expired\n", pr_debug("%s: %d(%s) hold timer expired\n",
p->br->dev.name, p->port_no, p->dev->name); p->br->dev->name, p->port_no, p->dev->name);
spin_lock_bh(&p->br->lock); spin_lock_bh(&p->br->lock);
if (p->config_pending) if (p->config_pending)
......
...@@ -22,7 +22,7 @@ static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr, ...@@ -22,7 +22,7 @@ static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr,
if (hooknr != NF_BR_BROUTING) if (hooknr != NF_BR_BROUTING)
memcpy((**pskb).mac.ethernet->h_dest, memcpy((**pskb).mac.ethernet->h_dest,
in->br_port->br->dev.dev_addr, ETH_ALEN); in->br_port->br->dev->dev_addr, ETH_ALEN);
else { else {
memcpy((**pskb).mac.ethernet->h_dest, memcpy((**pskb).mac.ethernet->h_dest,
in->dev_addr, ETH_ALEN); in->dev_addr, ETH_ALEN);
......
...@@ -135,10 +135,10 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h, ...@@ -135,10 +135,10 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
return 1; return 1;
if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check( if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check(
e->logical_in, &in->br_port->br->dev), EBT_ILOGICALIN)) e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN))
return 1; return 1;
if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check( if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check(
e->logical_out, &out->br_port->br->dev), EBT_ILOGICALOUT)) e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT))
return 1; return 1;
if (e->bitmask & EBT_SOURCEMAC) { if (e->bitmask & EBT_SOURCEMAC) {
......
...@@ -3005,14 +3005,15 @@ subsys_initcall(net_dev_init); ...@@ -3005,14 +3005,15 @@ subsys_initcall(net_dev_init);
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
struct net_hotplug_todo { struct net_hotplug_todo {
struct net_hotplug_todo *next; struct list_head list;
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
int is_register; int is_register;
}; };
static spinlock_t net_hotplug_list_lock = SPIN_LOCK_UNLOCKED; static spinlock_t net_hotplug_list_lock = SPIN_LOCK_UNLOCKED;
static struct net_hotplug_todo *net_hotplug_list; static DECLARE_MUTEX(net_hotplug_run);
static struct list_head net_hotplug_list = LIST_HEAD_INIT(net_hotplug_list);
static void net_run_hotplug_one(struct net_hotplug_todo *ent) static inline void net_run_hotplug_one(struct net_hotplug_todo *ent)
{ {
char *argv[3], *envp[5], ifname[12 + IFNAMSIZ], action_str[32]; char *argv[3], *envp[5], ifname[12 + IFNAMSIZ], action_str[32];
int i; int i;
...@@ -3037,23 +3038,37 @@ static void net_run_hotplug_one(struct net_hotplug_todo *ent) ...@@ -3037,23 +3038,37 @@ static void net_run_hotplug_one(struct net_hotplug_todo *ent)
call_usermodehelper(argv [0], argv, envp, 0); call_usermodehelper(argv [0], argv, envp, 0);
} }
/* Run all queued hotplug requests.
* Requests are run in FIFO order.
*/
static void net_run_hotplug_todo(void) static void net_run_hotplug_todo(void)
{ {
struct net_hotplug_todo *list; struct list_head list = LIST_HEAD_INIT(list);
/* This is racy but okay since any other requests will get
* processed when the other guy does rtnl_unlock.
*/
if (list_empty(&net_hotplug_list))
return;
/* Need to guard against multiple cpu's getting out of order. */
down(&net_hotplug_run);
/* Snapshot list, allow later requests */
spin_lock(&net_hotplug_list_lock); spin_lock(&net_hotplug_list_lock);
list = net_hotplug_list; list_splice_init(&net_hotplug_list, &list);
net_hotplug_list = NULL;
spin_unlock(&net_hotplug_list_lock); spin_unlock(&net_hotplug_list_lock);
while (list != NULL) { while (!list_empty(&list)) {
struct net_hotplug_todo *next = list->next; struct net_hotplug_todo *ent;
net_run_hotplug_one(list); ent = list_entry(list.next, struct net_hotplug_todo, list);
list_del(&ent->list);
kfree(list); net_run_hotplug_one(ent);
list = next; kfree(ent);
} }
up(&net_hotplug_run);
} }
/* Notify userspace when a netdevice event occurs, /* Notify userspace when a netdevice event occurs,
...@@ -3065,15 +3080,17 @@ static void net_run_sbin_hotplug(struct net_device *dev, int is_register) ...@@ -3065,15 +3080,17 @@ static void net_run_sbin_hotplug(struct net_device *dev, int is_register)
{ {
struct net_hotplug_todo *ent = kmalloc(sizeof(*ent), GFP_KERNEL); struct net_hotplug_todo *ent = kmalloc(sizeof(*ent), GFP_KERNEL);
ASSERT_RTNL();
if (!ent) if (!ent)
return; return;
INIT_LIST_HEAD(&ent->list);
memcpy(ent->ifname, dev->name, IFNAMSIZ); memcpy(ent->ifname, dev->name, IFNAMSIZ);
ent->is_register = is_register; ent->is_register = is_register;
spin_lock(&net_hotplug_list_lock); spin_lock(&net_hotplug_list_lock);
ent->next = net_hotplug_list; list_add(&ent->list, &net_hotplug_list);
net_hotplug_list = ent;
spin_unlock(&net_hotplug_list_lock); spin_unlock(&net_hotplug_list_lock);
} }
#endif #endif
...@@ -1094,6 +1094,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, ...@@ -1094,6 +1094,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
kfree(p); kfree(p);
return NULL; return NULL;
} }
p->sysctl_table = NULL;
write_lock_bh(&tbl->lock); write_lock_bh(&tbl->lock);
p->next = tbl->parms.next; p->next = tbl->parms.next;
tbl->parms.next = p; tbl->parms.next = p;
...@@ -1113,9 +1114,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) ...@@ -1113,9 +1114,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
if (*p == parms) { if (*p == parms) {
*p = parms->next; *p = parms->next;
write_unlock_bh(&tbl->lock); write_unlock_bh(&tbl->lock);
#ifdef CONFIG_SYSCTL
neigh_sysctl_unregister(parms);
#endif
kfree(parms); kfree(parms);
return; return;
} }
...@@ -1178,9 +1176,6 @@ int neigh_table_clear(struct neigh_table *tbl) ...@@ -1178,9 +1176,6 @@ int neigh_table_clear(struct neigh_table *tbl)
} }
} }
write_unlock(&neigh_tbl_lock); write_unlock(&neigh_tbl_lock);
#ifdef CONFIG_SYSCTL
neigh_sysctl_unregister(&tbl->parms);
#endif
return 0; return 0;
} }
......
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
* *
* Copyright (c) 2003 Stephen Hemminber <shemminger@osdl.org> * Copyright (c) 2003 Stephen Hemminber <shemminger@osdl.org>
* *
*
* TODO:
* last_tx
* last_rx
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -16,33 +12,61 @@ ...@@ -16,33 +12,61 @@
#include <net/sock.h> #include <net/sock.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#define to_net_dev(class) container_of((class), struct net_device, class_dev) #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
/* use same locking rules as GIF* ioctl's */
static ssize_t netdev_show(const struct class_device *cd, char *buf,
ssize_t (*format)(const struct net_device *, char *))
{
struct net_device *net = to_net_dev(cd);
ssize_t ret = -EINVAL;
read_lock(&dev_base_lock);
if (!net->deadbeaf)
ret = (*format)(net, buf);
read_unlock(&dev_base_lock);
return ret;
}
/* generate a show function for simple field */ /* generate a show function for simple field */
#define NETDEVICE_SHOW(field, format_string) \ #define NETDEVICE_SHOW(field, format_string) \
static ssize_t show_##field(struct class_device *dev, char *buf) \ static ssize_t format_##field(const struct net_device *net, char *buf) \
{ \ { \
return sprintf(buf, format_string, to_net_dev(dev)->field); \ return sprintf(buf, format_string, net->field); \
} \
static ssize_t show_##field(struct class_device *cd, char *buf) \
{ \
return netdev_show(cd, buf, format_##field); \
} }
/* generate a store function for a field with locking */
#define NETDEVICE_STORE(field) \ /* use same locking and permission rules as SIF* ioctl's */
static ssize_t \ static ssize_t netdev_store(struct class_device *dev,
store_##field(struct class_device *dev, const char *buf, size_t len) \ const char *buf, size_t len,
{ \ int (*set)(struct net_device *, unsigned long))
char *endp; \ {
long new = simple_strtol(buf, &endp, 16); \ struct net_device *net = to_net_dev(dev);
\ char *endp;
if (endp == buf || new < 0) \ unsigned long new;
return -EINVAL; \ int ret = -EINVAL;
\
if (!capable(CAP_NET_ADMIN)) \ if (!capable(CAP_NET_ADMIN))
return -EPERM; \ return -EPERM;
\
rtnl_lock(); \ new = simple_strtoul(buf, &endp, 0);
to_net_dev(dev)->field = new; \ if (endp == buf)
rtnl_unlock(); \ goto err;
return len; \
rtnl_lock();
if (!net->deadbeaf) {
if ((ret = (*set)(net, new)) == 0)
ret = len;
}
rtnl_unlock();
err:
return ret;
} }
/* generate a read-only network device class attribute */ /* generate a read-only network device class attribute */
...@@ -56,6 +80,7 @@ NETDEVICE_ATTR(ifindex, "%d\n"); ...@@ -56,6 +80,7 @@ NETDEVICE_ATTR(ifindex, "%d\n");
NETDEVICE_ATTR(features, "%#x\n"); NETDEVICE_ATTR(features, "%#x\n");
NETDEVICE_ATTR(type, "%d\n"); NETDEVICE_ATTR(type, "%d\n");
/* use same locking rules as GIFHWADDR ioctl's */
static ssize_t format_addr(char *buf, const unsigned char *addr, int len) static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
{ {
int i; int i;
...@@ -72,12 +97,16 @@ static ssize_t format_addr(char *buf, const unsigned char *addr, int len) ...@@ -72,12 +97,16 @@ static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
static ssize_t show_address(struct class_device *dev, char *buf) static ssize_t show_address(struct class_device *dev, char *buf)
{ {
struct net_device *net = to_net_dev(dev); struct net_device *net = to_net_dev(dev);
if (net->deadbeaf)
return -EINVAL;
return format_addr(buf, net->dev_addr, net->addr_len); return format_addr(buf, net->dev_addr, net->addr_len);
} }
static ssize_t show_broadcast(struct class_device *dev, char *buf) static ssize_t show_broadcast(struct class_device *dev, char *buf)
{ {
struct net_device *net = to_net_dev(dev); struct net_device *net = to_net_dev(dev);
if (net->deadbeaf)
return -EINVAL;
return format_addr(buf, net->broadcast, net->addr_len); return format_addr(buf, net->broadcast, net->addr_len);
} }
...@@ -87,54 +116,45 @@ static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL); ...@@ -87,54 +116,45 @@ static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL);
/* read-write attributes */ /* read-write attributes */
NETDEVICE_SHOW(mtu, "%d\n"); NETDEVICE_SHOW(mtu, "%d\n");
static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len) static int change_mtu(struct net_device *net, unsigned long new_mtu)
{ {
char *endp; return dev_set_mtu(net, (int) new_mtu);
int new_mtu; }
int err;
new_mtu = simple_strtoul(buf, &endp, 10);
if (endp == buf)
return -EINVAL;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
rtnl_lock();
err = dev_set_mtu(to_net_dev(dev), new_mtu);
rtnl_unlock();
return err == 0 ? len : err; static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
{
return netdev_store(dev, buf, len, change_mtu);
} }
static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu); static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu);
NETDEVICE_SHOW(flags, "%#x\n"); NETDEVICE_SHOW(flags, "%#x\n");
static int change_flags(struct net_device *net, unsigned long new_flags)
{
return dev_change_flags(net, (unsigned) new_flags);
}
static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len) static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len)
{ {
unsigned long new_flags; return netdev_store(dev, buf, len, change_flags);
char *endp; }
int err = 0;
new_flags = simple_strtoul(buf, &endp, 16); static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
if (endp == buf)
return -EINVAL;
if (!capable(CAP_NET_ADMIN)) NETDEVICE_SHOW(tx_queue_len, "%lu\n");
return -EPERM;
rtnl_lock();
err = dev_change_flags(to_net_dev(dev), new_flags);
rtnl_unlock();
return err ? err : len; static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
{
net->tx_queue_len = new_len;
return 0;
} }
static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags); static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, size_t len)
{
return netdev_store(dev, buf,len, change_tx_queue_len);
}
NETDEVICE_SHOW(tx_queue_len, "%lu\n");
NETDEVICE_STORE(tx_queue_len);
static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
store_tx_queue_len); store_tx_queue_len);
...@@ -237,16 +257,17 @@ netstat_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) ...@@ -237,16 +257,17 @@ netstat_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
{ {
struct netstat_fs_entry *entry struct netstat_fs_entry *entry
= container_of(attr, struct netstat_fs_entry, attr); = container_of(attr, struct netstat_fs_entry, attr);
struct class_device *class_dev
= container_of(kobj->parent, struct class_device, kobj);
struct net_device *dev struct net_device *dev
= to_net_dev(class_dev); = to_net_dev(to_class_dev(kobj->parent));
struct net_device_stats *stats struct net_device_stats *stats;
= dev->get_stats ? dev->get_stats(dev) : NULL; ssize_t ret = -EINVAL;
if (stats && entry->show) read_lock(&dev_base_lock);
return entry->show(stats, buf); if (!dev->deadbeaf && entry->show && dev->get_stats &&
return -EINVAL; (stats = (*dev->get_stats)(dev)))
ret = entry->show(stats, buf);
read_unlock(&dev_base_lock);
return ret;
} }
static struct sysfs_ops netstat_sysfs_ops = { static struct sysfs_ops netstat_sysfs_ops = {
...@@ -278,17 +299,11 @@ int netdev_register_sysfs(struct net_device *net) ...@@ -278,17 +299,11 @@ int netdev_register_sysfs(struct net_device *net)
goto out_unreg; goto out_unreg;
} }
net->stats_kobj.parent = NULL; net->stats_kobj.parent = NULL;
if (net->get_stats) { if (net->get_stats) {
struct kobject *k = &net->stats_kobj; struct kobject *k = &net->stats_kobj;
k->parent = kobject_get(&class_dev->kobj); k->parent = &class_dev->kobj;
if (!k->parent) {
ret = -EBUSY;
goto out_unreg;
}
strlcpy(k->name, "statistics", KOBJ_NAME_LEN); strlcpy(k->name, "statistics", KOBJ_NAME_LEN);
k->ktype = &netstat_ktype; k->ktype = &netstat_ktype;
......
...@@ -197,7 +197,9 @@ static void inetdev_destroy(struct in_device *in_dev) ...@@ -197,7 +197,9 @@ static void inetdev_destroy(struct in_device *in_dev)
/* in_dev_put following below will kill the in_device */ /* in_dev_put following below will kill the in_device */
write_unlock_bh(&inetdev_lock); write_unlock_bh(&inetdev_lock);
#ifdef CONFIG_SYSCTL
neigh_sysctl_unregister(in_dev->arp_parms);
#endif
neigh_parms_release(&arp_tbl, in_dev->arp_parms); neigh_parms_release(&arp_tbl, in_dev->arp_parms);
in_dev_put(in_dev); in_dev_put(in_dev);
} }
......
...@@ -107,10 +107,6 @@ ipt_local_out_hook(unsigned int hook, ...@@ -107,10 +107,6 @@ ipt_local_out_hook(unsigned int hook,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
......
...@@ -145,10 +145,6 @@ ipt_local_hook(unsigned int hook, ...@@ -145,10 +145,6 @@ ipt_local_hook(unsigned int hook,
u_int32_t saddr, daddr; u_int32_t saddr, daddr;
unsigned long nfmark; unsigned long nfmark;
/* FIXME: Push down to extensions --RR */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
return NF_DROP;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if ((*pskb)->len < sizeof(struct iphdr) if ((*pskb)->len < sizeof(struct iphdr)
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
......
...@@ -1893,10 +1893,11 @@ static int addrconf_ifdown(struct net_device *dev, int how) ...@@ -1893,10 +1893,11 @@ static int addrconf_ifdown(struct net_device *dev, int how)
/* Shot the device (if unregistered) */ /* Shot the device (if unregistered) */
if (how == 1) { if (how == 1) {
neigh_parms_release(&nd_tbl, idev->nd_parms);
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
addrconf_sysctl_unregister(&idev->cnf); addrconf_sysctl_unregister(&idev->cnf);
neigh_sysctl_unregister(idev->nd_parms);
#endif #endif
neigh_parms_release(&nd_tbl, idev->nd_parms);
in6_dev_put(idev); in6_dev_put(idev);
} }
return 0; return 0;
......
...@@ -1210,7 +1210,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) ...@@ -1210,7 +1210,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
IPV6_TLV_ROUTERALERT, 2, 0, 0, IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 }; IPV6_TLV_PADN, 0 };
skb = sock_alloc_send_skb(sk, size + dev->hard_header_len+15, 0, &err); skb = sock_alloc_send_skb(sk, size + dev->hard_header_len+15, 1, &err);
if (skb == 0) if (skb == 0)
return 0; return 0;
...@@ -1545,7 +1545,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) ...@@ -1545,7 +1545,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
payload_len = len + sizeof(ra); payload_len = len + sizeof(ra);
full_len = sizeof(struct ipv6hdr) + payload_len; full_len = sizeof(struct ipv6hdr) + payload_len;
skb = sock_alloc_send_skb(sk, dev->hard_header_len + full_len + 15, 0, &err); skb = sock_alloc_send_skb(sk, dev->hard_header_len + full_len + 15, 1, &err);
if (skb == NULL) if (skb == NULL)
return; return;
......
...@@ -1487,6 +1487,9 @@ int __init ndisc_init(struct net_proto_family *ops) ...@@ -1487,6 +1487,9 @@ int __init ndisc_init(struct net_proto_family *ops)
void ndisc_cleanup(void) void ndisc_cleanup(void)
{ {
#ifdef CONFIG_SYSCTL
neigh_sysctl_unregister(&nd_tbl.parms);
#endif
neigh_table_clear(&nd_tbl); neigh_table_clear(&nd_tbl);
sock_release(ndisc_socket); sock_release(ndisc_socket);
ndisc_socket = NULL; /* For safety. */ ndisc_socket = NULL; /* For safety. */
......
...@@ -596,10 +596,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, ...@@ -596,10 +596,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
BUG_TRAP(FRAG6_CB(head)->offset == 0); BUG_TRAP(FRAG6_CB(head)->offset == 0);
/* Unfragmented part is taken from the first segment. */ /* Unfragmented part is taken from the first segment. */
payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len; payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
nhoff = head->h.raw - head->nh.raw; if (payload_len > 65535)
if (payload_len > 65535 + 8)
goto out_oversize; goto out_oversize;
/* Head of list must not be cloned. */ /* Head of list must not be cloned. */
...@@ -633,9 +631,10 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, ...@@ -633,9 +631,10 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
* header in order to calculate ICV correctly. */ * header in order to calculate ICV correctly. */
nhoff = fq->nhoffset; nhoff = fq->nhoffset;
head->nh.raw[nhoff] = head->h.raw[0]; head->nh.raw[nhoff] = head->h.raw[0];
memmove(head->head+8, head->head, (head->data-head->head)-8); memmove(head->head + sizeof(struct frag_hdr), head->head,
head->mac.raw += 8; (head->data - head->head) - sizeof(struct frag_hdr));
head->nh.raw += 8; head->mac.raw += sizeof(struct frag_hdr);
head->nh.raw += sizeof(struct frag_hdr);
skb_shinfo(head)->frag_list = head->next; skb_shinfo(head)->frag_list = head->next;
head->h.raw = head->data; head->h.raw = head->data;
......
...@@ -584,7 +584,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, ...@@ -584,7 +584,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
for (; s; s = s->sk_next) { for (; s; s = s->sk_next) {
struct inet_opt *inet = inet_sk(s); struct inet_opt *inet = inet_sk(s);
if (inet->num == num && sk->sk_family == PF_INET6) { if (inet->num == num && s->sk_family == PF_INET6) {
struct ipv6_pinfo *np = inet6_sk(s); struct ipv6_pinfo *np = inet6_sk(s);
if (inet->dport) { if (inet->dport) {
if (inet->dport != rmt_port) if (inet->dport != rmt_port)
......
...@@ -183,7 +183,7 @@ static int llc_seq_core_show(struct seq_file *seq, void *v) ...@@ -183,7 +183,7 @@ static int llc_seq_core_show(struct seq_file *seq, void *v)
timer_pending(&llc->pf_cycle_timer.timer), timer_pending(&llc->pf_cycle_timer.timer),
timer_pending(&llc->rej_sent_timer.timer), timer_pending(&llc->rej_sent_timer.timer),
timer_pending(&llc->busy_state_timer.timer), timer_pending(&llc->busy_state_timer.timer),
!!sk->sk_backlog.tail, sock_owned_by_user(sk)); !!sk->sk_backlog.tail, !!sock_owned_by_user(sk));
out: out:
return 0; return 0;
} }
......
...@@ -190,6 +190,7 @@ EXPORT_SYMBOL(neigh_app_ns); ...@@ -190,6 +190,7 @@ EXPORT_SYMBOL(neigh_app_ns);
#endif #endif
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
EXPORT_SYMBOL(neigh_sysctl_register); EXPORT_SYMBOL(neigh_sysctl_register);
EXPORT_SYMBOL(neigh_sysctl_unregister);
#endif #endif
EXPORT_SYMBOL(pneigh_lookup); EXPORT_SYMBOL(pneigh_lookup);
EXPORT_SYMBOL(pneigh_enqueue); EXPORT_SYMBOL(pneigh_enqueue);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment