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.
22 #include "fail-open.h"
25 #include "ofp-actions.h"
29 #include "ofproto-provider.h"
31 #include "poll-loop.h"
38 #include "openvswitch/vconn.h"
39 #include "openvswitch/vlog.h"
43 VLOG_DEFINE_THIS_MODULE(bundles);
45 static struct ofp_bundle *
46 ofp_bundle_create(uint32_t id, uint16_t flags)
48 struct ofp_bundle *bundle;
50 bundle = xmalloc(sizeof(*bundle));
53 bundle->flags = flags;
54 bundle->state = BS_OPEN;
56 list_init(&bundle->msg_list);
62 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 ofp_bundle_entry_free(msg);
70 ofconn_remove_bundle(ofconn, bundle);
75 ofp_bundle_open(struct ofconn *ofconn, uint32_t id, uint16_t flags)
77 struct ofp_bundle *bundle;
80 bundle = ofconn_get_bundle(ofconn, id);
83 VLOG_INFO("Bundle %x already exists.", id);
84 ofp_bundle_remove__(ofconn, bundle);
86 return OFPERR_OFPBFC_BAD_ID;
89 bundle = ofp_bundle_create(id, flags);
90 error = ofconn_insert_bundle(ofconn, bundle);
99 ofp_bundle_close(struct ofconn *ofconn, uint32_t id, uint16_t flags)
101 struct ofp_bundle *bundle;
103 bundle = ofconn_get_bundle(ofconn, id);
106 return OFPERR_OFPBFC_BAD_ID;
109 if (bundle->state == BS_CLOSED) {
110 ofp_bundle_remove__(ofconn, bundle);
111 return OFPERR_OFPBFC_BUNDLE_CLOSED;
114 if (bundle->flags != flags) {
115 ofp_bundle_remove__(ofconn, bundle);
116 return OFPERR_OFPBFC_BAD_FLAGS;
119 bundle->state = BS_CLOSED;
124 ofp_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags)
126 struct ofp_bundle *bundle;
127 enum ofperr error = 0;
128 struct ofp_bundle_entry *msg;
130 bundle = ofconn_get_bundle(ofconn, id);
133 return OFPERR_OFPBFC_BAD_ID;
135 if (bundle->flags != flags) {
136 error = OFPERR_OFPBFC_BAD_FLAGS;
138 LIST_FOR_EACH (msg, node, &bundle->msg_list) {
139 /* XXX: actual commit */
140 error = OFPERR_OFPBFC_MSG_FAILED;
144 ofp_bundle_remove__(ofconn, bundle);
149 ofp_bundle_discard(struct ofconn *ofconn, uint32_t id)
151 struct ofp_bundle *bundle;
153 bundle = ofconn_get_bundle(ofconn, id);
156 return OFPERR_OFPBFC_BAD_ID;
159 ofp_bundle_remove__(ofconn, bundle);
165 ofp_bundle_add_message(struct ofconn *ofconn, uint32_t id, uint16_t flags,
166 struct ofp_bundle_entry *bmsg)
168 struct ofp_bundle *bundle;
170 bundle = ofconn_get_bundle(ofconn, id);
175 bundle = ofp_bundle_create(id, flags);
176 error = ofconn_insert_bundle(ofconn, bundle);
181 } else if (bundle->state == BS_CLOSED) {
182 ofp_bundle_remove__(ofconn, bundle);
183 return OFPERR_OFPBFC_BUNDLE_CLOSED;
184 } else if (flags != bundle->flags) {
185 ofp_bundle_remove__(ofconn, bundle);
186 return OFPERR_OFPBFC_BAD_FLAGS;
189 list_push_back(&bundle->msg_list, &bmsg->node);