static int do_open_netdev(const char *name, int ethertype, int tap_fd,
struct netdev **netdev_);
static int restore_flags(struct netdev *netdev);
-static int get_flags(const struct netdev *, int fd, int *flagsp);
-static int set_flags(struct netdev *, int flags);
+static int get_flags(const char *netdev_name, int *flagsp);
+static int set_flags(const char *netdev_name, int flags);
/* Obtains the IPv6 address for 'name' into 'in6'. */
static void
do_ethtool(netdev);
/* Save flags to restore at close or exit. */
- error = get_flags(netdev, netdev_fd, &netdev->save_flags);
+ error = get_flags(netdev->name, &netdev->save_flags);
if (error) {
goto error_already_set;
}
int
netdev_get_flags(const struct netdev *netdev, enum netdev_flags *flagsp)
{
- int error, flags;
-
- error = get_flags(netdev, netdev->netdev_fd, &flags);
- if (error) {
- return error;
- }
-
- *flagsp = 0;
- if (flags & IFF_UP) {
- *flagsp |= NETDEV_UP;
- }
- if (flags & IFF_PROMISC) {
- *flagsp |= NETDEV_PROMISC;
- }
- return 0;
+ return netdev_nodev_get_flags(netdev->name, flagsp);
}
static int
* will be reverted when 'netdev' is closed or the program exits. Returns 0 if
* successful, otherwise a positive errno value. */
static int
-do_update_flags(struct netdev *netdev, int fd, enum netdev_flags off,
+do_update_flags(struct netdev *netdev, enum netdev_flags off,
enum netdev_flags on, bool permanent)
{
int old_flags, new_flags;
int error;
- error = get_flags(netdev, fd, &old_flags);
+ error = get_flags(netdev->name, &old_flags);
if (error) {
return error;
}
netdev->changed_flags |= new_flags ^ old_flags;
}
if (new_flags != old_flags) {
- error = set_flags(netdev, new_flags);
+ error = set_flags(netdev->name, new_flags);
}
return error;
}
netdev_set_flags(struct netdev *netdev, enum netdev_flags flags,
bool permanent)
{
- return do_update_flags(netdev, netdev->netdev_fd, -1, flags, permanent);
+ return do_update_flags(netdev, -1, flags, permanent);
}
/* Turns on the specified 'flags' on 'netdev'.
netdev_turn_flags_on(struct netdev *netdev, enum netdev_flags flags,
bool permanent)
{
- return do_update_flags(netdev, netdev->netdev_fd, 0, flags, permanent);
+ return do_update_flags(netdev, 0, flags, permanent);
}
/* Turns off the specified 'flags' on 'netdev'.
netdev_turn_flags_off(struct netdev *netdev, enum netdev_flags flags,
bool permanent)
{
- return do_update_flags(netdev, netdev->netdev_fd, flags, 0, permanent);
+ return do_update_flags(netdev, flags, 0, permanent);
}
/* Looks up the ARP table entry for 'ip' on 'netdev'. If one exists and can be
strerror(errno));
}
}
+
+/* Obtains the current flags for the network device named 'netdev_name' and
+ * stores them into '*flagsp'. Returns 0 if successful, otherwise a positive
+ * errno value.
+ *
+ * If only device flags are needed, this is more efficient than calling
+ * netdev_open(), netdev_get_flags(), netdev_close(). */
+int
+netdev_nodev_get_flags(const char *netdev_name, enum netdev_flags *flagsp)
+{
+ int error, flags;
+
+ init_netdev();
+
+ error = get_flags(netdev_name, &flags);
+ if (error) {
+ return error;
+ }
+
+ *flagsp = 0;
+ if (flags & IFF_UP) {
+ *flagsp |= NETDEV_UP;
+ }
+ if (flags & IFF_PROMISC) {
+ *flagsp |= NETDEV_PROMISC;
+ }
+ return 0;
+}
\f
static void restore_all_flags(void *aux);
}
static int
-get_flags(const struct netdev *netdev, int fd, int *flags)
+get_flags(const char *netdev_name, int *flags)
{
struct ifreq ifr;
- strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name);
- if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+ strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
+ if (ioctl(af_inet_sock, SIOCGIFFLAGS, &ifr) < 0) {
VLOG_ERR("ioctl(SIOCGIFFLAGS) on %s device failed: %s",
- netdev->name, strerror(errno));
+ netdev_name, strerror(errno));
return errno;
}
*flags = ifr.ifr_flags;
}
static int
-set_flags(struct netdev *netdev, int flags)
+set_flags(const char *netdev_name, int flags)
{
struct ifreq ifr;
- strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name);
+ strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
ifr.ifr_flags = flags;
- if (ioctl(netdev->netdev_fd, SIOCSIFFLAGS, &ifr) < 0) {
+ if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) < 0) {
VLOG_ERR("ioctl(SIOCSIFFLAGS) on %s device failed: %s",
- netdev->name, strerror(errno));
+ netdev_name, strerror(errno));
return errno;
}
return 0;