summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bridge.c1
-rw-r--r--device.c2
-rw-r--r--system-dummy.c10
-rw-r--r--system-linux.c68
-rw-r--r--system.h1
5 files changed, 62 insertions, 20 deletions
diff --git a/bridge.c b/bridge.c
index 5337e3a..48e1665 100644
--- a/bridge.c
+++ b/bridge.c
@@ -336,6 +336,7 @@ bridge_dump_info(struct device *dev, struct blob_buf *b)
bst = container_of(dev, struct bridge_state, dev);
+ system_if_dump_info(dev, b);
list = blobmsg_open_array(b, "bridge-members");
list_for_each_entry(bm, &bst->members, list) {
blobmsg_add_string(b, NULL, bm->dev.dev->ifname);
diff --git a/device.c b/device.c
index 784905b..7253bb9 100644
--- a/device.c
+++ b/device.c
@@ -672,6 +672,8 @@ device_dump_status(struct blob_buf *b, struct device *dev)
blobmsg_add_u8(b, "up", !!dev->active);
if (dev->type->dump_info)
dev->type->dump_info(dev, b);
+ else
+ system_if_dump_info(dev, b);
s = blobmsg_open_table(b, "statistics");
if (dev->type->dump_stats)
diff --git a/system-dummy.c b/system-dummy.c
index 09d1806..f2e3aed 100644
--- a/system-dummy.c
+++ b/system-dummy.c
@@ -88,7 +88,15 @@ system_if_get_parent(struct device *dev)
return NULL;
}
-int system_if_dump_stats(struct device *dev, struct blob_buf *b)
+int
+system_if_dump_info(struct device *dev, struct blob_buf *b)
+{
+ blobmsg_add_u8(b, "link", dev->present);
+ return 0;
+}
+
+int
+system_if_dump_stats(struct device *dev, struct blob_buf *b)
{
return 0;
}
diff --git a/system-linux.c b/system-linux.c
index 4a3de8c..f2ee10a 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -639,7 +639,51 @@ system_if_get_parent(struct device *dev)
return device_get(devname, true);
}
-int system_if_dump_stats(struct device *dev, struct blob_buf *b)
+static bool
+read_int_file(int dir_fd, const char *file, int *val)
+{
+ char buf[64];
+ int len, fd;
+ bool ret = false;
+
+ fd = openat(dir_fd, file, O_RDONLY);
+ if (fd < 0)
+ return false;
+
+retry:
+ len = read(fd, buf, sizeof(buf));
+ if (len < 0) {
+ if (errno == EINTR)
+ goto retry;
+ } else if (len > 0) {
+ buf[len] = 0;
+ *val = strtoul(buf, NULL, 0);
+ ret = true;
+ }
+
+ close(fd);
+
+ return ret;
+}
+
+int
+system_if_dump_info(struct device *dev, struct blob_buf *b)
+{
+ char buf[64];
+ int dir_fd, val = 0;
+
+ snprintf(buf, sizeof(buf), "/sys/class/net/%s", dev->ifname);
+ dir_fd = open(buf, O_DIRECTORY);
+
+ if (read_int_file(dir_fd, "carrier", &val))
+ blobmsg_add_u8(b, "link", !!val);
+
+ close(dir_fd);
+ return 0;
+}
+
+int
+system_if_dump_stats(struct device *dev, struct blob_buf *b)
{
const char *const counters[] = {
"collisions", "rx_frame_errors", "tx_compressed",
@@ -653,30 +697,16 @@ int system_if_dump_stats(struct device *dev, struct blob_buf *b)
};
char buf[64];
int stats_dir;
- int i, fd, len;
+ int i, val = 0;
snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics", dev->ifname);
stats_dir = open(buf, O_DIRECTORY);
if (stats_dir < 0)
return -1;
- for (i = 0; i < ARRAY_SIZE(counters); i++) {
- fd = openat(stats_dir, counters[i], O_RDONLY);
- if (fd < 0)
- continue;
-
-retry:
- len = read(fd, buf, sizeof(buf));
- if (len < 0) {
- if (errno == EINTR)
- goto retry;
- continue;
- }
-
- buf[len] = 0;
- blobmsg_add_u32(b, counters[i], strtoul(buf, NULL, 0));
- close(fd);
- }
+ for (i = 0; i < ARRAY_SIZE(counters); i++)
+ if (read_int_file(stats_dir, counters[i], &val))
+ blobmsg_add_u32(b, counters[i], val);
close(stats_dir);
return 0;
diff --git a/system.h b/system.h
index 639dbc8..6de6b08 100644
--- a/system.h
+++ b/system.h
@@ -38,6 +38,7 @@ void system_if_clear_state(struct device *dev);
int system_if_up(struct device *dev);
int system_if_down(struct device *dev);
int system_if_check(struct device *dev);
+int system_if_dump_info(struct device *dev, struct blob_buf *b);
int system_if_dump_stats(struct device *dev, struct blob_buf *b);
struct device *system_if_get_parent(struct device *dev);