enum netdev_flags save_flags; /* Initial device flags. */
enum netdev_flags changed_flags; /* Flags that we changed. */
+
+ int ref_cnt; /* Times this 'netdev' was opened. */
};
void netdev_init(struct netdev *, struct netdev_dev *);
* If the 'may_open' flag is set then the call will succeed even if another
* caller has already opened it. It may be to false if the device should not
* currently be open. */
-
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);
{
memset(netdev, 0, sizeof *netdev);
netdev->netdev_dev = netdev_dev;
+ netdev->ref_cnt = 1;
list_push_back(&netdev_list, &netdev->node);
}
int netdev_open(struct netdev_options *, struct netdev **);
int netdev_open_default(const char *name, struct netdev **);
+struct netdev *netdev_reopen(struct netdev *);
int netdev_reconfigure(struct netdev *, const struct shash *args);
void netdev_close(struct netdev *);