2 * Copyright (c) 2013, 2014 Alexandru Copot <alex.mihai.c@gmail.com>, with support from IXIA.
3 * Copyright (c) 2013, 2014 Daniel Baluta <dbaluta@ixiacom.com>
4 * Copyright (c) 2014, 2015 Nicira, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include "fail-open.h"
26 #include "ofproto-provider.h"
27 #include "openvswitch/ofp-actions.h"
28 #include "openvswitch/ofp-msgs.h"
29 #include "openvswitch/ofp-util.h"
30 #include "openvswitch/ofpbuf.h"
31 #include "openvswitch/vconn.h"
32 #include "openvswitch/vlog.h"
34 #include "poll-loop.h"
42 VLOG_DEFINE_THIS_MODULE(bundles);
44 static struct ofp_bundle *
45 ofp_bundle_create(uint32_t id, uint16_t flags)
47 struct ofp_bundle *bundle;
49 bundle = xmalloc(sizeof(*bundle));
52 bundle->flags = flags;
53 bundle->state = BS_OPEN;
55 ovs_list_init(&bundle->msg_list);
61 ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle,
64 struct ofp_bundle_entry *msg;
66 LIST_FOR_EACH_POP (msg, node, &bundle->msg_list) {
67 if (success && msg->type == OFPTYPE_FLOW_MOD) {
68 /* Tell connmgr about successful flow mods. */
69 ofconn_report_flow_mod(ofconn, msg->ofm.fm.command);
71 ofp_bundle_entry_free(msg);
74 ofconn_remove_bundle(ofconn, bundle);
79 ofp_bundle_open(struct ofconn *ofconn, uint32_t id, uint16_t flags)
81 struct ofp_bundle *bundle;
84 bundle = ofconn_get_bundle(ofconn, id);
87 VLOG_INFO("Bundle %x already exists.", id);
88 ofp_bundle_remove__(ofconn, bundle, false);
90 return OFPERR_OFPBFC_BAD_ID;
93 bundle = ofp_bundle_create(id, flags);
94 error = ofconn_insert_bundle(ofconn, bundle);
103 ofp_bundle_close(struct ofconn *ofconn, uint32_t id, uint16_t flags)
105 struct ofp_bundle *bundle;
107 bundle = ofconn_get_bundle(ofconn, id);
110 return OFPERR_OFPBFC_BAD_ID;
113 if (bundle->state == BS_CLOSED) {
114 ofp_bundle_remove__(ofconn, bundle, false);
115 return OFPERR_OFPBFC_BUNDLE_CLOSED;
118 if (bundle->flags != flags) {
119 ofp_bundle_remove__(ofconn, bundle, false);
120 return OFPERR_OFPBFC_BAD_FLAGS;
123 bundle->state = BS_CLOSED;
128 ofp_bundle_discard(struct ofconn *ofconn, uint32_t id)
130 struct ofp_bundle *bundle;
132 bundle = ofconn_get_bundle(ofconn, id);
135 return OFPERR_OFPBFC_BAD_ID;
138 ofp_bundle_remove__(ofconn, bundle, false);
144 ofp_bundle_add_message(struct ofconn *ofconn, uint32_t id, uint16_t flags,
145 struct ofp_bundle_entry *bmsg)
147 struct ofp_bundle *bundle;
149 bundle = ofconn_get_bundle(ofconn, id);
154 bundle = ofp_bundle_create(id, flags);
155 error = ofconn_insert_bundle(ofconn, bundle);
160 } else if (bundle->state == BS_CLOSED) {
161 ofp_bundle_remove__(ofconn, bundle, false);
162 return OFPERR_OFPBFC_BUNDLE_CLOSED;
163 } else if (flags != bundle->flags) {
164 ofp_bundle_remove__(ofconn, bundle, false);
165 return OFPERR_OFPBFC_BAD_FLAGS;
168 ovs_list_push_back(&bundle->msg_list, &bmsg->node);