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>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
21 #include "fail-open.h"
24 #include "ofp-actions.h"
28 #include "ofproto-provider.h"
30 #include "poll-loop.h"
42 VLOG_DEFINE_THIS_MODULE(bundles
);
50 struct hmap_node node
; /* In struct ofconn's "bundles" hmap. */
53 enum bundle_state state
;
55 /* List of 'struct bundle_message's */
59 struct bundle_message
{
60 struct ofp_header
*msg
;
61 struct list node
; /* Element in 'struct ofp_bundles's msg_list */
65 bundle_hash(uint32_t id
)
67 return hash_int(id
, 0);
70 static struct ofp_bundle
*
71 ofp_bundle_find(struct hmap
*bundles
, uint32_t id
)
73 struct ofp_bundle
*bundle
;
75 HMAP_FOR_EACH_IN_BUCKET(bundle
, node
, bundle_hash(id
), bundles
) {
76 if (bundle
->id
== id
) {
84 static struct ofp_bundle
*
85 ofp_bundle_create(uint32_t id
, uint16_t flags
)
87 struct ofp_bundle
*bundle
;
89 bundle
= xmalloc(sizeof(*bundle
));
92 bundle
->flags
= flags
;
94 list_init(&bundle
->msg_list
);
100 ofp_bundle_remove(struct ofconn
*ofconn
, struct ofp_bundle
*item
)
102 struct bundle_message
*msg
, *next
;
103 struct hmap
*bundles
;
105 LIST_FOR_EACH_SAFE (msg
, next
, node
, &item
->msg_list
) {
106 list_remove(&msg
->node
);
111 bundles
= ofconn_get_bundles(ofconn
);
112 hmap_remove(bundles
, &item
->node
);
118 ofp_bundle_remove_all(struct ofconn
*ofconn
)
120 struct ofp_bundle
*b
, *next
;
121 struct hmap
*bundles
;
123 bundles
= ofconn_get_bundles(ofconn
);
125 HMAP_FOR_EACH_SAFE (b
, next
, node
, bundles
) {
126 ofp_bundle_remove(ofconn
, b
);
131 ofp_bundle_open(struct ofconn
*ofconn
, uint32_t id
, uint16_t flags
)
133 struct hmap
*bundles
;
134 struct ofp_bundle
*bundle
;
136 bundles
= ofconn_get_bundles(ofconn
);
137 bundle
= ofp_bundle_find(bundles
, id
);
140 VLOG_INFO("Bundle %x already exists.", id
);
141 ofp_bundle_remove(ofconn
, bundle
);
143 return OFPERR_OFPBFC_BAD_ID
;
146 /* XXX: Check the limit of open bundles */
148 bundle
= ofp_bundle_create(id
, flags
);
149 bundle
->state
= BS_OPEN
;
151 bundles
= ofconn_get_bundles(ofconn
);
152 hmap_insert(bundles
, &bundle
->node
, bundle_hash(id
));
158 ofp_bundle_close(struct ofconn
*ofconn
, uint32_t id
, uint16_t flags
)
160 struct hmap
*bundles
;
161 struct ofp_bundle
*bundle
;
163 bundles
= ofconn_get_bundles(ofconn
);
164 bundle
= ofp_bundle_find(bundles
, id
);
167 return OFPERR_OFPBFC_BAD_ID
;
170 if (bundle
->state
== BS_CLOSED
) {
171 ofp_bundle_remove(ofconn
, bundle
);
172 return OFPERR_OFPBFC_BUNDLE_CLOSED
;
175 if (bundle
->flags
!= flags
) {
176 ofp_bundle_remove(ofconn
, bundle
);
177 return OFPERR_OFPBFC_BAD_FLAGS
;
180 bundle
->state
= BS_CLOSED
;
185 ofp_bundle_commit(struct ofconn
*ofconn
, uint32_t id
, uint16_t flags
)
187 struct hmap
*bundles
;
188 struct ofp_bundle
*bundle
;
190 bundles
= ofconn_get_bundles(ofconn
);
191 bundle
= ofp_bundle_find(bundles
, id
);
194 return OFPERR_OFPBFC_BAD_ID
;
196 if (bundle
->flags
!= flags
) {
197 ofp_bundle_remove(ofconn
, bundle
);
198 return OFPERR_OFPBFC_BAD_FLAGS
;
201 /* XXX: actual commit */
203 return OFPERR_OFPBFC_MSG_UNSUP
;
207 ofp_bundle_discard(struct ofconn
*ofconn
, uint32_t id
)
209 struct hmap
*bundles
;
210 struct ofp_bundle
*bundle
;
212 bundles
= ofconn_get_bundles(ofconn
);
213 bundle
= ofp_bundle_find(bundles
, id
);
216 return OFPERR_OFPBFC_BAD_ID
;
219 ofp_bundle_remove(ofconn
, bundle
);
225 ofp_bundle_add_message(struct ofconn
*ofconn
, struct ofputil_bundle_add_msg
*badd
)
227 struct hmap
*bundles
;
228 struct ofp_bundle
*bundle
;
229 struct bundle_message
*bmsg
;
231 bundles
= ofconn_get_bundles(ofconn
);
232 bundle
= ofp_bundle_find(bundles
, badd
->bundle_id
);
235 bundle
= ofp_bundle_create(badd
->bundle_id
, badd
->flags
);
236 bundle
->state
= BS_OPEN
;
238 bundles
= ofconn_get_bundles(ofconn
);
239 hmap_insert(bundles
, &bundle
->node
, bundle_hash(badd
->bundle_id
));
242 if (bundle
->state
== BS_CLOSED
) {
243 ofp_bundle_remove(ofconn
, bundle
);
244 return OFPERR_OFPBFC_BUNDLE_CLOSED
;
247 bmsg
= xmalloc(sizeof *bmsg
);
248 bmsg
->msg
= xmemdup(badd
->msg
, ntohs(badd
->msg
->length
));
249 list_push_back(&bundle
->msg_list
, &bmsg
->node
);