From 51ab8ae072c2202e04c81d9f83b2361e3aae1ba5 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 15 Sep 2008 14:24:57 -0700 Subject: [PATCH] Fix handling of port flags. The "port watcher" in secchan was not keeping track of updates to port flags by the controller, which caused some combinations of secchan and controller to not turn on ports when the STP state otherwise should have done so. Thanks to Justin for reporting the problem. --- secchan/secchan.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/secchan/secchan.c b/secchan/secchan.c index 0aaa7cb1..cd6b567d 100644 --- a/secchan/secchan.c +++ b/secchan/secchan.c @@ -727,6 +727,31 @@ port_watcher_local_packet_cb(struct relay *r, void *pw_) return false; } +static bool +port_watcher_remote_packet_cb(struct relay *r, void *pw_) +{ + struct port_watcher *pw = pw_; + struct buffer *msg = r->halves[HALF_REMOTE].rxbuf; + struct ofp_header *oh = msg->data; + + if (oh->type == OFPT_PORT_MOD + && msg->size >= sizeof(struct ofp_port_mod)) { + struct ofp_port_mod *opm = msg->data; + uint16_t port_no = ntohs(opm->desc.port_no); + int idx = port_no_to_pw_idx(port_no); + if (idx >= 0) { + struct ofp_phy_port *pw_opp = &pw->ports[idx]; + if (pw_opp->port_no != htons(OFPP_NONE)) { + struct ofp_phy_port old = *pw_opp; + pw_opp->flags = ((pw_opp->flags & ~opm->mask) + | (opm->desc.flags & opm->mask)); + call_pw_callbacks(pw, port_no, &old, pw_opp); + } + } + } + return false; +} + static void port_watcher_periodic_cb(void *pw_) { @@ -844,7 +869,7 @@ port_watcher_set_flags(struct port_watcher *pw, old = *p; /* Update our idea of the flags. */ - p->flags = ntohl(flags); + p->flags = htonl((ntohl(p->flags) & ~mask) | (flags & mask)); call_pw_callbacks(pw, port_no, &old, p); /* Change the flags in the datapath. */ @@ -881,7 +906,8 @@ port_watcher_create(struct rconn *local_rconn, struct rconn *remote_rconn, pw->ports[i].port_no = htons(OFPP_NONE); } port_watcher_register_callback(pw, log_port_status, NULL); - return make_hook(port_watcher_local_packet_cb, NULL, + return make_hook(port_watcher_local_packet_cb, + port_watcher_remote_packet_cb, port_watcher_periodic_cb, NULL, pw); } -- 2.30.2