netdev: New function for obtaining the VID of a VLAN network device.
authorBen Pfaff <blp@nicira.com>
Fri, 20 Mar 2009 20:38:48 +0000 (13:38 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 20 Mar 2009 20:51:23 +0000 (13:51 -0700)
This is needed for autogenerating a unique datapath ID on Xen, on which
a VLAN bridge reuses the bridge address of the VLAN device's physical
network device.

lib/netdev.c
lib/netdev.h

index f754cad3b563506879c03c108354ba0ddb87444f..1dd33b88b09076ecd8f73b941be0c3ced4ea8ae5 100644 (file)
@@ -59,6 +59,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "dynamic-string.h"
 #include "fatal-signal.h"
 #include "list.h"
 #include "netlink.h"
@@ -1201,6 +1202,58 @@ netdev_nodev_get_etheraddr(const char *netdev_name, uint8_t mac[6])
 
     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);
 
index 6981803ae9256ffdcf94540f8124fed9004d16af..4afaff6554862c9dbaac2ab722e21878fc910e50 100644 (file)
@@ -124,4 +124,6 @@ int netdev_nodev_get_flags(const char *netdev_name, enum netdev_flags *);
 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 */