bridge: make hotplug-added vlans default to tagged
[project/netifd.git] / bridge.c
index 8a5b7588a49b11b3979b01234a9604fa3811adb6..fb1f196ad3c892ddb7d22b80396017b417ca2895 100644 (file)
--- a/bridge.c
+++ b/bridge.c
@@ -206,7 +206,7 @@ __bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan,
        if (bm->pvid == vlan->vid)
                flags |= BRVLAN_F_PVID;
 
-       system_bridge_vlan(port->ifname, vlan->vid, add, flags);
+       system_bridge_vlan(port->ifname, vlan->vid, -1, add, flags);
 }
 
 static void
@@ -233,7 +233,7 @@ bridge_set_local_vlan(struct bridge_state *bst, struct bridge_vlan *vlan, bool a
        if (!vlan->local && add)
                return;
 
-       system_bridge_vlan(bst->dev.ifname, vlan->vid, add, BRVLAN_F_SELF);
+       system_bridge_vlan(bst->dev.ifname, vlan->vid, -1, add, BRVLAN_F_SELF);
 }
 
 static void
@@ -361,7 +361,7 @@ bridge_enable_interface(struct bridge_state *bst)
 
        if (bst->has_vlans) {
                /* delete default VLAN 1 */
-               system_bridge_vlan(bst->dev.ifname, 1, false, BRVLAN_F_SELF);
+               system_bridge_vlan(bst->dev.ifname, 1, -1, false, BRVLAN_F_SELF);
 
                bridge_set_local_vlans(bst, true);
        }
@@ -394,6 +394,17 @@ bridge_disable_interface(struct bridge_state *bst)
        bst->active = false;
 }
 
+static void
+bridge_member_add_extra_vlans(struct bridge_member *bm)
+{
+       struct device *dev = bm->dev.dev;
+       int i;
+
+       for (i = 0; i < dev->n_extra_vlan; i++)
+               system_bridge_vlan(dev->ifname, dev->extra_vlan[i].start,
+                                  dev->extra_vlan[i].end, true, 0);
+}
+
 static int
 bridge_enable_member(struct bridge_member *bm)
 {
@@ -435,8 +446,9 @@ bridge_enable_member(struct bridge_member *bm)
        bm->active = true;
        if (bst->has_vlans) {
                /* delete default VLAN 1 */
-               system_bridge_vlan(bm->dev.dev->ifname, 1, false, 0);
+               system_bridge_vlan(bm->dev.dev->ifname, 1, -1, false, 0);
 
+               bridge_member_add_extra_vlans(bm);
                vlist_for_each_element(&bst->dev.vlans, vlan, node)
                        bridge_set_member_vlan(bm, vlan, true);
        }
@@ -789,7 +801,7 @@ bridge_hotplug_set_member_vlans(struct bridge_state *bst, struct blob_attr *vlan
 
        blobmsg_for_each_attr(cur, vlans, rem) {
                struct bridge_vlan_hotplug_port *port;
-               uint16_t flags = BRVLAN_F_UNTAGGED;
+               uint16_t flags = 0;
                char *name_buf;
                unsigned int vid;
                char *end;
@@ -816,8 +828,8 @@ bridge_hotplug_set_member_vlans(struct bridge_state *bst, struct blob_attr *vlan
 
                        for (end++; *end; end++) {
                                switch (*end) {
-                               case 't':
-                                       flags &= ~BRVLAN_F_UNTAGGED;
+                               case 'u':
+                                       flags |= BRVLAN_F_UNTAGGED;
                                        break;
                                case '*':
                                        flags |= BRVLAN_F_PVID;
@@ -968,12 +980,15 @@ bridge_dump_vlan(struct blob_buf *b, struct bridge_vlan *vlan)
 static void
 bridge_dump_info(struct device *dev, struct blob_buf *b)
 {
+       struct bridge_config *cfg;
        struct bridge_state *bst;
        struct bridge_member *bm;
        struct bridge_vlan *vlan;
        void *list;
+       void *c;
 
        bst = container_of(dev, struct bridge_state, dev);
+       cfg = &bst->config;
 
        system_if_dump_info(dev, b);
        list = blobmsg_open_array(b, "bridge-members");
@@ -987,6 +1002,29 @@ bridge_dump_info(struct device *dev, struct blob_buf *b)
 
        blobmsg_close_array(b, list);
 
+       c = blobmsg_open_table(b, "bridge-attributes");
+
+       blobmsg_add_u8(b, "stp", cfg->stp);
+       blobmsg_add_u32(b, "forward_delay", cfg->forward_delay);
+       blobmsg_add_u32(b, "priority", cfg->priority);
+       blobmsg_add_u32(b, "ageing_time", cfg->ageing_time);
+       blobmsg_add_u32(b, "hello_time", cfg->hello_time);
+       blobmsg_add_u32(b, "max_age", cfg->max_age);
+       blobmsg_add_u8(b, "igmp_snooping", cfg->igmp_snoop);
+       blobmsg_add_u8(b, "bridge_empty", cfg->bridge_empty);
+       blobmsg_add_u8(b, "multicast_querier", cfg->multicast_querier);
+       blobmsg_add_u32(b, "hash_max", cfg->hash_max);
+       blobmsg_add_u32(b, "robustness", cfg->robustness);
+       blobmsg_add_u32(b, "query_interval", cfg->query_interval);
+       blobmsg_add_u32(b, "query_response_interval", cfg->query_response_interval);
+       blobmsg_add_u32(b, "last_member_interval", cfg->last_member_interval);
+       blobmsg_add_u8(b, "vlan_filtering", cfg->vlan_filtering);
+       blobmsg_add_u8(b, "stp_kernel", cfg->stp_kernel);
+       if (cfg->stp_proto)
+               blobmsg_add_string(b, "stp_proto", cfg->stp_proto);
+
+       blobmsg_close_table(b, c);
+
        if (avl_is_empty(&dev->vlans.avl))
                return;