diff --git a/bridge.c b/bridge.c index 0c5c430..a45f633 100644 --- a/bridge.c +++ b/bridge.c @@ -43,6 +43,7 @@ enum { BRIDGE_ATTR_HAS_VLANS, BRIDGE_ATTR_STP_KERNEL, BRIDGE_ATTR_STP_PROTO, + BRIDGE_ATTR_VLAN_PROTOCOL, __BRIDGE_ATTR_MAX }; @@ -66,6 +67,7 @@ static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = { [BRIDGE_ATTR_HAS_VLANS] = { "__has_vlans", BLOBMSG_TYPE_BOOL }, /* internal */ [BRIDGE_ATTR_STP_KERNEL] = { "stp_kernel", BLOBMSG_TYPE_BOOL }, [BRIDGE_ATTR_STP_PROTO] = { "stp_proto", BLOBMSG_TYPE_STRING }, + [BRIDGE_ATTR_VLAN_PROTOCOL] = { "vlan_protocol", BLOBMSG_TYPE_INT32 }, }; static const struct uci_blob_param_info bridge_attr_info[__BRIDGE_ATTR_MAX] = { @@ -1129,6 +1131,7 @@ bridge_dump_info(struct device *dev, struct blob_buf *b) blobmsg_add_u8(b, "stp_kernel", cfg->stp_kernel); if (cfg->stp_proto) blobmsg_add_string(b, "stp_proto", cfg->stp_proto); + blobmsg_add_u32(b, "vlan_protocol", cfg->vlan_protocol); blobmsg_close_table(b, c); @@ -1260,6 +1263,12 @@ bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb) if ((cur = tb[BRIDGE_ATTR_VLAN_FILTERING])) cfg->vlan_filtering = blobmsg_get_bool(cur); + + if ((cur = tb[BRIDGE_ATTR_VLAN_PROTOCOL])) + cfg->vlan_protocol = blobmsg_get_u32(cur); + + if (cfg->vlan_protocol != VLAN_PROTO_8021AD) + cfg->vlan_protocol = VLAN_PROTO_8021Q; } static enum dev_change_type diff --git a/system-linux.c b/system-linux.c index 0160b30..bed3aed 100644 --- a/system-linux.c +++ b/system-linux.c @@ -1558,6 +1558,7 @@ int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg) } nla_put_u8(msg, IFLA_BR_VLAN_FILTERING, !!cfg->vlan_filtering); + nla_put_u16(msg, IFLA_BR_VLAN_PROTOCOL, htons(cfg->vlan_protocol)); nla_put_u16(msg, IFLA_BR_PRIORITY, cfg->priority); nla_put_u32(msg, IFLA_BR_HELLO_TIME, sec_to_jiffies(cfg->hello_time)); nla_put_u32(msg, IFLA_BR_MAX_AGE, sec_to_jiffies(cfg->max_age)); diff --git a/system.h b/system.h index e8edfb7..588a20c 100644 --- a/system.h +++ b/system.h @@ -116,6 +116,11 @@ enum bridge_opt { BRIDGE_OPT_LAST_MEMBER_INTERVAL = (1 << 4), }; +enum vlan_proto { + VLAN_PROTO_8021Q = 0x8100, + VLAN_PROTO_8021AD = 0x88A8 +}; + struct bridge_config { enum bridge_opt flags; bool stp; @@ -138,6 +143,7 @@ struct bridge_config { int max_age; int hash_max; + enum vlan_proto vlan_protocol; bool vlan_filtering; }; @@ -166,11 +172,6 @@ struct veth_config { unsigned char peer_macaddr[6]; }; -enum vlan_proto { - VLAN_PROTO_8021Q = 0x8100, - VLAN_PROTO_8021AD = 0x88A8 -}; - struct vlan_qos_mapping { struct vlist_simple_node node; /* entry in vlandev_config->{e,in}gress_qos_mapping_list */ uint32_t from;