/*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/* Add all the remotes. */
HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
- struct sockaddr_in *sin = &addrs[n_addrs];
const char *target = rconn_get_target(ofconn->rconn);
+ struct sockaddr_storage ss;
- if (ofconn->band == OFPROTO_OUT_OF_BAND) {
- continue;
- }
-
- if (stream_parse_target_with_default_port(target,
- OFP_OLD_PORT,
- sin)) {
- n_addrs++;
+ if (ofconn->band == OFPROTO_IN_BAND
+ && stream_parse_target_with_default_port(target, OFP_OLD_PORT, &ss)
+ && ss.ss_family == AF_INET) {
+ addrs[n_addrs++] = *(struct sockaddr_in *) &ss;
}
}
for (i = 0; i < mgr->n_extra_remotes; i++) {
enum ofp_packet_in_reason wire_reason);
/* Sends an OFPT_PORT_STATUS message with 'opp' and 'reason' to appropriate
- * controllers managed by 'mgr'. */
+ * controllers managed by 'mgr'. For messages caused by a controller
+ * OFPT_PORT_MOD, specify 'source' as the controller connection that sent the
+ * request; otherwise, specify 'source' as NULL. */
void
-connmgr_send_port_status(struct connmgr *mgr,
+connmgr_send_port_status(struct connmgr *mgr, struct ofconn *source,
const struct ofputil_phy_port *pp, uint8_t reason)
{
/* XXX Should limit the number of queued port status change messages. */
if (ofconn_receives_async_msg(ofconn, OAM_PORT_STATUS, reason)) {
struct ofpbuf *msg;
+ /* Before 1.5, OpenFlow specified that OFPT_PORT_MOD should not
+ * generate OFPT_PORT_STATUS messages. That requirement was a
+ * relic of how OpenFlow originally supported a single controller,
+ * so that one could expect the controller to already know the
+ * changes it had made.
+ *
+ * EXT-338 changes OpenFlow 1.5 OFPT_PORT_MOD to send
+ * OFPT_PORT_STATUS messages to every controller. This is
+ * obviously more useful in the multi-controller case. We could
+ * always implement it that way in OVS, but that would risk
+ * confusing controllers that are intended for single-controller
+ * use only. (Imagine a controller that generates an OFPT_PORT_MOD
+ * in response to any OFPT_PORT_STATUS!)
+ *
+ * So this compromises: for OpenFlow 1.4 and earlier, it generates
+ * OFPT_PORT_STATUS for OFPT_PORT_MOD, but not back to the
+ * originating controller. In a single-controller environment, in
+ * particular, this means that it will never generate
+ * OFPT_PORT_STATUS for OFPT_PORT_MOD at all. */
+ if (ofconn == source
+ && rconn_get_version(ofconn->rconn) < OFP15_VERSION) {
+ continue;
+ }
+
msg = ofputil_encode_port_status(&ps, ofconn_get_protocol(ofconn));
ofconn_send(ofconn, msg, NULL);
}