This is the diff between RSTP patch v3 and v2 (the one sent on February 24th).
--- diff --git a/v1/lib/rstp.c b/v2/lib/rstp.c index 2725707..d226967 100644 --- a/v1/lib/rstp.c +++ b/v2/lib/rstp.c @@ -1076,6 +1076,20 @@ rstp_port_get_aux(struct rstp_port *p) return aux; } +/* Returns true if 'state' is one in which BPDU packets should be received + * and transmitted on a port, false otherwise. + */ + bool + rstp_should_manage_bpdu(enum rstp_state state) + { + if (state == RSTP_DISCARDING || state == RSTP_LEARNING || + state == RSTP_FORWARDING) { + return true; + } else { + return false; + } + } + /* Returns true if 'state' is one in which packets received on a port should * be forwarded, false otherwise. * @@ -1144,4 +1158,3 @@ rstp_unixctl_tcn(struct unixctl_conn *conn, int argc, out: ovs_mutex_unlock(&mutex); } --- diff --git a/v1/lib/rstp.h b/v2/lib/rstp.h index 31cee13..d3eb6a6 100644 --- a/v1/lib/rstp.h +++ b/v2/lib/rstp.h @@ -107,6 +107,7 @@ char *get_id_string_from_uint8_t(uint8_t *, int); char *rstp_state_name(enum rstp_state); bool rstp_forward_in_state(enum rstp_state); bool rstp_learn_in_state(enum rstp_state); +bool rstp_should_manage_bpdu(enum rstp_state state); char *rstp_port_role_name(enum rstp_port_role); void rstp_init(void); ---- diff --git a/v1/lib/rstp-state-machines.c b/v2/lib/rstp-state-machines.c index e8a263d..9f96f79 100644 --- a/v1/lib/rstp-state-machines.c +++ b/v2/lib/rstp-state-machines.c @@ -531,7 +531,7 @@ OVS_REQUIRES(mutex) pkt = ofpbuf_new(ETH_HEADER_LEN + LLC_HEADER_LEN + bpdu_size); pkt->l2 = eth = ofpbuf_put_zeros(pkt, sizeof *eth); llc = ofpbuf_put_zeros(pkt, sizeof *llc); - pkt->l3 = ofpbuf_put(pkt, bpdu, bpdu_size); + ofpbuf_set_l3(pkt, ofpbuf_put(pkt, bpdu, bpdu_size)); /* 802.2 header. */ memcpy(eth->eth_dst, eth_addr_rstp, ETH_ADDR_LEN); --- diff --git a/v1/ofproto/ofproto-dpif-upcall.c b/v2/ofproto/ofproto-dpif-upcall.c index 244e0f8..8a330f1 100644 --- a/v1/ofproto/ofproto-dpif-upcall.c +++ b/v2/ofproto/ofproto-dpif-upcall.c @@ -921,7 +921,7 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout, cookie.slow_path.unused = 0; cookie.slow_path.reason = xout->slow; - port = xout->slow & (SLOW_CFM | SLOW_BFD | SLOW_LACP | SLOW_STP) + port = xout->slow & (SLOW_CFM | SLOW_BFD | SLOW_LACP | SLOW_STP | SLOW_RSTP) ? ODPP_NONE : odp_in_port; pid = dpif_port_get_pid(udpif->dpif, port, 0); --- diff --git a/v1/ofproto/ofproto-dpif-xlate.c b/v2/ofproto/ofproto-dpif-xlate.c index 0a6b65b..9a0c718 100644 --- a/v1/ofproto/ofproto-dpif-xlate.c +++ b/v2/ofproto/ofproto-dpif-xlate.c @@ -739,7 +739,7 @@ xport_get_rstp_port(const struct xport *xport) : NULL; } -static enum rstp_state +static bool xport_rstp_learn_state(const struct xport *xport) { struct rstp_port *rp = xport_get_rstp_port(xport); @@ -753,6 +753,13 @@ xport_rstp_forward_state(const struct xport *xport) return rstp_forward_in_state(rp ? rstp_port_get_state(rp) : RSTP_DISABLED); } +static bool +xport_rstp_should_manage_bpdu(const struct xport *xport) +{ + struct rstp_port *rp = xport_get_rstp_port(xport); + return rstp_should_manage_bpdu(rp ? rstp_port_get_state(rp) : RSTP_DISABLED); +} + /* Returns true if RSTP should process 'flow'. Sets fields in 'wc' that * were used to make the determination.*/ static bool @@ -1770,21 +1777,23 @@ 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) { - if (eth_addr_equals(ctx->base_flow.dl_dst, eth_addr_stp)) { - if (!xport_stp_listen_state(xport)) { + } else if (check_stp && check_rstp) { + if (eth_addr_equals(ctx->base_flow.dl_dst, eth_addr_stp) && + eth_addr_equals(ctx->base_flow.dl_dst, eth_addr_rstp)) { + if (!xport_stp_listen_state(xport) && + !xport_rstp_should_manage_bpdu(xport)) { xlate_report(ctx, "STP not in listening state, " + "RSTP does not manage BPDU in this state, " "skipping bpdu output"); return; - } - } else if (!xport_stp_forward_state(xport)) { + } else if (!xport_stp_forward_state(xport) && + !xport_rstp_forward_state(xport)) { xlate_report(ctx, "STP not in forwarding state, " + "RSTP not in forwarding state, " "skipping output"); return; } - } else if (check_rstp && !xport_rstp_forward_state(xport)) { - xlate_report(ctx, "RSTP not int forwarding state, skipping output"); - return; + } } if (mbridge_has_mirrors(ctx->xbridge->mbridge) && xport->xbundle) { @@ -1811,7 +1820,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, if (xport_stp_forward_state(peer)) { xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true); } else if (xport_rstp_forward_state(peer)) { - xlate_table_action(ctx, flow->in_port.ofp_port, 0, true); + xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true); } else { /* Forwarding is disabled by STP and RSTP. Let OFPP_NORMAL and * the learning action look at the packet, then drop it. */ --- diff --git a/v1/tests/automake.mk b/v2/tests/automake.mk index ac4af10..6d99f2c 100644 --- a/v1/tests/automake.mk +++ b/v2/tests/automake.mk @@ -263,7 +263,7 @@ tests_test_random_LDADD = lib/libopenvswitch.la noinst_PROGRAMS += tests/test-rstp tests_test_rstp_SOURCES = tests/test-rstp.c -tests_test_rstp_LDADD = lib/libopenvswitch.la $(SSL_LIBS) +tests_test_rstp_LDADD = lib/libopenvswitch.la noinst_PROGRAMS += tests/test-stp tests_test_stp_SOURCES = tests/test-stp.c --- diff --git a/v1/tests/test-rstp.c b/v2/tests/test-rstp.c index 664220c..e4377b5 100644 --- a/v1/tests/test-rstp.c +++ b/v2/tests/test-rstp.c @@ -76,7 +76,7 @@ send_bpdu(struct ofpbuf *pkt, int port_no, void *b_) assert(port_no < b->n_ports); lan = b->ports[port_no]; if (lan) { - const void *data = pkt->l3; + const void *data = ofpbuf_get_l3(pkt); size_t size = (char *) ofpbuf_tail(pkt) - (char *) data; int i; @@ -658,4 +658,3 @@ main(int argc, char *argv[]) free(tc); return 0; } --- _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev