From: Ben Pfaff Date: Fri, 20 Mar 2009 20:38:48 +0000 (-0700) Subject: netdev: New function for obtaining the VID of a VLAN network device. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47f8dcce0e336fe95e8b8efdbca0ac9fd6b80b1c;p=openvswitch netdev: New function for obtaining the VID of a VLAN network device. 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. --- diff --git a/lib/netdev.c b/lib/netdev.c index f754cad3..1dd33b88 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -59,6 +59,7 @@ #include #include +#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; +} static void restore_all_flags(void *aux); diff --git a/lib/netdev.h b/lib/netdev.h index 6981803a..4afaff65 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -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 */