From 76fb6ae4a7895977e35a78433a0f1f695e097cd5 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 16 Jul 2014 13:28:40 -0700 Subject: [PATCH] learning-switch: Make test-controller work with OpenFlow 1.3+. The controller setup in my personal test environment has been broken for a while. I figured that it wasn't anything important, though, because no one else had reported similar problems. Anyway, it turns out that enabling OpenFlow 1.3 by default broke test-controller because OpenFlow 1.3 doesn't send table misses to the controller by default. This commit fixes the problem. Signed-off-by: Ben Pfaff Acked-by: Alex Wang --- lib/learning-switch.c | 44 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/learning-switch.c b/lib/learning-switch.c index ca579116f..e3b48d56c 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2008, 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. @@ -173,10 +173,50 @@ static void lswitch_handshake(struct lswitch *sw) { enum ofputil_protocol protocol; + enum ofp_version version; send_features_request(sw); - protocol = ofputil_protocol_from_ofp_version(rconn_get_version(sw->rconn)); + version = rconn_get_version(sw->rconn); + protocol = ofputil_protocol_from_ofp_version(version); + if (version >= OFP13_VERSION) { + /* OpenFlow 1.3 and later by default drop packets that miss in the flow + * table. Set up a flow to send packets to the controller by + * default. */ + struct ofputil_flow_mod fm; + struct ofpact_output output; + struct ofpbuf *msg; + int error; + + ofpact_init_OUTPUT(&output); + output.port = OFPP_CONTROLLER; + output.max_len = OFP_DEFAULT_MISS_SEND_LEN; + + match_init_catchall(&fm.match); + fm.priority = 0; + fm.cookie = 0; + fm.cookie_mask = 0; + fm.new_cookie = 0; + fm.modify_cookie = false; + fm.table_id = 0; + fm.command = OFPFC_ADD; + fm.idle_timeout = 0; + fm.hard_timeout = 0; + fm.buffer_id = UINT32_MAX; + fm.out_port = OFPP_NONE; + fm.out_group = OFPG_ANY; + fm.flags = 0; + fm.ofpacts = &output.ofpact; + fm.ofpacts_len = sizeof output; + fm.delete_reason = 0; + + msg = ofputil_encode_flow_mod(&fm, protocol); + error = rconn_send(sw->rconn, msg, NULL); + if (error) { + VLOG_INFO_RL(&rl, "%s: failed to add default flow (%s)", + rconn_get_name(sw->rconn), ovs_strerror(error)); + } + } if (sw->default_flows) { struct ofpbuf *msg = NULL; int error = 0; -- 2.20.1