bridge: show vlans in device status
authorFelix Fietkau <nbd@nbd.name>
Wed, 28 Oct 2020 17:54:39 +0000 (18:54 +0100)
committerFelix Fietkau <nbd@nbd.name>
Wed, 28 Oct 2020 17:54:44 +0000 (18:54 +0100)
List vlans with member ports, VLAN IDs and flags

Signed-off-by: Felix Fietkau <nbd@nbd.name>
bridge.c

index 92eea9f7e22e20b149057b6b55ded2869639e917..cf874083de8083afc2a765ef39551da7bb73a93d 100644 (file)
--- a/bridge.c
+++ b/bridge.c
@@ -218,7 +218,7 @@ bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan, bool
 }
 
 static void
-brigde_set_local_vlan(struct bridge_state *bst, struct bridge_vlan *vlan, bool add)
+bridge_set_local_vlan(struct bridge_state *bst, struct bridge_vlan *vlan, bool add)
 {
        if (!vlan->local && add)
                return;
@@ -232,7 +232,7 @@ bridge_set_local_vlans(struct bridge_state *bst, bool add)
        struct bridge_vlan *vlan;
 
        vlist_for_each_element(&bst->dev.vlans, vlan, node)
-               brigde_set_local_vlan(bst, vlan, add);
+               bridge_set_local_vlan(bst, vlan, add);
 }
 
 static struct bridge_vlan *
@@ -264,7 +264,7 @@ bridge_set_vlan_state(struct bridge_state *bst, struct bridge_vlan *vlan, bool a
        struct bridge_member *bm;
        struct bridge_vlan *vlan2;
 
-       brigde_set_local_vlan(bst, vlan, add);
+       bridge_set_local_vlan(bst, vlan, add);
 
        vlist_for_each_element(&bst->members, bm, node) {
                struct bridge_vlan_port *port;
@@ -754,11 +754,49 @@ bridge_free(struct device *dev)
        free(bst);
 }
 
+static void
+bridge_dump_port(struct blob_buf *b, struct bridge_vlan_port *port)
+{
+       bool tagged = !(port->flags & BRVLAN_F_UNTAGGED);
+       bool pvid = (port->flags & BRVLAN_F_PVID);
+
+       blobmsg_printf(b, "%s%s%s%s\n", port->ifname,
+               tagged || pvid ? ":" : "",
+               tagged ? "t" : "",
+               pvid ? "*" : "");
+}
+
+static void
+bridge_dump_vlan(struct blob_buf *b, struct bridge_vlan *vlan)
+{
+       struct bridge_vlan_hotplug_port *port;
+       void *c, *p;
+       int i;
+
+       c = blobmsg_open_table(b, NULL);
+
+       blobmsg_add_u32(b, "id", vlan->vid);
+       blobmsg_add_u8(b, "local", vlan->local);
+
+       p = blobmsg_open_array(b, "ports");
+
+       for (i = 0; i < vlan->n_ports; i++)
+           bridge_dump_port(b, &vlan->ports[i]);
+
+       list_for_each_entry(port, &vlan->hotplug_ports, list)
+               bridge_dump_port(b, &port->port);
+
+       blobmsg_close_array(b, p);
+
+       blobmsg_close_table(b, c);
+}
+
 static void
 bridge_dump_info(struct device *dev, struct blob_buf *b)
 {
        struct bridge_state *bst;
        struct bridge_member *bm;
+       struct bridge_vlan *vlan;
        void *list;
 
        bst = container_of(dev, struct bridge_state, dev);
@@ -774,6 +812,16 @@ bridge_dump_info(struct device *dev, struct blob_buf *b)
        }
 
        blobmsg_close_array(b, list);
+
+       if (avl_is_empty(&dev->vlans.avl))
+               return;
+
+       list = blobmsg_open_array(b, "bridge-vlans");
+
+       vlist_for_each_element(&bst->dev.vlans, vlan, node)
+               bridge_dump_vlan(b, vlan);
+
+       blobmsg_close_array(b, list);
 }
 
 static void