#include <string.h>
#include <unistd.h>
+#include "dynamic-string.h"
#include "fatal-signal.h"
#include "list.h"
#include "netlink.h"
return get_etheraddr(netdev_name, mac, NULL);
}
+
+/* If 'netdev_name' is the name of a VLAN network device (e.g. one created with
+ * vconfig(8)), sets '*vlan_vid' to the VLAN VID associated with that device
+ * and returns 0. Otherwise returns a errno value (specifically ENOENT if
+ * 'netdev_name' is the name of a network device that is not a VLAN device) and
+ * sets '*vlan_vid' to -1. */
+int
+netdev_get_vlan_vid(const char *netdev_name, int *vlan_vid)
+{
+ struct ds line = DS_EMPTY_INITIALIZER;
+ FILE *stream = NULL;
+ int error;
+ char *fn;
+
+ fn = xasprintf("/proc/net/vlan/%s", netdev_name);
+ stream = fopen(fn, "r");
+ if (!stream) {
+ error = errno;
+ goto done;
+ }
+
+ if (ds_get_line(&line, stream)) {
+ if (ferror(stream)) {
+ error = errno;
+ VLOG_ERR_RL(&rl, "error reading \"%s\": %s", fn, strerror(errno));
+ } else {
+ error = EPROTO;
+ VLOG_ERR_RL(&rl, "unexpected end of file reading \"%s\"", fn);
+ }
+ goto done;
+ }
+
+ if (!sscanf(ds_cstr(&line), "%*s VID: %d", vlan_vid)) {
+ error = EPROTO;
+ VLOG_ERR_RL(&rl, "parse error reading \"%s\" line 1: \"%s\"",
+ fn, ds_cstr(&line));
+ goto done;
+ }
+
+ error = 0;
+
+done:
+ free(fn);
+ if (stream) {
+ fclose(stream);
+ }
+ ds_destroy(&line);
+ if (error) {
+ *vlan_vid = -1;
+ }
+ return error;
+}
\f
static void restore_all_flags(void *aux);
int netdev_nodev_set_etheraddr(const char *name, const uint8_t mac[6]);
int netdev_nodev_get_etheraddr(const char *netdev_name, uint8_t mac[6]);
+int netdev_get_vlan_vid(const char *netdev_name, int *vlan_vid);
+
#endif /* netdev.h */