Neither of these constructs are used anymore.
VLOG_DEFINE_THIS_MODULE(netdev_dummy);
-struct netdev_dummy_notifier {
- struct netdev_notifier notifier;
- struct list list_node;
- struct shash_node *shash_node;
-};
-
struct netdev_dev_dummy {
struct netdev_dev netdev_dev;
uint8_t hwaddr[ETH_ADDR_LEN];
struct netdev netdev;
};
-static struct shash netdev_dummy_notifiers =
- SHASH_INITIALIZER(&netdev_dummy_notifiers);
-
static int netdev_dummy_create(const struct netdev_class *, const char *,
const struct shash *, struct netdev_dev **);
static void netdev_dummy_poll_notify(const struct netdev *);
return 0;
}
-static int
-netdev_dummy_poll_add(struct netdev *netdev,
- void (*cb)(struct netdev_notifier *), void *aux,
- struct netdev_notifier **notifierp)
-{
- const char *name = netdev_get_name(netdev);
- struct netdev_dummy_notifier *notifier;
- struct list *list;
- struct shash_node *shash_node;
-
- shash_node = shash_find_data(&netdev_dummy_notifiers, name);
- if (!shash_node) {
- list = xmalloc(sizeof *list);
- list_init(list);
- shash_node = shash_add(&netdev_dummy_notifiers, name, list);
- } else {
- list = shash_node->data;
- }
-
- notifier = xmalloc(sizeof *notifier);
- netdev_notifier_init(¬ifier->notifier, netdev, cb, aux);
- list_push_back(list, ¬ifier->list_node);
- notifier->shash_node = shash_node;
-
- *notifierp = ¬ifier->notifier;
-
- return 0;
-}
-
-static void
-netdev_dummy_poll_remove(struct netdev_notifier *notifier_)
-{
- struct netdev_dummy_notifier *notifier =
- CONTAINER_OF(notifier_, struct netdev_dummy_notifier, notifier);
-
- struct list *list;
-
- list = list_remove(¬ifier->list_node);
- if (list_is_empty(list)) {
- shash_delete(&netdev_dummy_notifiers, notifier->shash_node);
- free(list);
- }
-
- free(notifier);
-}
-
static unsigned int
netdev_dummy_change_seq(const struct netdev *netdev)
{
static void
netdev_dummy_poll_notify(const struct netdev *netdev)
{
- const char *name = netdev_get_name(netdev);
- struct list *list = shash_find_data(&netdev_dummy_notifiers, name);
struct netdev_dev_dummy *dev =
netdev_dev_dummy_cast(netdev_get_dev(netdev));
- if (list) {
- struct netdev_dummy_notifier *notifier;
-
- LIST_FOR_EACH (notifier, list_node, list) {
- struct netdev_notifier *n = ¬ifier->notifier;
- n->cb(n);
- }
- }
-
dev->change_seq++;
if (!dev->change_seq) {
dev->change_seq++;
netdev_dummy_update_flags,
- netdev_dummy_poll_add,
- netdev_dummy_poll_remove,
netdev_dummy_change_seq
};
/* A Netlink routing socket that is not subscribed to any multicast groups. */
static struct nl_sock *rtnl_sock;
-struct netdev_linux_notifier {
- struct netdev_notifier notifier;
- struct list node;
-};
-
-static struct shash netdev_linux_notifiers =
- SHASH_INITIALIZER(&netdev_linux_notifiers);
-static struct rtnetlink_notifier netdev_linux_poll_notifier;
-
/* This is set pretty low because we probably won't learn anything from the
* additional log messages. */
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
static int get_stats_via_netlink(int ifindex, struct netdev_stats *stats);
static int get_stats_via_proc(const char *netdev_name, struct netdev_stats *stats);
static int af_packet_sock(void);
-static void poll_notify(struct list *);
static void netdev_linux_miimon_run(void);
static void netdev_linux_miimon_wait(void);
netdev_linux_get_miimon(dev->netdev_dev.name, &miimon);
if (miimon != dev->miimon) {
- struct list *list;
-
dev->miimon = miimon;
- list = shash_find_data(&netdev_linux_notifiers,
- dev->netdev_dev.name);
- if (list) {
- poll_notify(list);
- }
netdev_dev_linux_changed(dev);
}
return error;
}
-static void
-poll_notify(struct list *list)
-{
- struct netdev_linux_notifier *notifier;
- LIST_FOR_EACH (notifier, node, list) {
- struct netdev_notifier *n = ¬ifier->notifier;
- n->cb(n);
- }
-}
-
-static void
-netdev_linux_poll_cb(const struct rtnetlink_link_change *change,
- void *aux OVS_UNUSED)
-{
- if (change) {
- struct list *list = shash_find_data(&netdev_linux_notifiers,
- change->ifname);
- if (list) {
- poll_notify(list);
- }
- } else {
- struct shash_node *node;
- SHASH_FOR_EACH (node, &netdev_linux_notifiers) {
- poll_notify(node->data);
- }
- }
-}
-
-static int
-netdev_linux_poll_add(struct netdev *netdev,
- void (*cb)(struct netdev_notifier *), void *aux,
- struct netdev_notifier **notifierp)
-{
- const char *netdev_name = netdev_get_name(netdev);
- struct netdev_linux_notifier *notifier;
- struct list *list;
-
- if (shash_is_empty(&netdev_linux_notifiers)) {
- int error;
- error = rtnetlink_link_notifier_register(&netdev_linux_poll_notifier,
- netdev_linux_poll_cb, NULL);
- if (error) {
- return error;
- }
- }
-
- list = shash_find_data(&netdev_linux_notifiers, netdev_name);
- if (!list) {
- list = xmalloc(sizeof *list);
- list_init(list);
- shash_add(&netdev_linux_notifiers, netdev_name, list);
- }
-
- notifier = xmalloc(sizeof *notifier);
- netdev_notifier_init(¬ifier->notifier, netdev, cb, aux);
- list_push_back(list, ¬ifier->node);
- *notifierp = ¬ifier->notifier;
- return 0;
-}
-
-static void
-netdev_linux_poll_remove(struct netdev_notifier *notifier_)
-{
- struct netdev_linux_notifier *notifier =
- CONTAINER_OF(notifier_, struct netdev_linux_notifier, notifier);
- struct list *list;
-
- /* Remove 'notifier' from its list. */
- list = list_remove(¬ifier->node);
- if (list_is_empty(list)) {
- /* The list is now empty. Remove it from the hash and free it. */
- const char *netdev_name = netdev_get_name(notifier->notifier.netdev);
- shash_delete(&netdev_linux_notifiers,
- shash_find(&netdev_linux_notifiers, netdev_name));
- free(list);
- }
- free(notifier);
-
- /* If that was the last notifier, unregister. */
- if (shash_is_empty(&netdev_linux_notifiers)) {
- rtnetlink_link_notifier_unregister(&netdev_linux_poll_notifier);
- }
-}
-
static unsigned int
netdev_linux_change_seq(const struct netdev *netdev)
{
\
netdev_linux_update_flags, \
\
- netdev_linux_poll_add, \
- netdev_linux_poll_remove, \
netdev_linux_change_seq \
}
netdev_dev_assert_class(netdev_get_dev(netdev), netdev_class);
}
-/* A network device notifier.
- *
- * Network device implementations should use netdev_notifier_init() to
- * initialize this structure, but they may freely read its members after
- * initialization. */
-struct netdev_notifier {
- struct netdev *netdev;
- void (*cb)(struct netdev_notifier *);
- void *aux;
-};
-void netdev_notifier_init(struct netdev_notifier *, struct netdev *,
- void (*cb)(struct netdev_notifier *), void *aux);
-
/* Network device class structure, to be defined by each implementation of a
* network device.
*
int (*update_flags)(struct netdev *netdev, enum netdev_flags off,
enum netdev_flags on, enum netdev_flags *old_flags);
- /* Arranges for 'cb' to be called whenever one of the attributes of
- * 'netdev' changes and sets '*notifierp' to a newly created
- * netdev_notifier that represents this arrangement. The created notifier
- * will have its 'netdev', 'cb', and 'aux' members set to the values of the
- * corresponding parameters. */
- int (*poll_add)(struct netdev *netdev,
- void (*cb)(struct netdev_notifier *notifier), void *aux,
- struct netdev_notifier **notifierp);
-
- /* Cancels poll notification for 'notifier'. */
- void (*poll_remove)(struct netdev_notifier *notifier);
-
/* Returns a sequence number which indicates changes in one of 'netdev''s
* properties. The returned sequence number must be nonzero so that
* callers have a value which they may use as a reset when tracking
VLOG_DEFINE_THIS_MODULE(netdev_vport);
-struct netdev_vport_notifier {
- struct netdev_notifier notifier;
- struct list list_node;
- struct shash_node *shash_node;
-};
-
struct netdev_dev_vport {
struct netdev_dev netdev_dev;
struct ofpbuf *options;
struct shash *args);
};
-static struct shash netdev_vport_notifiers =
- SHASH_INITIALIZER(&netdev_vport_notifiers);
-
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
static int netdev_vport_create(const struct netdev_class *, const char *,
return 0;
}
-static char *
-make_poll_name(const struct netdev *netdev)
-{
- return xasprintf("%s:%s", netdev_get_type(netdev), netdev_get_name(netdev));
-}
-
-static int
-netdev_vport_poll_add(struct netdev *netdev,
- void (*cb)(struct netdev_notifier *), void *aux,
- struct netdev_notifier **notifierp)
-{
- char *poll_name = make_poll_name(netdev);
- struct netdev_vport_notifier *notifier;
- struct list *list;
- struct shash_node *shash_node;
-
- shash_node = shash_find(&netdev_vport_notifiers, poll_name);
- if (!shash_node) {
- list = xmalloc(sizeof *list);
- list_init(list);
- shash_node = shash_add(&netdev_vport_notifiers, poll_name, list);
- } else {
- list = shash_node->data;
- }
-
- notifier = xmalloc(sizeof *notifier);
- netdev_notifier_init(¬ifier->notifier, netdev, cb, aux);
- list_push_back(list, ¬ifier->list_node);
- notifier->shash_node = shash_node;
-
- *notifierp = ¬ifier->notifier;
- free(poll_name);
-
- return 0;
-}
-
-static void
-netdev_vport_poll_remove(struct netdev_notifier *notifier_)
-{
- struct netdev_vport_notifier *notifier =
- CONTAINER_OF(notifier_, struct netdev_vport_notifier, notifier);
-
- struct list *list;
-
- list = list_remove(¬ifier->list_node);
- if (list_is_empty(list)) {
- shash_delete(&netdev_vport_notifiers, notifier->shash_node);
- free(list);
- }
-
- free(notifier);
-}
-
static unsigned int
netdev_vport_change_seq(const struct netdev *netdev)
{
static void
netdev_vport_poll_notify(const struct netdev *netdev)
{
- char *poll_name = make_poll_name(netdev);
- struct list *list = shash_find_data(&netdev_vport_notifiers,
- poll_name);
struct netdev_dev_vport *ndv;
ndv = netdev_dev_vport_cast(netdev_get_dev(netdev));
- if (list) {
- struct netdev_vport_notifier *notifier;
-
- LIST_FOR_EACH (notifier, list_node, list) {
- struct netdev_notifier *n = ¬ifier->notifier;
- n->cb(n);
- }
- }
-
ndv->change_seq++;
if (!ndv->change_seq) {
ndv->change_seq++;
}
-
- free(poll_name);
}
\f
/* Code specific to individual vport types. */
\
netdev_vport_update_flags, \
\
- netdev_vport_poll_add, \
- netdev_vport_poll_remove, \
netdev_vport_change_seq
void
{
return netdev->netdev_dev;
}
-
-/* Initializes 'notifier' as a netdev notifier for 'netdev', for which
- * notification will consist of calling 'cb', with auxiliary data 'aux'. */
-void
-netdev_notifier_init(struct netdev_notifier *notifier, struct netdev *netdev,
- void (*cb)(struct netdev_notifier *), void *aux)
-{
- notifier->netdev = netdev;
- notifier->cb = cb;
- notifier->aux = aux;
-}
-\f
-/* Tracks changes in the status of a set of network devices. */
-struct netdev_monitor {
- struct shash polled_netdevs;
- struct sset changed_netdevs;
-};
-
-/* Creates and returns a new structure for monitor changes in the status of
- * network devices. */
-struct netdev_monitor *
-netdev_monitor_create(void)
-{
- struct netdev_monitor *monitor = xmalloc(sizeof *monitor);
- shash_init(&monitor->polled_netdevs);
- sset_init(&monitor->changed_netdevs);
- return monitor;
-}
-
-/* Destroys 'monitor'. */
-void
-netdev_monitor_destroy(struct netdev_monitor *monitor)
-{
- if (monitor) {
- struct shash_node *node;
-
- SHASH_FOR_EACH (node, &monitor->polled_netdevs) {
- struct netdev_notifier *notifier = node->data;
- netdev_get_dev(notifier->netdev)->netdev_class->poll_remove(
- notifier);
- }
-
- shash_destroy(&monitor->polled_netdevs);
- sset_destroy(&monitor->changed_netdevs);
- free(monitor);
- }
-}
-
-static void
-netdev_monitor_cb(struct netdev_notifier *notifier)
-{
- struct netdev_monitor *monitor = notifier->aux;
- const char *name = netdev_get_name(notifier->netdev);
- sset_add(&monitor->changed_netdevs, name);
-}
-
-/* Attempts to add 'netdev' as a netdev monitored by 'monitor'. Returns 0 if
- * successful, otherwise a positive errno value.
- *
- * Adding a given 'netdev' to a monitor multiple times is equivalent to adding
- * it once. */
-int
-netdev_monitor_add(struct netdev_monitor *monitor, struct netdev *netdev)
-{
- const char *netdev_name = netdev_get_name(netdev);
- int error = 0;
- if (!shash_find(&monitor->polled_netdevs, netdev_name)
- && netdev_get_dev(netdev)->netdev_class->poll_add)
- {
- struct netdev_notifier *notifier;
- error = netdev_get_dev(netdev)->netdev_class->poll_add(netdev,
- netdev_monitor_cb, monitor, ¬ifier);
- if (!error) {
- assert(notifier->netdev == netdev);
- shash_add(&monitor->polled_netdevs, netdev_name, notifier);
- }
- }
- return error;
-}
-
-/* Removes 'netdev' from the set of netdevs monitored by 'monitor'. (This has
- * no effect if 'netdev' is not in the set of devices monitored by
- * 'monitor'.) */
-void
-netdev_monitor_remove(struct netdev_monitor *monitor, struct netdev *netdev)
-{
- const char *netdev_name = netdev_get_name(netdev);
- struct shash_node *node;
-
- node = shash_find(&monitor->polled_netdevs, netdev_name);
- if (node) {
- /* Cancel future notifications. */
- struct netdev_notifier *notifier = node->data;
- netdev_get_dev(netdev)->netdev_class->poll_remove(notifier);
- shash_delete(&monitor->polled_netdevs, node);
-
- /* Drop any pending notification. */
- sset_find_and_delete(&monitor->changed_netdevs, netdev_name);
- }
-}
-
-/* Checks for changes to netdevs in the set monitored by 'monitor'. If any of
- * the attributes (Ethernet address, carrier status, speed or peer-advertised
- * speed, flags, etc.) of a network device monitored by 'monitor' has changed,
- * sets '*devnamep' to the name of a device that has changed and returns 0.
- * The caller is responsible for freeing '*devnamep' (with free()).
- *
- * If no devices have changed, sets '*devnamep' to NULL and returns EAGAIN. */
-int
-netdev_monitor_poll(struct netdev_monitor *monitor, char **devnamep)
-{
- if (sset_is_empty(&monitor->changed_netdevs)) {
- *devnamep = NULL;
- return EAGAIN;
- } else {
- *devnamep = sset_pop(&monitor->changed_netdevs);
- return 0;
- }
-}
-
-/* Clears all notifications from 'monitor'. May be called instead of
- * netdev_monitor_poll() by clients which don't care specifically which netdevs
- * have changed. */
-void
-netdev_monitor_flush(struct netdev_monitor *monitor)
-{
- sset_clear(&monitor->changed_netdevs);
-}
-
-/* Registers with the poll loop to wake up from the next call to poll_block()
- * when netdev_monitor_poll(monitor) would indicate that a device has
- * changed. */
-void
-netdev_monitor_poll_wait(const struct netdev_monitor *monitor)
-{
- if (!sset_is_empty(&monitor->changed_netdevs)) {
- poll_immediate_wake();
- } else {
- /* XXX Nothing needed here for netdev_linux, but maybe other netdev
- * classes need help. */
- }
-}
\f
/* Restore the network device flags on 'netdev' to those that were active
* before we changed them. Returns 0 if successful, otherwise a positive
/* Linux stuff. */
int netdev_get_vlan_vid(const struct netdev *, int *vlan_vid);
-/* Monitoring for changes in network device status. */
-struct netdev_monitor *netdev_monitor_create(void);
-void netdev_monitor_destroy(struct netdev_monitor *);
-int netdev_monitor_add(struct netdev_monitor *, struct netdev *);
-void netdev_monitor_remove(struct netdev_monitor *, struct netdev *);
-int netdev_monitor_poll(struct netdev_monitor *, char **devnamep);
-void netdev_monitor_flush(struct netdev_monitor *);
-void netdev_monitor_poll_wait(const struct netdev_monitor *);
-
#ifdef __cplusplus
}
#endif