2 * Copyright (c) 2010, 2011 Nicira Networks.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include "netdev-provider.h"
29 VLOG_DEFINE_THIS_MODULE(netdev_dummy
);
31 struct netdev_dev_dummy
{
32 struct netdev_dev netdev_dev
;
33 uint8_t hwaddr
[ETH_ADDR_LEN
];
35 struct netdev_stats stats
;
36 enum netdev_flags flags
;
37 unsigned int change_seq
;
44 static int netdev_dummy_create(const struct netdev_class
*, const char *,
45 struct netdev_dev
**);
46 static void netdev_dummy_poll_notify(const struct netdev
*);
49 is_dummy_class(const struct netdev_class
*class)
51 return class->create
== netdev_dummy_create
;
54 static struct netdev_dev_dummy
*
55 netdev_dev_dummy_cast(const struct netdev_dev
*netdev_dev
)
57 assert(is_dummy_class(netdev_dev_get_class(netdev_dev
)));
58 return CONTAINER_OF(netdev_dev
, struct netdev_dev_dummy
, netdev_dev
);
61 static struct netdev_dummy
*
62 netdev_dummy_cast(const struct netdev
*netdev
)
64 struct netdev_dev
*netdev_dev
= netdev_get_dev(netdev
);
65 assert(is_dummy_class(netdev_dev_get_class(netdev_dev
)));
66 return CONTAINER_OF(netdev
, struct netdev_dummy
, netdev
);
70 netdev_dummy_create(const struct netdev_class
*class, const char *name
,
71 struct netdev_dev
**netdev_devp
)
73 static unsigned int n
= 0xaa550000;
74 struct netdev_dev_dummy
*netdev_dev
;
76 netdev_dev
= xzalloc(sizeof *netdev_dev
);
77 netdev_dev_init(&netdev_dev
->netdev_dev
, name
, class);
78 netdev_dev
->hwaddr
[0] = 0xaa;
79 netdev_dev
->hwaddr
[1] = 0x55;
80 netdev_dev
->hwaddr
[2] = n
>> 24;
81 netdev_dev
->hwaddr
[3] = n
>> 16;
82 netdev_dev
->hwaddr
[4] = n
>> 8;
83 netdev_dev
->hwaddr
[5] = n
;
84 netdev_dev
->mtu
= 1500;
85 netdev_dev
->flags
= 0;
86 netdev_dev
->change_seq
= 1;
90 *netdev_devp
= &netdev_dev
->netdev_dev
;
96 netdev_dummy_destroy(struct netdev_dev
*netdev_dev_
)
98 struct netdev_dev_dummy
*netdev_dev
= netdev_dev_dummy_cast(netdev_dev_
);
104 netdev_dummy_open(struct netdev_dev
*netdev_dev_
, struct netdev
**netdevp
)
106 struct netdev_dummy
*netdev
;
108 netdev
= xmalloc(sizeof *netdev
);
109 netdev_init(&netdev
->netdev
, netdev_dev_
);
111 *netdevp
= &netdev
->netdev
;
116 netdev_dummy_close(struct netdev
*netdev_
)
118 struct netdev_dummy
*netdev
= netdev_dummy_cast(netdev_
);
123 netdev_dummy_listen(struct netdev
*netdev_ OVS_UNUSED
)
125 /* It's OK to listen on a dummy device. It just never receives any
131 netdev_dummy_recv(struct netdev
*netdev_ OVS_UNUSED
,
132 void *buffer OVS_UNUSED
, size_t size OVS_UNUSED
)
134 /* A dummy device never receives any packets. */
139 netdev_dummy_set_etheraddr(struct netdev
*netdev
,
140 const uint8_t mac
[ETH_ADDR_LEN
])
142 struct netdev_dev_dummy
*dev
=
143 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
145 if (!eth_addr_equals(dev
->hwaddr
, mac
)) {
146 memcpy(dev
->hwaddr
, mac
, ETH_ADDR_LEN
);
147 netdev_dummy_poll_notify(netdev
);
154 netdev_dummy_get_etheraddr(const struct netdev
*netdev
,
155 uint8_t mac
[ETH_ADDR_LEN
])
157 const struct netdev_dev_dummy
*dev
=
158 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
160 memcpy(mac
, dev
->hwaddr
, ETH_ADDR_LEN
);
165 netdev_dummy_get_mtu(const struct netdev
*netdev
, int *mtup
)
167 const struct netdev_dev_dummy
*dev
=
168 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
175 netdev_dummy_set_mtu(const struct netdev
*netdev
, int mtu
)
177 struct netdev_dev_dummy
*dev
=
178 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
185 netdev_dummy_get_stats(const struct netdev
*netdev
, struct netdev_stats
*stats
)
187 const struct netdev_dev_dummy
*dev
=
188 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
195 netdev_dummy_set_stats(struct netdev
*netdev
, const struct netdev_stats
*stats
)
197 struct netdev_dev_dummy
*dev
=
198 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
205 netdev_dummy_update_flags(struct netdev
*netdev
,
206 enum netdev_flags off
, enum netdev_flags on
,
207 enum netdev_flags
*old_flagsp
)
209 struct netdev_dev_dummy
*dev
=
210 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
212 if ((off
| on
) & ~(NETDEV_UP
| NETDEV_PROMISC
)) {
216 *old_flagsp
= dev
->flags
;
219 if (*old_flagsp
!= dev
->flags
) {
220 netdev_dummy_poll_notify(netdev
);
226 netdev_dummy_change_seq(const struct netdev
*netdev
)
228 return netdev_dev_dummy_cast(netdev_get_dev(netdev
))->change_seq
;
231 /* Helper functions. */
234 netdev_dummy_poll_notify(const struct netdev
*netdev
)
236 struct netdev_dev_dummy
*dev
=
237 netdev_dev_dummy_cast(netdev_get_dev(netdev
));
240 if (!dev
->change_seq
) {
245 static const struct netdev_class dummy_class
= {
252 netdev_dummy_destroy
,
253 NULL
, /* get_config */
254 NULL
, /* set_config */
259 netdev_dummy_listen
, /* listen */
260 netdev_dummy_recv
, /* recv */
261 NULL
, /* recv_wait */
265 NULL
, /* send_wait */
267 netdev_dummy_set_etheraddr
,
268 netdev_dummy_get_etheraddr
,
269 netdev_dummy_get_mtu
,
270 netdev_dummy_set_mtu
,
271 NULL
, /* get_ifindex */
272 NULL
, /* get_carrier */
273 NULL
, /* get_carrier_resets */
274 NULL
, /* get_miimon */
275 netdev_dummy_get_stats
,
276 netdev_dummy_set_stats
,
278 NULL
, /* get_features */
279 NULL
, /* set_advertisements */
281 NULL
, /* set_policing */
282 NULL
, /* get_qos_types */
283 NULL
, /* get_qos_capabilities */
286 NULL
, /* get_queue */
287 NULL
, /* set_queue */
288 NULL
, /* delete_queue */
289 NULL
, /* get_queue_stats */
290 NULL
, /* dump_queues */
291 NULL
, /* dump_queue_stats */
296 NULL
, /* add_router */
297 NULL
, /* get_next_hop */
298 NULL
, /* get_status */
299 NULL
, /* arp_lookup */
301 netdev_dummy_update_flags
,
303 netdev_dummy_change_seq
307 netdev_dummy_register(void)
309 netdev_register_provider(&dummy_class
);