The restriction only allows to send bpdu in forwarding state in compose_output_action__. But a port could send bpdu in listening and learning state according to comments in lib/stp.h(State of an STP port).
Signed-off-by: kmindg <kmi...@gmail.com> --- lib/stp.c | 9 +++++++++ lib/stp.h | 1 + ofproto/ofproto-dpif-xlate.c | 24 ++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/stp.c b/lib/stp.c index e4ddf3c..8ecc261 100644 --- a/lib/stp.c +++ b/lib/stp.c @@ -685,6 +685,15 @@ stp_learn_in_state(enum stp_state state) return (state & (STP_DISABLED | STP_LEARNING | STP_FORWARDING)) != 0; } +/* Returns true if 'state' is one in which rx&tx bpdu should be done on + * on a port, false otherwise. */ +bool +stp_listen_in_state(enum stp_state state) +{ + return (state & + (STP_LISTENING | STP_LEARNING | STP_FORWARDING)) != 0; +} + /* Returns the name for the given 'role' (for use in debugging and log * messages). */ const char * diff --git a/lib/stp.h b/lib/stp.h index affde18..c0175cd 100644 --- a/lib/stp.h +++ b/lib/stp.h @@ -120,6 +120,7 @@ enum stp_state { const char *stp_state_name(enum stp_state); bool stp_forward_in_state(enum stp_state); bool stp_learn_in_state(enum stp_state); +bool stp_listen_in_state(enum stp_state); /* Role of an STP port. */ enum stp_role { diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index eb4931e..97c4e59 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -665,7 +665,7 @@ xport_get_stp_port(const struct xport *xport) : NULL; } -static enum stp_state +static bool xport_stp_learn_state(const struct xport *xport) { struct stp_port *sp = xport_get_stp_port(xport); @@ -679,6 +679,13 @@ xport_stp_forward_state(const struct xport *xport) return stp_forward_in_state(sp ? stp_port_get_state(sp) : STP_DISABLED); } +static bool +xport_stp_listen_state(const struct xport *xport) +{ + struct stp_port *sp = xport_get_stp_port(xport); + return stp_listen_in_state(sp ? stp_port_get_state(sp) : STP_DISABLED); +} + /* Returns true if STP should process 'flow'. Sets fields in 'wc' that * were used to make the determination.*/ static bool @@ -1693,9 +1700,18 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, } else if (xport->config & OFPUTIL_PC_NO_FWD) { xlate_report(ctx, "OFPPC_NO_FWD set, skipping output"); return; - } else if (check_stp && !xport_stp_forward_state(xport)) { - xlate_report(ctx, "STP not in forwarding state, skipping output"); - return; + } else if (check_stp) { + if (eth_addr_equals(ctx->base_flow.dl_dst, eth_addr_stp)) { + if (!xport_stp_listen_state(xport)) { + xlate_report(ctx, "STP not in listening state, " + "skipping bpdu output"); + return; + } + } else if (!xport_stp_forward_state(xport)) { + xlate_report(ctx, "STP not in forwarding state, " + "skipping output"); + return; + } } if (mbridge_has_mirrors(ctx->xbridge->mbridge) && xport->xbundle) { -- 1.9.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev