diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_netlink.c | 6 | ||||
-rw-r--r-- | net/bridge/br_private.h | 1 | ||||
-rw-r--r-- | net/bridge/br_stp_bpdu.c | 7 | ||||
-rw-r--r-- | net/bridge/br_sysfs_if.c | 2 |
4 files changed, 15 insertions, 1 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 0188a2f706c4..c331e28c7880 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -26,6 +26,7 @@ static inline size_t br_port_info_size(void) | |||
26 | + nla_total_size(2) /* IFLA_BRPORT_PRIORITY */ | 26 | + nla_total_size(2) /* IFLA_BRPORT_PRIORITY */ |
27 | + nla_total_size(4) /* IFLA_BRPORT_COST */ | 27 | + nla_total_size(4) /* IFLA_BRPORT_COST */ |
28 | + nla_total_size(1) /* IFLA_BRPORT_MODE */ | 28 | + nla_total_size(1) /* IFLA_BRPORT_MODE */ |
29 | + nla_total_size(1) /* IFLA_BRPORT_GUARD */ | ||
29 | + 0; | 30 | + 0; |
30 | } | 31 | } |
31 | 32 | ||
@@ -49,7 +50,8 @@ static int br_port_fill_attrs(struct sk_buff *skb, | |||
49 | if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) || | 50 | if (nla_put_u8(skb, IFLA_BRPORT_STATE, p->state) || |
50 | nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) || | 51 | nla_put_u16(skb, IFLA_BRPORT_PRIORITY, p->priority) || |
51 | nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) || | 52 | nla_put_u32(skb, IFLA_BRPORT_COST, p->path_cost) || |
52 | nla_put_u8(skb, IFLA_BRPORT_MODE, mode)) | 53 | nla_put_u8(skb, IFLA_BRPORT_MODE, mode) || |
54 | nla_put_u8(skb, IFLA_BRPORT_GUARD, !!(p->flags & BR_BPDU_GUARD))) | ||
53 | return -EMSGSIZE; | 55 | return -EMSGSIZE; |
54 | 56 | ||
55 | return 0; | 57 | return 0; |
@@ -162,6 +164,7 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = { | |||
162 | [IFLA_BRPORT_COST] = { .type = NLA_U32 }, | 164 | [IFLA_BRPORT_COST] = { .type = NLA_U32 }, |
163 | [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, | 165 | [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, |
164 | [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, | 166 | [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, |
167 | [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, | ||
165 | }; | 168 | }; |
166 | 169 | ||
167 | /* Change the state of the port and notify spanning tree */ | 170 | /* Change the state of the port and notify spanning tree */ |
@@ -203,6 +206,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[]) | |||
203 | int err; | 206 | int err; |
204 | 207 | ||
205 | br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE); | 208 | br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE); |
209 | br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD); | ||
206 | 210 | ||
207 | if (tb[IFLA_BRPORT_COST]) { | 211 | if (tb[IFLA_BRPORT_COST]) { |
208 | err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST])); | 212 | err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST])); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 22111ffd68df..c92b0804ff2d 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -135,6 +135,7 @@ struct net_bridge_port | |||
135 | 135 | ||
136 | unsigned long flags; | 136 | unsigned long flags; |
137 | #define BR_HAIRPIN_MODE 0x00000001 | 137 | #define BR_HAIRPIN_MODE 0x00000001 |
138 | #define BR_BPDU_GUARD 0x00000002 | ||
138 | 139 | ||
139 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 140 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
140 | u32 multicast_startup_queries_sent; | 141 | u32 multicast_startup_queries_sent; |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index fd30a6022dea..7f884e3fb955 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -170,6 +170,13 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
170 | if (!ether_addr_equal(dest, br->group_addr)) | 170 | if (!ether_addr_equal(dest, br->group_addr)) |
171 | goto out; | 171 | goto out; |
172 | 172 | ||
173 | if (p->flags & BR_BPDU_GUARD) { | ||
174 | br_notice(br, "BPDU received on blocked port %u(%s)\n", | ||
175 | (unsigned int) p->port_no, p->dev->name); | ||
176 | br_stp_disable_port(p); | ||
177 | goto out; | ||
178 | } | ||
179 | |||
173 | buf = skb_pull(skb, 3); | 180 | buf = skb_pull(skb, 3); |
174 | 181 | ||
175 | if (buf[0] == BPDU_TYPE_CONFIG) { | 182 | if (buf[0] == BPDU_TYPE_CONFIG) { |
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index f26173d33d8d..d1dfa4026185 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c | |||
@@ -156,6 +156,7 @@ static int store_flush(struct net_bridge_port *p, unsigned long v) | |||
156 | static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush); | 156 | static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush); |
157 | 157 | ||
158 | BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE); | 158 | BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE); |
159 | BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD); | ||
159 | 160 | ||
160 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 161 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
161 | static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) | 162 | static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) |
@@ -189,6 +190,7 @@ static const struct brport_attribute *brport_attrs[] = { | |||
189 | &brport_attr_hold_timer, | 190 | &brport_attr_hold_timer, |
190 | &brport_attr_flush, | 191 | &brport_attr_flush, |
191 | &brport_attr_hairpin_mode, | 192 | &brport_attr_hairpin_mode, |
193 | &brport_attr_bpdu_guard, | ||
192 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 194 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
193 | &brport_attr_multicast_router, | 195 | &brport_attr_multicast_router, |
194 | #endif | 196 | #endif |