]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/dummy.c
[RTNETLINK]: rtnl_link API simplification
[mirror_ubuntu-artful-kernel.git] / drivers / net / dummy.c
CommitLineData
1da177e4
LT
1/* dummy.c: a dummy net driver
2
3 The purpose of this driver is to provide a device to point a
4 route through, but not to actually transmit packets.
5
6 Why? If you have a machine whose only connection is an occasional
7 PPP/SLIP/PLIP link, you can only connect to your own hostname
8 when the link is up. Otherwise you have to use localhost.
9 This isn't very consistent.
10
11 One solution is to set up a dummy link using PPP/SLIP/PLIP,
12 but this seems (to me) too much overhead for too little gain.
13 This driver provides a small alternative. Thus you can do
6aa20a22 14
1da177e4
LT
15 [when not running slip]
16 ifconfig dummy slip.addr.ess.here up
17 [to go to slip]
18 ifconfig dummy down
19 dip whatever
20
21 This was written by looking at Donald Becker's skeleton driver
22 and the loopback driver. I then threw away anything that didn't
23 apply! Thanks to Alan Cox for the key clue on what to do with
24 misguided packets.
25
26 Nick Holloway, 27th May 1994
27 [I tweaked this explanation a little but that's all]
28 Alan Cox, 30th May 1994
29*/
30
1da177e4
LT
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/netdevice.h>
34#include <linux/etherdevice.h>
35#include <linux/init.h>
36#include <linux/moduleparam.h>
206c9fb2 37#include <linux/rtnetlink.h>
5d5cb173 38#include <net/rtnetlink.h>
206c9fb2 39
1da177e4
LT
40static int numdummies = 1;
41
42static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
1da177e4
LT
43
44static int dummy_set_address(struct net_device *dev, void *p)
45{
46 struct sockaddr *sa = p;
47
6aa20a22 48 if (!is_valid_ether_addr(sa->sa_data))
1da177e4 49 return -EADDRNOTAVAIL;
6aa20a22 50
1da177e4
LT
51 memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
52 return 0;
53}
54
55/* fake multicast ability */
56static void set_multicast_list(struct net_device *dev)
57{
58}
59
5d5cb173 60static void dummy_setup(struct net_device *dev)
1da177e4
LT
61{
62 /* Initialize the device structure. */
1da177e4
LT
63 dev->hard_start_xmit = dummy_xmit;
64 dev->set_multicast_list = set_multicast_list;
65 dev->set_mac_address = dummy_set_address;
5d5cb173 66 dev->destructor = free_netdev;
1da177e4
LT
67
68 /* Fill in device structure with ethernet-generic values. */
69 ether_setup(dev);
70 dev->tx_queue_len = 0;
71 dev->change_mtu = NULL;
72 dev->flags |= IFF_NOARP;
73 dev->flags &= ~IFF_MULTICAST;
74 SET_MODULE_OWNER(dev);
75 random_ether_addr(dev->dev_addr);
76}
77
78static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
79{
58651b24
PM
80 dev->stats.tx_packets++;
81 dev->stats.tx_bytes += skb->len;
1da177e4
LT
82
83 dev_kfree_skb(skb);
84 return 0;
85}
86
5d5cb173
PM
87static struct rtnl_link_ops dummy_link_ops __read_mostly = {
88 .kind = "dummy",
5d5cb173 89 .setup = dummy_setup,
5d5cb173
PM
90};
91
1da177e4
LT
92/* Number of dummy devices to be set up by this module. */
93module_param(numdummies, int, 0);
94MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
95
206c9fb2 96static int __init dummy_init_one(void)
1da177e4
LT
97{
98 struct net_device *dev_dummy;
99 int err;
100
2d85cba2 101 dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup);
1da177e4
LT
102 if (!dev_dummy)
103 return -ENOMEM;
104
5d5cb173
PM
105 err = dev_alloc_name(dev_dummy, dev_dummy->name);
106 if (err < 0)
107 goto err;
1da177e4 108
5d5cb173
PM
109 dev_dummy->rtnl_link_ops = &dummy_link_ops;
110 err = register_netdevice(dev_dummy);
111 if (err < 0)
112 goto err;
5d5cb173 113 return 0;
206c9fb2 114
5d5cb173
PM
115err:
116 free_netdev(dev_dummy);
117 return err;
6aa20a22 118}
1da177e4
LT
119
120static int __init dummy_init_module(void)
6aa20a22 121{
1da177e4 122 int i, err = 0;
206c9fb2 123
5d5cb173
PM
124 rtnl_lock();
125 err = __rtnl_link_register(&dummy_link_ops);
126
1da177e4 127 for (i = 0; i < numdummies && !err; i++)
206c9fb2 128 err = dummy_init_one();
2d85cba2 129 if (err < 0)
5d5cb173 130 __rtnl_link_unregister(&dummy_link_ops);
5d5cb173
PM
131 rtnl_unlock();
132
1da177e4 133 return err;
6aa20a22 134}
1da177e4
LT
135
136static void __exit dummy_cleanup_module(void)
137{
2d85cba2 138 rtnl_link_unregister(&dummy_link_ops);
1da177e4
LT
139}
140
141module_init(dummy_init_module);
142module_exit(dummy_cleanup_module);
143MODULE_LICENSE("GPL");
5d5cb173 144MODULE_ALIAS_RTNL_LINK("dummy");