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, 2016 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 "openvswitch/poll-loop.h"
35 #include "openvswitch/rconn.h"
36 #include "openvswitch/shash.h"
41 VLOG_DEFINE_THIS_MODULE(bundles
);
43 static struct ofp_bundle
*
44 ofp_bundle_create(uint32_t id
, uint16_t flags
, const struct ofp_header
*oh
)
46 struct ofp_bundle
*bundle
;
48 bundle
= xmalloc(sizeof(*bundle
));
50 bundle
->used
= time_msec();
52 bundle
->flags
= flags
;
53 bundle
->state
= BS_OPEN
;
54 bundle
->msg
= xmemdup(oh
, ntohs(oh
->length
));
56 ovs_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
);
76 ofp_bundle_open(struct ofconn
*ofconn
, uint32_t id
, uint16_t flags
,
77 const struct ofp_header
*oh
)
79 struct ofp_bundle
*bundle
;
81 bundle
= ofconn_get_bundle(ofconn
, id
);
84 VLOG_INFO("Bundle %x already exists.", id
);
85 ofp_bundle_remove__(ofconn
, bundle
);
87 return OFPERR_OFPBFC_BAD_ID
;
90 bundle
= ofp_bundle_create(id
, flags
, oh
);
91 ofconn_insert_bundle(ofconn
, bundle
);
97 ofp_bundle_close(struct ofconn
*ofconn
, uint32_t id
, uint16_t flags
)
99 struct ofp_bundle
*bundle
;
101 bundle
= ofconn_get_bundle(ofconn
, id
);
104 return OFPERR_OFPBFC_BAD_ID
;
107 if (bundle
->state
== BS_CLOSED
) {
108 ofp_bundle_remove__(ofconn
, bundle
);
109 return OFPERR_OFPBFC_BUNDLE_CLOSED
;
112 if (bundle
->flags
!= flags
) {
113 ofp_bundle_remove__(ofconn
, bundle
);
114 return OFPERR_OFPBFC_BAD_FLAGS
;
117 bundle
->used
= time_msec();
118 bundle
->state
= BS_CLOSED
;
123 ofp_bundle_discard(struct ofconn
*ofconn
, uint32_t id
)
125 struct ofp_bundle
*bundle
;
127 bundle
= ofconn_get_bundle(ofconn
, id
);
130 return OFPERR_OFPBFC_BAD_ID
;
133 ofp_bundle_remove__(ofconn
, bundle
);
138 ofp_bundle_add_message(struct ofconn
*ofconn
, uint32_t id
, uint16_t flags
,
139 struct ofp_bundle_entry
*bmsg
,
140 const struct ofp_header
*oh
)
142 struct ofp_bundle
*bundle
;
144 bundle
= ofconn_get_bundle(ofconn
, id
);
147 bundle
= ofp_bundle_create(id
, flags
, oh
);
148 ofconn_insert_bundle(ofconn
, bundle
);
149 } else if (bundle
->state
== BS_CLOSED
) {
150 ofp_bundle_remove__(ofconn
, bundle
);
151 return OFPERR_OFPBFC_BUNDLE_CLOSED
;
152 } else if (flags
!= bundle
->flags
) {
153 ofp_bundle_remove__(ofconn
, bundle
);
154 return OFPERR_OFPBFC_BAD_FLAGS
;
157 bundle
->used
= time_msec();
158 ovs_list_push_back(&bundle
->msg_list
, &bmsg
->node
);