* to the new network device, otherwise to null.
*
* If this is the first time the device has been opened, then create is called
- * before opening. The device is created using the given type and arguments.
+ * before opening. The device is created using the given type and arguments.
*
* 'ethertype' may be a 16-bit Ethernet protocol value in host byte order to
* capture frames of that type received on the device. It may also be one of
* the 'enum netdev_pseudo_ethertype' values to receive frames in one of those
* categories. */
-
int
netdev_open(struct netdev_options *options, struct netdev **netdevp)
{
return netdev_open(&options, netdevp);
}
+/* Increments the reference count on 'netdev'. Returns 'netdev'. */
+struct netdev *
+netdev_reopen(struct netdev *netdev)
+{
+ netdev->ref_cnt++;
+ return netdev;
+}
+
/* Reconfigures the device 'netdev' with 'args'. 'args' may be empty
* or NULL if none are needed. */
int
return 0;
}
-/* Closes and destroys 'netdev'. */
+/* Decrements the reference count on 'netdev'. If the reference count reaches
+ * zero, closes and destroys 'netdev'. */
void
netdev_close(struct netdev *netdev)
{
- if (netdev) {
+ assert(!netdev || netdev->ref_cnt > 0);
+ if (netdev && !--netdev->ref_cnt) {
struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
assert(netdev_dev->ref_cnt);
* be returned.
*
* Some network devices may not implement support for this function. In such
- * cases this function will always return EOPNOTSUPP.
- */
+ * cases this function will always return EOPNOTSUPP. */
int
netdev_recv(struct netdev *netdev, struct ofpbuf *buffer)
{
* passed-in values are set to 0.
*
* Some network devices may not implement support for this function. In such
- * cases this function will always return EOPNOTSUPP.
- */
+ * cases this function will always return EOPNOTSUPP. */
int
netdev_get_features(struct netdev *netdev,
uint32_t *current, uint32_t *advertised,
*
* - EOPNOTSUPP: No IPv4 network stack attached to 'netdev'.
*
- * 'address' or 'netmask' or both may be null, in which case the address or netmask
- * is not reported. */
+ * 'address' or 'netmask' or both may be null, in which case the address or
+ * netmask is not reported. */
int
netdev_get_in4(const struct netdev *netdev,
struct in_addr *address_, struct in_addr *netmask_)
* the current form of QoS (e.g. as returned by netdev_get_n_queues(netdev)).
*
* This function does not modify 'details', and the caller retains ownership of
- * it.
- */
+ * it. */
int
netdev_set_queue(struct netdev *netdev,
unsigned int queue_id, const struct shash *details)
{
memset(netdev, 0, sizeof *netdev);
netdev->netdev_dev = netdev_dev;
+ netdev->ref_cnt = 1;
list_push_back(&netdev_list, &netdev->node);
}
*
* Normally this function only needs to be called from netdev_close().
* However, it may be called by providers due to an error on opening
- * that occurs after initialization. It this case netdev_close() would
+ * that occurs after initialization. In this case netdev_close() would
* never be called. */
void
netdev_uninit(struct netdev *netdev, bool close)
* 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.
- */
+ * If no devices have changed, sets '*devnamep' to NULL and returns EAGAIN. */
int
netdev_monitor_poll(struct netdev_monitor *monitor, char **devnamep)
{
*devnamep = NULL;
return EAGAIN;
} else {
- *devnamep = xstrdup(node->name);
- shash_delete(&monitor->changed_netdevs, node);
+ *devnamep = shash_steal(&monitor->changed_netdevs, node);
return 0;
}
}
close_all_netdevs(void *aux OVS_UNUSED)
{
struct netdev *netdev, *next;
- LIST_FOR_EACH_SAFE(netdev, next, struct netdev, node, &netdev_list) {
+ LIST_FOR_EACH_SAFE(netdev, next, node, &netdev_list) {
netdev_close(netdev);
}
}