X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fdummy.c;h=37dcfdc63456bb521bfd0e74ec58f65ad403dea5;hb=1a8cdc5d49cdbd79dedce8db3840fca825304d8d;hp=2f2cf3c04bc799ddaef15e18f122864fa1303a61;hpb=206c9fb26f5df2ea6d440fb64159faf4d8665398;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 2f2cf3c..37dcfdc 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -35,16 +35,10 @@ #include #include #include - -struct dummy_priv { - struct net_device *dev; - struct list_head list; -}; +#include static int numdummies = 1; -static int dummy_xmit(struct sk_buff *skb, struct net_device *dev); - static int dummy_set_address(struct net_device *dev, void *p) { struct sockaddr *sa = p; @@ -61,33 +55,53 @@ static void set_multicast_list(struct net_device *dev) { } -static void __init dummy_setup(struct net_device *dev) + +static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) +{ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +static const struct net_device_ops dummy_netdev_ops = { + .ndo_start_xmit = dummy_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_multicast_list = set_multicast_list, + .ndo_set_mac_address = dummy_set_address, +}; + +static void dummy_setup(struct net_device *dev) { + ether_setup(dev); + /* Initialize the device structure. */ - dev->hard_start_xmit = dummy_xmit; - dev->set_multicast_list = set_multicast_list; - dev->set_mac_address = dummy_set_address; + dev->netdev_ops = &dummy_netdev_ops; + dev->destructor = free_netdev; /* Fill in device structure with ethernet-generic values. */ - ether_setup(dev); dev->tx_queue_len = 0; - dev->change_mtu = NULL; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; - SET_MODULE_OWNER(dev); random_ether_addr(dev->dev_addr); } - -static int dummy_xmit(struct sk_buff *skb, struct net_device *dev) +static int dummy_validate(struct nlattr *tb[], struct nlattr *data[]) { - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - dev_kfree_skb(skb); + if (tb[IFLA_ADDRESS]) { + if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) + return -EINVAL; + if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) + return -EADDRNOTAVAIL; + } return 0; } -static LIST_HEAD(dummies); +static struct rtnl_link_ops dummy_link_ops __read_mostly = { + .kind = "dummy", + .setup = dummy_setup, + .validate = dummy_validate, +}; /* Number of dummy devices to be set up by this module. */ module_param(numdummies, int, 0); @@ -96,58 +110,49 @@ MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices"); static int __init dummy_init_one(void) { struct net_device *dev_dummy; - struct dummy_priv *priv; int err; - dev_dummy = alloc_netdev(sizeof(struct dummy_priv), "dummy%d", - dummy_setup); - + dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup); if (!dev_dummy) return -ENOMEM; - if ((err = register_netdev(dev_dummy))) { - free_netdev(dev_dummy); - dev_dummy = NULL; - } else { - priv = netdev_priv(dev_dummy); - priv->dev = dev_dummy; - list_add_tail(&priv->list, &dummies); - } + err = dev_alloc_name(dev_dummy, dev_dummy->name); + if (err < 0) + goto err; - return err; -} - -static void dummy_free_one(struct net_device *dev) -{ - struct dummy_priv *priv = netdev_priv(dev); + dev_dummy->rtnl_link_ops = &dummy_link_ops; + err = register_netdevice(dev_dummy); + if (err < 0) + goto err; + return 0; - list_del(&priv->list); - unregister_netdev(dev); - free_netdev(dev); +err: + free_netdev(dev_dummy); + return err; } static int __init dummy_init_module(void) { - struct dummy_priv *priv, *next; int i, err = 0; + rtnl_lock(); + err = __rtnl_link_register(&dummy_link_ops); + for (i = 0; i < numdummies && !err; i++) err = dummy_init_one(); - if (err) { - list_for_each_entry_safe(priv, next, &dummies, list) - dummy_free_one(priv->dev); - } + if (err < 0) + __rtnl_link_unregister(&dummy_link_ops); + rtnl_unlock(); + return err; } static void __exit dummy_cleanup_module(void) { - struct dummy_priv *priv, *next; - - list_for_each_entry_safe(priv, next, &dummies, list) - dummy_free_one(priv->dev); + rtnl_link_unregister(&dummy_link_ops); } module_init(dummy_init_module); module_exit(dummy_cleanup_module); MODULE_LICENSE("GPL"); +MODULE_ALIAS_RTNL_LINK("dummy");