]> git.proxmox.com Git - mirror_ovs.git/blame - ofproto/bundles.c
cirrus: Use FreeBSD 12.2.
[mirror_ovs.git] / ofproto / bundles.c
CommitLineData
777af88d
AC
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>
51bb26fa 4 * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
777af88d
AC
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
b598f214 21#include "bundles.h"
777af88d
AC
22#include "coverage.h"
23#include "fail-open.h"
24#include "in-band.h"
25#include "odp-util.h"
d271907f 26#include "ofproto-provider.h"
b598f214 27#include "openvswitch/ofp-actions.h"
d271907f 28#include "openvswitch/ofp-msgs.h"
64c96779 29#include "openvswitch/ofpbuf.h"
d271907f
BW
30#include "openvswitch/vconn.h"
31#include "openvswitch/vlog.h"
777af88d 32#include "pinsched.h"
fd016ae3 33#include "openvswitch/poll-loop.h"
dc02e1eb 34#include "openvswitch/rconn.h"
ee89ea7b 35#include "openvswitch/shash.h"
777af88d
AC
36#include "simap.h"
37#include "stream.h"
38#include "timeval.h"
777af88d 39
777af88d
AC
40VLOG_DEFINE_THIS_MODULE(bundles);
41
777af88d 42static struct ofp_bundle *
51bb26fa 43ofp_bundle_create(uint32_t id, uint16_t flags, const struct ofp_header *oh)
777af88d
AC
44{
45 struct ofp_bundle *bundle;
46
47 bundle = xmalloc(sizeof(*bundle));
48
51bb26fa 49 bundle->used = time_msec();
777af88d
AC
50 bundle->id = id;
51 bundle->flags = flags;
ff09bc08 52 bundle->state = BS_OPEN;
52c57cbb 53 bundle->msg = xmemdup(oh, ntohs(oh->length));
777af88d 54
417e7e66 55 ovs_list_init(&bundle->msg_list);
777af88d
AC
56
57 return bundle;
58}
59
ff09bc08 60void
0c78eebe 61ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle)
777af88d 62{
7ac27a04 63 struct ofp_bundle_entry *msg;
777af88d 64
7ac27a04
JR
65 LIST_FOR_EACH_POP (msg, node, &bundle->msg_list) {
66 ofp_bundle_entry_free(msg);
777af88d
AC
67 }
68
ff09bc08 69 ofconn_remove_bundle(ofconn, bundle);
52c57cbb 70 free(bundle->msg);
7ac27a04 71 free(bundle);
777af88d
AC
72}
73
777af88d 74enum ofperr
51bb26fa
JR
75ofp_bundle_open(struct ofconn *ofconn, uint32_t id, uint16_t flags,
76 const struct ofp_header *oh)
777af88d 77{
777af88d
AC
78 struct ofp_bundle *bundle;
79
ff09bc08 80 bundle = ofconn_get_bundle(ofconn, id);
777af88d
AC
81
82 if (bundle) {
83 VLOG_INFO("Bundle %x already exists.", id);
0c78eebe 84 ofp_bundle_remove__(ofconn, bundle);
777af88d
AC
85
86 return OFPERR_OFPBFC_BAD_ID;
87 }
88
51bb26fa 89 bundle = ofp_bundle_create(id, flags, oh);
52c57cbb 90 ofconn_insert_bundle(ofconn, bundle);
777af88d 91
52c57cbb 92 return 0;
777af88d
AC
93}
94
95enum ofperr
96ofp_bundle_close(struct ofconn *ofconn, uint32_t id, uint16_t flags)
97{
777af88d
AC
98 struct ofp_bundle *bundle;
99
ff09bc08 100 bundle = ofconn_get_bundle(ofconn, id);
777af88d
AC
101
102 if (!bundle) {
103 return OFPERR_OFPBFC_BAD_ID;
104 }
105
106 if (bundle->state == BS_CLOSED) {
0c78eebe 107 ofp_bundle_remove__(ofconn, bundle);
777af88d
AC
108 return OFPERR_OFPBFC_BUNDLE_CLOSED;
109 }
110
111 if (bundle->flags != flags) {
0c78eebe 112 ofp_bundle_remove__(ofconn, bundle);
777af88d
AC
113 return OFPERR_OFPBFC_BAD_FLAGS;
114 }
115
51bb26fa 116 bundle->used = time_msec();
777af88d
AC
117 bundle->state = BS_CLOSED;
118 return 0;
119}
120
777af88d
AC
121enum ofperr
122ofp_bundle_discard(struct ofconn *ofconn, uint32_t id)
123{
777af88d
AC
124 struct ofp_bundle *bundle;
125
ff09bc08 126 bundle = ofconn_get_bundle(ofconn, id);
777af88d
AC
127
128 if (!bundle) {
129 return OFPERR_OFPBFC_BAD_ID;
130 }
131
0c78eebe 132 ofp_bundle_remove__(ofconn, bundle);
777af88d
AC
133 return 0;
134}
135
136enum ofperr
7ac27a04 137ofp_bundle_add_message(struct ofconn *ofconn, uint32_t id, uint16_t flags,
51bb26fa
JR
138 struct ofp_bundle_entry *bmsg,
139 const struct ofp_header *oh)
777af88d 140{
777af88d 141 struct ofp_bundle *bundle;
777af88d 142
ff09bc08 143 bundle = ofconn_get_bundle(ofconn, id);
777af88d
AC
144
145 if (!bundle) {
51bb26fa 146 bundle = ofp_bundle_create(id, flags, oh);
52c57cbb 147 ofconn_insert_bundle(ofconn, bundle);
7b334c5c 148 } else if (bundle->state == BS_CLOSED) {
0c78eebe 149 ofp_bundle_remove__(ofconn, bundle);
777af88d 150 return OFPERR_OFPBFC_BUNDLE_CLOSED;
7ac27a04 151 } else if (flags != bundle->flags) {
0c78eebe 152 ofp_bundle_remove__(ofconn, bundle);
7b334c5c 153 return OFPERR_OFPBFC_BAD_FLAGS;
777af88d
AC
154 }
155
51bb26fa 156 bundle->used = time_msec();
417e7e66 157 ovs_list_push_back(&bundle->msg_list, &bmsg->node);
777af88d
AC
158 return 0;
159}