#include "ofproto.h"
#include <errno.h>
#include <inttypes.h>
+#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdbool.h>
static void ofconn_run(struct ofconn *, struct ofproto *);
static void ofconn_wait(struct ofconn *);
static bool ofconn_receives_async_msgs(const struct ofconn *);
+static char *ofconn_make_name(const struct ofproto *, const char *target);
static void queue_tx(struct ofpbuf *msg, const struct ofconn *ofconn,
struct rconn_packet_counter *counter);
if (discovery) {
ofconn->discovery = discovery;
} else {
- rconn_connect(ofconn->rconn, c->target);
+ char *name = ofconn_make_name(ofproto, c->target);
+ rconn_connect(ofconn->rconn, c->target, name);
+ free(name);
}
hmap_insert(&ofproto->controllers, &ofconn->hmap_node,
hash_string(c->target, 0));
static const char *
ofconn_get_target(const struct ofconn *ofconn)
{
- return ofconn->discovery ? "discover" : rconn_get_name(ofconn->rconn);
+ return ofconn->discovery ? "discover" : rconn_get_target(ofconn->rconn);
}
static struct ofconn *
HMAP_FOR_EACH (ofconn, struct ofconn, hmap_node, &ofproto->controllers) {
struct sockaddr_in *sin = &addrs[n_addrs];
+ if (ofconn->band == OFPROTO_OUT_OF_BAND) {
+ continue;
+ }
+
sin->sin_addr.s_addr = rconn_get_remote_ip(ofconn->rconn);
if (sin->sin_addr.s_addr) {
sin->sin_port = rconn_get_remote_port(ofconn->rconn);
in_band_create(ofproto, ofproto->dpif, ofproto->switch_status,
&ofproto->in_band);
}
- in_band_set_remotes(ofproto->in_band, addrs, n_addrs);
+ if (ofproto->in_band) {
+ in_band_set_remotes(ofproto->in_band, addrs, n_addrs);
+ }
ofproto->next_in_band_update = time_msec() + 1000;
} else {
in_band_destroy(ofproto->in_band);
retval = pvconn_accept(p->listeners[i], OFP_VERSION, &vconn);
if (!retval) {
- ofconn_create(p, rconn_new_from_vconn("passive", vconn),
- OFCONN_TRANSIENT);
+ struct rconn *rconn;
+ char *name;
+
+ rconn = rconn_create(60, 0);
+ name = ofconn_make_name(p, vconn_get_name(vconn));
+ rconn_connect_unreliably(rconn, vconn, name);
+ free(name);
+
+ ofconn_create(p, rconn, OFCONN_TRANSIENT);
} else if (retval != EAGAIN) {
VLOG_WARN_RL(&rl, "accept failed (%s)", strerror(retval));
}
memset(&netdev_options, 0, sizeof netdev_options);
netdev_options.name = odp_port->devname;
netdev_options.ethertype = NETDEV_ETH_TYPE_NONE;
- netdev_options.may_open = true;
error = netdev_open(&netdev_options, &netdev);
if (error) {
}
if (discovery_run(ofconn->discovery, &controller_name)) {
if (controller_name) {
- rconn_connect(ofconn->rconn, controller_name);
+ char *ofconn_name = ofconn_make_name(p, controller_name);
+ rconn_connect(ofconn->rconn, controller_name, ofconn_name);
+ free(ofconn_name);
} else {
rconn_disconnect(ofconn->rconn);
}
return ofconn->miss_send_len > 0;
}
}
+
+/* Returns a human-readable name for an OpenFlow connection between 'ofproto'
+ * and 'target', suitable for use in log messages for identifying the
+ * connection.
+ *
+ * The name is dynamically allocated. The caller should free it (with free())
+ * when it is no longer needed. */
+static char *
+ofconn_make_name(const struct ofproto *ofproto, const char *target)
+{
+ return xasprintf("%s<->%s", dpif_base_name(ofproto->dpif), target);
+}
\f
/* Caller is responsible for initializing the 'cr' member of the returned
* rule. */
/* Learn source MAC (but don't try to learn from revalidation). */
if (packet != NULL) {
tag_type rev_tag = mac_learning_learn(ofproto->ml, flow->dl_src,
- 0, flow->in_port);
+ 0, flow->in_port,
+ GRAT_ARP_LOCK_NONE);
if (rev_tag) {
/* The log messages here could actually be useful in debugging,
* so keep the rate limit relatively high. */
}
/* Determine output port. */
- out_port = mac_learning_lookup_tag(ofproto->ml, flow->dl_dst, 0, tags);
+ out_port = mac_learning_lookup_tag(ofproto->ml, flow->dl_dst, 0, tags,
+ NULL);
if (out_port < 0) {
add_output_group_action(actions, DP_GROUP_FLOOD, nf_output_iface);
} else if (out_port != flow->in_port) {