- if (!nl_policy_parse(reply, NLMSG_HDRLEN + sizeof(struct ifinfomsg),
- rtnlgrp_link_policy,
- attrs, ARRAY_SIZE(rtnlgrp_link_policy))) {
- ofpbuf_delete(reply);
- return EPROTO;
- }
-
- if (!attrs[IFLA_STATS]) {
- VLOG_WARN_RL(&rl, "RTM_GETLINK reply lacks stats");
- ofpbuf_delete(reply);
- return EPROTO;
- }
-
- netdev_stats_from_rtnl_link_stats(stats, nl_attr_get(attrs[IFLA_STATS]));
-
- ofpbuf_delete(reply);
-
- return 0;
-}
-
-static int
-get_stats_via_proc(const char *netdev_name, struct netdev_stats *stats)
-{
- static const char fn[] = "/proc/net/dev";
- char line[1024];
- FILE *stream;
- int ln;
-
- stream = fopen(fn, "r");
- if (!stream) {
- VLOG_WARN_RL(&rl, "%s: open failed: %s", fn, strerror(errno));
- return errno;
- }
-
- ln = 0;
- while (fgets(line, sizeof line, stream)) {
- if (++ln >= 3) {
- char devname[16];
-#define X64 "%"SCNu64
- if (sscanf(line,
- " %15[^:]:"
- X64 X64 X64 X64 X64 X64 X64 "%*u"
- X64 X64 X64 X64 X64 X64 X64 "%*u",
- devname,
- &stats->rx_bytes,
- &stats->rx_packets,
- &stats->rx_errors,
- &stats->rx_dropped,
- &stats->rx_fifo_errors,
- &stats->rx_frame_errors,
- &stats->multicast,
- &stats->tx_bytes,
- &stats->tx_packets,
- &stats->tx_errors,
- &stats->tx_dropped,
- &stats->tx_fifo_errors,
- &stats->collisions,
- &stats->tx_carrier_errors) != 15) {
- VLOG_WARN_RL(&rl, "%s:%d: parse error", fn, ln);
- } else if (!strcmp(devname, netdev_name)) {
- stats->rx_length_errors = UINT64_MAX;
- stats->rx_over_errors = UINT64_MAX;
- stats->rx_crc_errors = UINT64_MAX;
- stats->rx_missed_errors = UINT64_MAX;
- stats->tx_aborted_errors = UINT64_MAX;
- stats->tx_heartbeat_errors = UINT64_MAX;
- stats->tx_window_errors = UINT64_MAX;
- fclose(stream);
- return 0;
- }
- }
- }
- VLOG_WARN_RL(&rl, "%s: no stats for %s", fn, netdev_name);
- fclose(stream);
- return ENODEV;
-}
-
-static int
-get_carrier_via_sysfs(const char *name, bool *carrier)
-{
- char line[8];
- int retval;
-
- int error = 0;
- char *fn = NULL;
- int fd = -1;
-
- *carrier = false;
-
- fn = xasprintf("/sys/class/net/%s/carrier", name);
- fd = open(fn, O_RDONLY);
- if (fd < 0) {
- error = errno;
- VLOG_WARN_RL(&rl, "%s: open failed: %s", fn, strerror(error));
- goto exit;
- }
-
- retval = read(fd, line, sizeof line);
- if (retval < 0) {
- error = errno;
- if (error == EINVAL) {
- /* This is the normal return value when we try to check carrier if
- * the network device is not up. */