]> git.proxmox.com Git - ovs.git/blob - ofproto/bundles.c
Documentation: Add note about dpdkvhostuser and IOMMU.
[ovs.git] / ofproto / bundles.c
1 /*
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.
5 *
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:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 */
18
19 #include <config.h>
20
21 #include "bundles.h"
22 #include "coverage.h"
23 #include "fail-open.h"
24 #include "in-band.h"
25 #include "odp-util.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"
33 #include "pinsched.h"
34 #include "openvswitch/poll-loop.h"
35 #include "openvswitch/rconn.h"
36 #include "openvswitch/shash.h"
37 #include "simap.h"
38 #include "stream.h"
39 #include "timeval.h"
40
41 VLOG_DEFINE_THIS_MODULE(bundles);
42
43 static struct ofp_bundle *
44 ofp_bundle_create(uint32_t id, uint16_t flags, const struct ofp_header *oh)
45 {
46 struct ofp_bundle *bundle;
47
48 bundle = xmalloc(sizeof(*bundle));
49
50 bundle->used = time_msec();
51 bundle->id = id;
52 bundle->flags = flags;
53 bundle->state = BS_OPEN;
54 bundle->msg = xmemdup(oh, ntohs(oh->length));
55
56 ovs_list_init(&bundle->msg_list);
57
58 return bundle;
59 }
60
61 void
62 ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle)
63 {
64 struct ofp_bundle_entry *msg;
65
66 LIST_FOR_EACH_POP (msg, node, &bundle->msg_list) {
67 ofp_bundle_entry_free(msg);
68 }
69
70 ofconn_remove_bundle(ofconn, bundle);
71 free(bundle->msg);
72 free(bundle);
73 }
74
75 enum ofperr
76 ofp_bundle_open(struct ofconn *ofconn, uint32_t id, uint16_t flags,
77 const struct ofp_header *oh)
78 {
79 struct ofp_bundle *bundle;
80
81 bundle = ofconn_get_bundle(ofconn, id);
82
83 if (bundle) {
84 VLOG_INFO("Bundle %x already exists.", id);
85 ofp_bundle_remove__(ofconn, bundle);
86
87 return OFPERR_OFPBFC_BAD_ID;
88 }
89
90 bundle = ofp_bundle_create(id, flags, oh);
91 ofconn_insert_bundle(ofconn, bundle);
92
93 return 0;
94 }
95
96 enum ofperr
97 ofp_bundle_close(struct ofconn *ofconn, uint32_t id, uint16_t flags)
98 {
99 struct ofp_bundle *bundle;
100
101 bundle = ofconn_get_bundle(ofconn, id);
102
103 if (!bundle) {
104 return OFPERR_OFPBFC_BAD_ID;
105 }
106
107 if (bundle->state == BS_CLOSED) {
108 ofp_bundle_remove__(ofconn, bundle);
109 return OFPERR_OFPBFC_BUNDLE_CLOSED;
110 }
111
112 if (bundle->flags != flags) {
113 ofp_bundle_remove__(ofconn, bundle);
114 return OFPERR_OFPBFC_BAD_FLAGS;
115 }
116
117 bundle->used = time_msec();
118 bundle->state = BS_CLOSED;
119 return 0;
120 }
121
122 enum ofperr
123 ofp_bundle_discard(struct ofconn *ofconn, uint32_t id)
124 {
125 struct ofp_bundle *bundle;
126
127 bundle = ofconn_get_bundle(ofconn, id);
128
129 if (!bundle) {
130 return OFPERR_OFPBFC_BAD_ID;
131 }
132
133 ofp_bundle_remove__(ofconn, bundle);
134 return 0;
135 }
136
137 enum ofperr
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)
141 {
142 struct ofp_bundle *bundle;
143
144 bundle = ofconn_get_bundle(ofconn, id);
145
146 if (!bundle) {
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;
155 }
156
157 bundle->used = time_msec();
158 ovs_list_push_back(&bundle->msg_list, &bmsg->node);
159 return 0;
160 }