Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <config.h>
18 : : #include <errno.h>
19 : : #include <stdlib.h>
20 : :
21 : : #include "bundles.h"
22 : : #include "connmgr.h"
23 : : #include "coverage.h"
24 : : #include "fail-open.h"
25 : : #include "in-band.h"
26 : : #include "odp-util.h"
27 : : #include "ofproto-provider.h"
28 : : #include "openvswitch/dynamic-string.h"
29 : : #include "openvswitch/ofp-actions.h"
30 : : #include "openvswitch/ofp-msgs.h"
31 : : #include "openvswitch/ofp-util.h"
32 : : #include "openvswitch/ofpbuf.h"
33 : : #include "openvswitch/vconn.h"
34 : : #include "openvswitch/vlog.h"
35 : : #include "pinsched.h"
36 : : #include "poll-loop.h"
37 : : #include "rconn.h"
38 : : #include "openvswitch/shash.h"
39 : : #include "simap.h"
40 : : #include "stream.h"
41 : : #include "timeval.h"
42 : : #include "util.h"
43 : :
44 : 1288 : VLOG_DEFINE_THIS_MODULE(connmgr);
45 : : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
46 : :
47 : : /* An OpenFlow connection.
48 : : *
49 : : *
50 : : * Thread-safety
51 : : * =============
52 : : *
53 : : * 'ofproto_mutex' must be held whenever an ofconn is created or destroyed or,
54 : : * more or less equivalently, whenever an ofconn is added to or removed from a
55 : : * connmgr. 'ofproto_mutex' doesn't protect the data inside the ofconn, except
56 : : * as specifically noted below. */
57 : : struct ofconn {
58 : : /* Configuration that persists from one connection to the next. */
59 : :
60 : : struct ovs_list node; /* In struct connmgr's "all_conns" list. */
61 : : struct hmap_node hmap_node; /* In struct connmgr's "controllers" map. */
62 : :
63 : : struct connmgr *connmgr; /* Connection's manager. */
64 : : struct rconn *rconn; /* OpenFlow connection. */
65 : : enum ofconn_type type; /* Type. */
66 : : enum ofproto_band band; /* In-band or out-of-band? */
67 : : bool enable_async_msgs; /* Initially enable async messages? */
68 : :
69 : : /* State that should be cleared from one connection to the next. */
70 : :
71 : : /* OpenFlow state. */
72 : : enum ofp12_controller_role role; /* Role. */
73 : : enum ofputil_protocol protocol; /* Current protocol variant. */
74 : : enum nx_packet_in_format packet_in_format; /* OFPT_PACKET_IN format. */
75 : :
76 : : /* OFPT_PACKET_IN related data. */
77 : : struct rconn_packet_counter *packet_in_counter; /* # queued on 'rconn'. */
78 : : #define N_SCHEDULERS 2
79 : : struct pinsched *schedulers[N_SCHEDULERS];
80 : : int miss_send_len; /* Bytes to send of buffered packets. */
81 : : uint16_t controller_id; /* Connection controller ID. */
82 : :
83 : : /* Number of OpenFlow messages queued on 'rconn' as replies to OpenFlow
84 : : * requests, and the maximum number before we stop reading OpenFlow
85 : : * requests. */
86 : : #define OFCONN_REPLY_MAX 100
87 : : struct rconn_packet_counter *reply_counter;
88 : :
89 : : /* Asynchronous message configuration in each possible role.
90 : : *
91 : : * A 1-bit enables sending an asynchronous message for one possible reason
92 : : * that the message might be generated, a 0-bit disables it. */
93 : : struct ofputil_async_cfg *async_cfg;
94 : :
95 : : /* Flow table operation logging. */
96 : : int n_add, n_delete, n_modify; /* Number of unreported ops of each kind. */
97 : : long long int first_op, last_op; /* Range of times for unreported ops. */
98 : : long long int next_op_report; /* Time to report ops, or LLONG_MAX. */
99 : : long long int op_backoff; /* Earliest time to report ops again. */
100 : :
101 : : /* Flow monitors (e.g. NXST_FLOW_MONITOR). */
102 : :
103 : : /* Configuration. Contains "struct ofmonitor"s. */
104 : : struct hmap monitors OVS_GUARDED_BY(ofproto_mutex);
105 : :
106 : : /* Flow control.
107 : : *
108 : : * When too many flow monitor notifications back up in the transmit buffer,
109 : : * we pause the transmission of further notifications. These members track
110 : : * the flow control state.
111 : : *
112 : : * When notifications are flowing, 'monitor_paused' is 0. When
113 : : * notifications are paused, 'monitor_paused' is the value of
114 : : * 'monitor_seqno' at the point we paused.
115 : : *
116 : : * 'monitor_counter' counts the OpenFlow messages and bytes currently in
117 : : * flight. This value growing too large triggers pausing. */
118 : : uint64_t monitor_paused OVS_GUARDED_BY(ofproto_mutex);
119 : : struct rconn_packet_counter *monitor_counter OVS_GUARDED_BY(ofproto_mutex);
120 : :
121 : : /* State of monitors for a single ongoing flow_mod.
122 : : *
123 : : * 'updates' is a list of "struct ofpbuf"s that contain
124 : : * NXST_FLOW_MONITOR_REPLY messages representing the changes made by the
125 : : * current flow_mod.
126 : : *
127 : : * When 'updates' is nonempty, 'sent_abbrev_update' is true if 'updates'
128 : : * contains an update event of type NXFME_ABBREV and false otherwise.. */
129 : : struct ovs_list updates OVS_GUARDED_BY(ofproto_mutex);
130 : : bool sent_abbrev_update OVS_GUARDED_BY(ofproto_mutex);
131 : :
132 : : /* Active bundles. Contains "struct ofp_bundle"s. */
133 : : struct hmap bundles;
134 : : };
135 : :
136 : : static struct ofconn *ofconn_create(struct connmgr *, struct rconn *,
137 : : enum ofconn_type, bool enable_async_msgs)
138 : : OVS_REQUIRES(ofproto_mutex);
139 : : static void ofconn_destroy(struct ofconn *) OVS_REQUIRES(ofproto_mutex);
140 : : static void ofconn_flush(struct ofconn *) OVS_REQUIRES(ofproto_mutex);
141 : :
142 : : static void ofconn_reconfigure(struct ofconn *,
143 : : const struct ofproto_controller *);
144 : :
145 : : static void ofconn_run(struct ofconn *,
146 : : void (*handle_openflow)(struct ofconn *,
147 : : const struct ofpbuf *ofp_msg));
148 : : static void ofconn_wait(struct ofconn *);
149 : :
150 : : static void ofconn_log_flow_mods(struct ofconn *);
151 : :
152 : : static const char *ofconn_get_target(const struct ofconn *);
153 : : static char *ofconn_make_name(const struct connmgr *, const char *target);
154 : :
155 : : static void ofconn_set_rate_limit(struct ofconn *, int rate, int burst);
156 : :
157 : : static void ofconn_send(const struct ofconn *, struct ofpbuf *,
158 : : struct rconn_packet_counter *);
159 : :
160 : : static void do_send_packet_ins(struct ofconn *, struct ovs_list *txq);
161 : :
162 : : /* A listener for incoming OpenFlow "service" connections. */
163 : : struct ofservice {
164 : : struct hmap_node node; /* In struct connmgr's "services" hmap. */
165 : : struct pvconn *pvconn; /* OpenFlow connection listener. */
166 : :
167 : : /* These are not used by ofservice directly. They are settings for
168 : : * accepted "struct ofconn"s from the pvconn. */
169 : : int probe_interval; /* Max idle time before probing, in seconds. */
170 : : int rate_limit; /* Max packet-in rate in packets per second. */
171 : : int burst_limit; /* Limit on accumulating packet credits. */
172 : : bool enable_async_msgs; /* Initially enable async messages? */
173 : : uint8_t dscp; /* DSCP Value for controller connection */
174 : : uint32_t allowed_versions; /* OpenFlow protocol versions that may
175 : : * be negotiated for a session. */
176 : : };
177 : :
178 : : static void ofservice_reconfigure(struct ofservice *,
179 : : const struct ofproto_controller *);
180 : : static int ofservice_create(struct connmgr *mgr, const char *target,
181 : : uint32_t allowed_versions, uint8_t dscp);
182 : : static void ofservice_destroy(struct connmgr *, struct ofservice *);
183 : : static struct ofservice *ofservice_lookup(struct connmgr *,
184 : : const char *target);
185 : :
186 : : /* Connection manager for an OpenFlow switch. */
187 : : struct connmgr {
188 : : struct ofproto *ofproto;
189 : : char *name;
190 : : char *local_port_name;
191 : :
192 : : /* OpenFlow connections. */
193 : : struct hmap controllers; /* All OFCONN_PRIMARY controllers. */
194 : : struct ovs_list all_conns; /* All controllers. */
195 : : uint64_t master_election_id; /* monotonically increasing sequence number
196 : : * for master election */
197 : : bool master_election_id_defined;
198 : :
199 : : /* OpenFlow listeners. */
200 : : struct hmap services; /* Contains "struct ofservice"s. */
201 : : struct pvconn **snoops;
202 : : size_t n_snoops;
203 : :
204 : : /* Fail open. */
205 : : struct fail_open *fail_open;
206 : : enum ofproto_fail_mode fail_mode;
207 : :
208 : : /* In-band control. */
209 : : struct in_band *in_band;
210 : : struct sockaddr_in *extra_in_band_remotes;
211 : : size_t n_extra_remotes;
212 : : int in_band_queue;
213 : : };
214 : :
215 : : static void update_in_band_remotes(struct connmgr *);
216 : : static void add_snooper(struct connmgr *, struct vconn *);
217 : : static void ofmonitor_run(struct connmgr *);
218 : : static void ofmonitor_wait(struct connmgr *);
219 : :
220 : : /* Creates and returns a new connection manager owned by 'ofproto'. 'name' is
221 : : * a name for the ofproto suitable for using in log messages.
222 : : * 'local_port_name' is the name of the local port (OFPP_LOCAL) within
223 : : * 'ofproto'. */
224 : : struct connmgr *
225 : 749 : connmgr_create(struct ofproto *ofproto,
226 : : const char *name, const char *local_port_name)
227 : : {
228 : : struct connmgr *mgr;
229 : :
230 : 749 : mgr = xmalloc(sizeof *mgr);
231 : 749 : mgr->ofproto = ofproto;
232 : 749 : mgr->name = xstrdup(name);
233 : 749 : mgr->local_port_name = xstrdup(local_port_name);
234 : :
235 : 749 : hmap_init(&mgr->controllers);
236 : 749 : ovs_list_init(&mgr->all_conns);
237 : 749 : mgr->master_election_id = 0;
238 : 749 : mgr->master_election_id_defined = false;
239 : :
240 : 749 : hmap_init(&mgr->services);
241 : 749 : mgr->snoops = NULL;
242 : 749 : mgr->n_snoops = 0;
243 : :
244 : 749 : mgr->fail_open = NULL;
245 : 749 : mgr->fail_mode = OFPROTO_FAIL_SECURE;
246 : :
247 : 749 : mgr->in_band = NULL;
248 : 749 : mgr->extra_in_band_remotes = NULL;
249 : 749 : mgr->n_extra_remotes = 0;
250 : 749 : mgr->in_band_queue = -1;
251 : :
252 : 749 : return mgr;
253 : : }
254 : :
255 : : /* Frees 'mgr' and all of its resources. */
256 : : void
257 : 749 : connmgr_destroy(struct connmgr *mgr)
258 : : {
259 : : struct ofservice *ofservice, *next_ofservice;
260 : : struct ofconn *ofconn, *next_ofconn;
261 : : size_t i;
262 : :
263 [ - + ]: 749 : if (!mgr) {
264 : 0 : return;
265 : : }
266 : :
267 : 749 : ovs_mutex_lock(&ofproto_mutex);
268 [ + + ][ + + ]: 779 : LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &mgr->all_conns) {
269 : 30 : ofconn_destroy(ofconn);
270 : : }
271 : 749 : ovs_mutex_unlock(&ofproto_mutex);
272 : :
273 : 749 : hmap_destroy(&mgr->controllers);
274 : :
275 [ + + ][ - + ]: 1498 : HMAP_FOR_EACH_SAFE (ofservice, next_ofservice, node, &mgr->services) {
[ + + ]
276 : 749 : ofservice_destroy(mgr, ofservice);
277 : : }
278 : 749 : hmap_destroy(&mgr->services);
279 : :
280 [ + + ]: 1498 : for (i = 0; i < mgr->n_snoops; i++) {
281 : 749 : pvconn_close(mgr->snoops[i]);
282 : : }
283 : 749 : free(mgr->snoops);
284 : :
285 : 749 : fail_open_destroy(mgr->fail_open);
286 : 749 : mgr->fail_open = NULL;
287 : :
288 : 749 : in_band_destroy(mgr->in_band);
289 : 749 : mgr->in_band = NULL;
290 : 749 : free(mgr->extra_in_band_remotes);
291 : 749 : free(mgr->name);
292 : 749 : free(mgr->local_port_name);
293 : :
294 : 749 : free(mgr);
295 : : }
296 : :
297 : : /* Does all of the periodic maintenance required by 'mgr'. Calls
298 : : * 'handle_openflow' for each message received on an OpenFlow connection,
299 : : * passing along the OpenFlow connection itself and the message that was sent.
300 : : * 'handle_openflow' must not modify or free the message. */
301 : : void
302 : 157605 : connmgr_run(struct connmgr *mgr,
303 : : void (*handle_openflow)(struct ofconn *,
304 : : const struct ofpbuf *ofp_msg))
305 : : OVS_EXCLUDED(ofproto_mutex)
306 : : {
307 : : struct ofconn *ofconn, *next_ofconn;
308 : : struct ofservice *ofservice;
309 : : size_t i;
310 : :
311 [ + + ]: 157605 : if (mgr->in_band) {
312 [ - + ]: 48 : if (!in_band_run(mgr->in_band)) {
313 : 0 : in_band_destroy(mgr->in_band);
314 : 0 : mgr->in_band = NULL;
315 : : }
316 : : }
317 : :
318 [ + + ][ + + ]: 261611 : LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &mgr->all_conns) {
319 : 104006 : ofconn_run(ofconn, handle_openflow);
320 : : }
321 : 157605 : ofmonitor_run(mgr);
322 : :
323 : : /* Fail-open maintenance. Do this after processing the ofconns since
324 : : * fail-open checks the status of the controller rconn. */
325 [ - + ]: 157605 : if (mgr->fail_open) {
326 : 0 : fail_open_run(mgr->fail_open);
327 : : }
328 : :
329 [ + + ][ - + ]: 315213 : HMAP_FOR_EACH (ofservice, node, &mgr->services) {
330 : : struct vconn *vconn;
331 : : int retval;
332 : :
333 : 157608 : retval = pvconn_accept(ofservice->pvconn, &vconn);
334 [ + + ]: 157608 : if (!retval) {
335 : : struct rconn *rconn;
336 : : char *name;
337 : :
338 : : /* Passing default value for creation of the rconn */
339 : 3419 : rconn = rconn_create(ofservice->probe_interval, 0, ofservice->dscp,
340 : : vconn_get_allowed_versions(vconn));
341 : 3419 : name = ofconn_make_name(mgr, vconn_get_name(vconn));
342 : 3419 : rconn_connect_unreliably(rconn, vconn, name);
343 : 3419 : free(name);
344 : :
345 : 3419 : ovs_mutex_lock(&ofproto_mutex);
346 : 3419 : ofconn = ofconn_create(mgr, rconn, OFCONN_SERVICE,
347 : 3419 : ofservice->enable_async_msgs);
348 : 3419 : ovs_mutex_unlock(&ofproto_mutex);
349 : :
350 : 3419 : ofconn_set_rate_limit(ofconn, ofservice->rate_limit,
351 : : ofservice->burst_limit);
352 [ - + ]: 154189 : } else if (retval != EAGAIN) {
353 [ # # ]: 0 : VLOG_WARN_RL(&rl, "accept failed (%s)", ovs_strerror(retval));
354 : : }
355 : : }
356 : :
357 [ + + ]: 315210 : for (i = 0; i < mgr->n_snoops; i++) {
358 : : struct vconn *vconn;
359 : : int retval;
360 : :
361 : 157605 : retval = pvconn_accept(mgr->snoops[i], &vconn);
362 [ - + ]: 157605 : if (!retval) {
363 : 0 : add_snooper(mgr, vconn);
364 [ - + ]: 157605 : } else if (retval != EAGAIN) {
365 [ # # ]: 0 : VLOG_WARN_RL(&rl, "accept failed (%s)", ovs_strerror(retval));
366 : : }
367 : : }
368 : 157605 : }
369 : :
370 : : /* Causes the poll loop to wake up when connmgr_run() needs to run. */
371 : : void
372 : 153645 : connmgr_wait(struct connmgr *mgr)
373 : : {
374 : : struct ofservice *ofservice;
375 : : struct ofconn *ofconn;
376 : : size_t i;
377 : :
378 [ + + ]: 256921 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
379 : 103276 : ofconn_wait(ofconn);
380 : : }
381 : 153645 : ofmonitor_wait(mgr);
382 [ + + ]: 153645 : if (mgr->in_band) {
383 : 48 : in_band_wait(mgr->in_band);
384 : : }
385 [ - + ]: 153645 : if (mgr->fail_open) {
386 : 0 : fail_open_wait(mgr->fail_open);
387 : : }
388 [ + + ][ - + ]: 307292 : HMAP_FOR_EACH (ofservice, node, &mgr->services) {
389 : 153647 : pvconn_wait(ofservice->pvconn);
390 : : }
391 [ + + ]: 307290 : for (i = 0; i < mgr->n_snoops; i++) {
392 : 153645 : pvconn_wait(mgr->snoops[i]);
393 : : }
394 : 153645 : }
395 : :
396 : : /* Adds some memory usage statistics for 'mgr' into 'usage', for use with
397 : : * memory_report(). */
398 : : void
399 : 109 : connmgr_get_memory_usage(const struct connmgr *mgr, struct simap *usage)
400 : : {
401 : : const struct ofconn *ofconn;
402 : 109 : unsigned int packets = 0;
403 : 109 : unsigned int ofconns = 0;
404 : :
405 [ + + ]: 135 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
406 : : int i;
407 : :
408 : 26 : ofconns++;
409 : :
410 : 26 : packets += rconn_count_txqlen(ofconn->rconn);
411 [ + + ]: 78 : for (i = 0; i < N_SCHEDULERS; i++) {
412 : : struct pinsched_stats stats;
413 : :
414 : 52 : pinsched_get_stats(ofconn->schedulers[i], &stats);
415 : 52 : packets += stats.n_queued;
416 : : }
417 : : }
418 : 109 : simap_increase(usage, "ofconns", ofconns);
419 : 109 : simap_increase(usage, "packets", packets);
420 : 109 : }
421 : :
422 : : /* Returns the ofproto that owns 'ofconn''s connmgr. */
423 : : struct ofproto *
424 : 36734 : ofconn_get_ofproto(const struct ofconn *ofconn)
425 : : {
426 : 36734 : return ofconn->connmgr->ofproto;
427 : : }
428 : :
429 : : /* OpenFlow configuration. */
430 : :
431 : : static void add_controller(struct connmgr *, const char *target, uint8_t dscp,
432 : : uint32_t allowed_versions)
433 : : OVS_REQUIRES(ofproto_mutex);
434 : : static struct ofconn *find_controller_by_target(struct connmgr *,
435 : : const char *target);
436 : : static void update_fail_open(struct connmgr *) OVS_EXCLUDED(ofproto_mutex);
437 : : static int set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp,
438 : : const struct sset *);
439 : :
440 : : /* Returns true if 'mgr' has any configured primary controllers.
441 : : *
442 : : * Service controllers do not count, but configured primary controllers do
443 : : * count whether or not they are currently connected. */
444 : : bool
445 : 14536 : connmgr_has_controllers(const struct connmgr *mgr)
446 : : {
447 : 14536 : return !hmap_is_empty(&mgr->controllers);
448 : : }
449 : :
450 : : /* Initializes 'info' and populates it with information about each configured
451 : : * primary controller. The keys in 'info' are the controllers' targets; the
452 : : * data values are corresponding "struct ofproto_controller_info".
453 : : *
454 : : * The caller owns 'info' and everything in it and should free it when it is no
455 : : * longer needed. */
456 : : void
457 : 901 : connmgr_get_controller_info(struct connmgr *mgr, struct shash *info)
458 : : {
459 : : const struct ofconn *ofconn;
460 : :
461 [ + + ][ - + ]: 903 : HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
462 : 2 : const struct rconn *rconn = ofconn->rconn;
463 : 2 : const char *target = rconn_get_target(rconn);
464 : :
465 [ + - ]: 2 : if (!shash_find(info, target)) {
466 : 2 : struct ofproto_controller_info *cinfo = xmalloc(sizeof *cinfo);
467 : 2 : time_t now = time_now();
468 : 2 : time_t last_connection = rconn_get_last_connection(rconn);
469 : 2 : time_t last_disconnect = rconn_get_last_disconnect(rconn);
470 : 2 : int last_error = rconn_get_last_error(rconn);
471 : : int i;
472 : :
473 : 2 : shash_add(info, target, cinfo);
474 : :
475 : 2 : cinfo->is_connected = rconn_is_connected(rconn);
476 : 2 : cinfo->role = ofconn->role;
477 : :
478 : 2 : smap_init(&cinfo->pairs);
479 [ + - ]: 2 : if (last_error) {
480 : 2 : smap_add(&cinfo->pairs, "last_error",
481 : : ovs_retval_to_string(last_error));
482 : : }
483 : :
484 : 2 : smap_add(&cinfo->pairs, "state", rconn_get_state(rconn));
485 : :
486 [ - + ]: 2 : if (last_connection != TIME_MIN) {
487 : 0 : smap_add_format(&cinfo->pairs, "sec_since_connect",
488 : 0 : "%ld", (long int) (now - last_connection));
489 : : }
490 : :
491 [ + - ]: 2 : if (last_disconnect != TIME_MIN) {
492 : 2 : smap_add_format(&cinfo->pairs, "sec_since_disconnect",
493 : 2 : "%ld", (long int) (now - last_disconnect));
494 : : }
495 : :
496 [ + + ]: 6 : for (i = 0; i < N_SCHEDULERS; i++) {
497 [ - + ]: 4 : if (ofconn->schedulers[i]) {
498 [ # # ]: 0 : const char *name = i ? "miss" : "action";
499 : : struct pinsched_stats stats;
500 : :
501 : 0 : pinsched_get_stats(ofconn->schedulers[i], &stats);
502 : 0 : smap_add_nocopy(&cinfo->pairs,
503 : : xasprintf("packet-in-%s-backlog", name),
504 : : xasprintf("%u", stats.n_queued));
505 : 0 : smap_add_nocopy(&cinfo->pairs,
506 : : xasprintf("packet-in-%s-bypassed", name),
507 : : xasprintf("%llu", stats.n_normal));
508 : 0 : smap_add_nocopy(&cinfo->pairs,
509 : : xasprintf("packet-in-%s-queued", name),
510 : : xasprintf("%llu", stats.n_limited));
511 : 0 : smap_add_nocopy(&cinfo->pairs,
512 : : xasprintf("packet-in-%s-dropped", name),
513 : : xasprintf("%llu", stats.n_queue_dropped));
514 : : }
515 : : }
516 : : }
517 : : }
518 : 901 : }
519 : :
520 : : void
521 : 1178 : connmgr_free_controller_info(struct shash *info)
522 : : {
523 : : struct shash_node *node;
524 : :
525 [ + + ][ - + ]: 1180 : SHASH_FOR_EACH (node, info) {
526 : 2 : struct ofproto_controller_info *cinfo = node->data;
527 : 2 : smap_destroy(&cinfo->pairs);
528 : 2 : free(cinfo);
529 : : }
530 : 1178 : shash_destroy(info);
531 : 1178 : }
532 : :
533 : : /* Changes 'mgr''s set of controllers to the 'n_controllers' controllers in
534 : : * 'controllers'. */
535 : : void
536 : 4700 : connmgr_set_controllers(struct connmgr *mgr,
537 : : const struct ofproto_controller *controllers,
538 : : size_t n_controllers, uint32_t allowed_versions)
539 : : OVS_EXCLUDED(ofproto_mutex)
540 : : {
541 : 4700 : bool had_controllers = connmgr_has_controllers(mgr);
542 : : struct shash new_controllers;
543 : : struct ofconn *ofconn, *next_ofconn;
544 : : struct ofservice *ofservice, *next_ofservice;
545 : : size_t i;
546 : :
547 : : /* Required to add and remove ofconns. This could probably be narrowed to
548 : : * cover a smaller amount of code, if that yielded some benefit. */
549 : 4700 : ovs_mutex_lock(&ofproto_mutex);
550 : :
551 : : /* Create newly configured controllers and services.
552 : : * Create a name to ofproto_controller mapping in 'new_controllers'. */
553 : 4700 : shash_init(&new_controllers);
554 [ + + ]: 9402 : for (i = 0; i < n_controllers; i++) {
555 : 4702 : const struct ofproto_controller *c = &controllers[i];
556 : :
557 [ + + ]: 4702 : if (!vconn_verify_name(c->target)) {
558 : 1 : bool add = false;
559 : 1 : ofconn = find_controller_by_target(mgr, c->target);
560 [ + - ]: 1 : if (!ofconn) {
561 [ + - ]: 1 : VLOG_INFO("%s: added primary controller \"%s\"",
562 : : mgr->name, c->target);
563 : 1 : add = true;
564 [ # # ]: 0 : } else if (rconn_get_allowed_versions(ofconn->rconn) !=
565 : : allowed_versions) {
566 [ # # ]: 0 : VLOG_INFO("%s: re-added primary controller \"%s\"",
567 : : mgr->name, c->target);
568 : 0 : add = true;
569 : 0 : ofconn_destroy(ofconn);
570 : : }
571 [ + - ]: 1 : if (add) {
572 : 1 : add_controller(mgr, c->target, c->dscp, allowed_versions);
573 : : }
574 [ + - ]: 4701 : } else if (!pvconn_verify_name(c->target)) {
575 : 4701 : bool add = false;
576 : 4701 : ofservice = ofservice_lookup(mgr, c->target);
577 [ + + ]: 4701 : if (!ofservice) {
578 [ + - ]: 750 : VLOG_INFO("%s: added service controller \"%s\"",
579 : : mgr->name, c->target);
580 : 750 : add = true;
581 [ - + ]: 3951 : } else if (ofservice->allowed_versions != allowed_versions) {
582 [ # # ]: 0 : VLOG_INFO("%s: re-added service controller \"%s\"",
583 : : mgr->name, c->target);
584 : 0 : ofservice_destroy(mgr, ofservice);
585 : 0 : add = true;
586 : : }
587 [ + + ]: 4701 : if (add) {
588 : 4701 : ofservice_create(mgr, c->target, allowed_versions, c->dscp);
589 : : }
590 : : } else {
591 [ # # ]: 0 : VLOG_WARN_RL(&rl, "%s: unsupported controller \"%s\"",
592 : : mgr->name, c->target);
593 : 0 : continue;
594 : : }
595 : :
596 : 4702 : shash_add_once(&new_controllers, c->target, &controllers[i]);
597 : : }
598 : :
599 : : /* Delete controllers that are no longer configured.
600 : : * Update configuration of all now-existing controllers. */
601 [ + + ][ - + ]: 4701 : HMAP_FOR_EACH_SAFE (ofconn, next_ofconn, hmap_node, &mgr->controllers) {
[ + + ]
602 : 1 : const char *target = ofconn_get_target(ofconn);
603 : : struct ofproto_controller *c;
604 : :
605 : 1 : c = shash_find_data(&new_controllers, target);
606 [ - + ]: 1 : if (!c) {
607 [ # # ]: 0 : VLOG_INFO("%s: removed primary controller \"%s\"",
608 : : mgr->name, target);
609 : 0 : ofconn_destroy(ofconn);
610 : : } else {
611 : 1 : ofconn_reconfigure(ofconn, c);
612 : : }
613 : : }
614 : :
615 : : /* Delete services that are no longer configured.
616 : : * Update configuration of all now-existing services. */
617 [ + + ][ - + ]: 9402 : HMAP_FOR_EACH_SAFE (ofservice, next_ofservice, node, &mgr->services) {
[ + + ]
618 : 4702 : const char *target = pvconn_get_name(ofservice->pvconn);
619 : : struct ofproto_controller *c;
620 : :
621 : 4702 : c = shash_find_data(&new_controllers, target);
622 [ + + ]: 4702 : if (!c) {
623 [ + - ]: 1 : VLOG_INFO("%s: removed service controller \"%s\"",
624 : : mgr->name, target);
625 : 1 : ofservice_destroy(mgr, ofservice);
626 : : } else {
627 : 4701 : ofservice_reconfigure(ofservice, c);
628 : : }
629 : : }
630 : :
631 : 4700 : shash_destroy(&new_controllers);
632 : :
633 : 4700 : ovs_mutex_unlock(&ofproto_mutex);
634 : :
635 : 4700 : update_in_band_remotes(mgr);
636 : 4700 : update_fail_open(mgr);
637 [ + + ]: 4700 : if (had_controllers != connmgr_has_controllers(mgr)) {
638 : 1 : ofproto_flush_flows(mgr->ofproto);
639 : : }
640 : 4700 : }
641 : :
642 : : /* Drops the connections between 'mgr' and all of its primary and secondary
643 : : * controllers, forcing them to reconnect. */
644 : : void
645 : 749 : connmgr_reconnect(const struct connmgr *mgr)
646 : : {
647 : : struct ofconn *ofconn;
648 : :
649 [ - + ]: 749 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
650 : 0 : rconn_reconnect(ofconn->rconn);
651 : : }
652 : 749 : }
653 : :
654 : : /* Sets the "snoops" for 'mgr' to the pvconn targets listed in 'snoops'.
655 : : *
656 : : * A "snoop" is a pvconn to which every OpenFlow message to or from the most
657 : : * important controller on 'mgr' is mirrored. */
658 : : int
659 : 749 : connmgr_set_snoops(struct connmgr *mgr, const struct sset *snoops)
660 : : {
661 : 749 : return set_pvconns(&mgr->snoops, &mgr->n_snoops, snoops);
662 : : }
663 : :
664 : : /* Adds each of the snoops currently configured on 'mgr' to 'snoops'. */
665 : : void
666 : 0 : connmgr_get_snoops(const struct connmgr *mgr, struct sset *snoops)
667 : : {
668 : : size_t i;
669 : :
670 [ # # ]: 0 : for (i = 0; i < mgr->n_snoops; i++) {
671 : 0 : sset_add(snoops, pvconn_get_name(mgr->snoops[i]));
672 : : }
673 : 0 : }
674 : :
675 : : /* Returns true if 'mgr' has at least one snoop, false if it has none. */
676 : : bool
677 : 4700 : connmgr_has_snoops(const struct connmgr *mgr)
678 : : {
679 : 4700 : return mgr->n_snoops > 0;
680 : : }
681 : :
682 : : /* Creates a new controller for 'target' in 'mgr'. update_controller() needs
683 : : * to be called later to finish the new ofconn's configuration. */
684 : : static void
685 : 1 : add_controller(struct connmgr *mgr, const char *target, uint8_t dscp,
686 : : uint32_t allowed_versions)
687 : : OVS_REQUIRES(ofproto_mutex)
688 : : {
689 : 1 : char *name = ofconn_make_name(mgr, target);
690 : : struct ofconn *ofconn;
691 : :
692 : 1 : ofconn = ofconn_create(mgr, rconn_create(5, 8, dscp, allowed_versions),
693 : : OFCONN_PRIMARY, true);
694 : 1 : rconn_connect(ofconn->rconn, target, name);
695 : 1 : hmap_insert(&mgr->controllers, &ofconn->hmap_node, hash_string(target, 0));
696 : :
697 : 1 : free(name);
698 : 1 : }
699 : :
700 : : static struct ofconn *
701 : 1 : find_controller_by_target(struct connmgr *mgr, const char *target)
702 : : {
703 : : struct ofconn *ofconn;
704 : :
705 [ - + ][ - + ]: 1 : HMAP_FOR_EACH_WITH_HASH (ofconn, hmap_node,
706 : : hash_string(target, 0), &mgr->controllers) {
707 [ # # ]: 0 : if (!strcmp(ofconn_get_target(ofconn), target)) {
708 : 0 : return ofconn;
709 : : }
710 : : }
711 : 1 : return NULL;
712 : : }
713 : :
714 : : static void
715 : 4700 : update_in_band_remotes(struct connmgr *mgr)
716 : : {
717 : : struct sockaddr_in *addrs;
718 : : size_t max_addrs, n_addrs;
719 : : struct ofconn *ofconn;
720 : : size_t i;
721 : :
722 : : /* Allocate enough memory for as many remotes as we could possibly have. */
723 : 4700 : max_addrs = mgr->n_extra_remotes + hmap_count(&mgr->controllers);
724 : 4700 : addrs = xmalloc(max_addrs * sizeof *addrs);
725 : 4700 : n_addrs = 0;
726 : :
727 : : /* Add all the remotes. */
728 [ + + ][ - + ]: 4701 : HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
729 : 1 : const char *target = rconn_get_target(ofconn->rconn);
730 : : union {
731 : : struct sockaddr_storage ss;
732 : : struct sockaddr_in in;
733 : : } sa;
734 : :
735 [ + - ]: 1 : if (ofconn->band == OFPROTO_IN_BAND
736 [ + - ]: 1 : && stream_parse_target_with_default_port(target, OFP_PORT, &sa.ss)
737 [ + - ]: 1 : && sa.ss.ss_family == AF_INET) {
738 : 1 : addrs[n_addrs++] = sa.in;
739 : : }
740 : : }
741 [ - + ]: 4700 : for (i = 0; i < mgr->n_extra_remotes; i++) {
742 : 0 : addrs[n_addrs++] = mgr->extra_in_band_remotes[i];
743 : : }
744 : :
745 : : /* Create or update or destroy in-band. */
746 [ + + ]: 4700 : if (n_addrs) {
747 [ + - ]: 1 : if (!mgr->in_band) {
748 : 1 : in_band_create(mgr->ofproto, mgr->local_port_name, &mgr->in_band);
749 : : }
750 : 1 : in_band_set_queue(mgr->in_band, mgr->in_band_queue);
751 : : } else {
752 : : /* in_band_run() needs a chance to delete any existing in-band flows.
753 : : * We will destroy mgr->in_band after it's done with that. */
754 : : }
755 [ + + ]: 4700 : if (mgr->in_band) {
756 : 1 : in_band_set_remotes(mgr->in_band, addrs, n_addrs);
757 : : }
758 : :
759 : : /* Clean up. */
760 : 4700 : free(addrs);
761 : 4700 : }
762 : :
763 : : static void
764 : 4845 : update_fail_open(struct connmgr *mgr)
765 : : OVS_EXCLUDED(ofproto_mutex)
766 : : {
767 [ + + ]: 4845 : if (connmgr_has_controllers(mgr)
768 [ - + ]: 1 : && mgr->fail_mode == OFPROTO_FAIL_STANDALONE) {
769 [ # # ]: 0 : if (!mgr->fail_open) {
770 : 0 : mgr->fail_open = fail_open_create(mgr->ofproto, mgr);
771 : : }
772 : : } else {
773 : 4845 : fail_open_destroy(mgr->fail_open);
774 : 4845 : mgr->fail_open = NULL;
775 : : }
776 : 4845 : }
777 : :
778 : : static int
779 : 749 : set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp,
780 : : const struct sset *sset)
781 : : {
782 : 749 : struct pvconn **pvconns = *pvconnsp;
783 : 749 : size_t n_pvconns = *n_pvconnsp;
784 : : const char *name;
785 : 749 : int retval = 0;
786 : : size_t i;
787 : :
788 [ - + ]: 749 : for (i = 0; i < n_pvconns; i++) {
789 : 0 : pvconn_close(pvconns[i]);
790 : : }
791 : 749 : free(pvconns);
792 : :
793 : 749 : pvconns = xmalloc(sset_count(sset) * sizeof *pvconns);
794 : 749 : n_pvconns = 0;
795 [ + - ][ - + ]: 1498 : SSET_FOR_EACH (name, sset) {
[ + + ]
796 : : struct pvconn *pvconn;
797 : : int error;
798 : 749 : error = pvconn_open(name, 0, 0, &pvconn);
799 [ + - ]: 749 : if (!error) {
800 : 749 : pvconns[n_pvconns++] = pvconn;
801 : : } else {
802 [ # # ]: 0 : VLOG_ERR("failed to listen on %s: %s", name, ovs_strerror(error));
803 [ # # ]: 0 : if (!retval) {
804 : 0 : retval = error;
805 : : }
806 : : }
807 : : }
808 : :
809 : 749 : *pvconnsp = pvconns;
810 : 749 : *n_pvconnsp = n_pvconns;
811 : :
812 : 749 : return retval;
813 : : }
814 : :
815 : : /* Returns a "preference level" for snooping 'ofconn'. A higher return value
816 : : * means that 'ofconn' is more interesting for monitoring than a lower return
817 : : * value. */
818 : : static int
819 : 0 : snoop_preference(const struct ofconn *ofconn)
820 : : {
821 [ # # # # ]: 0 : switch (ofconn->role) {
822 : : case OFPCR12_ROLE_MASTER:
823 : 0 : return 3;
824 : : case OFPCR12_ROLE_EQUAL:
825 : 0 : return 2;
826 : : case OFPCR12_ROLE_SLAVE:
827 : 0 : return 1;
828 : : case OFPCR12_ROLE_NOCHANGE:
829 : : default:
830 : : /* Shouldn't happen. */
831 : 0 : return 0;
832 : : }
833 : : }
834 : :
835 : : /* One of 'mgr''s "snoop" pvconns has accepted a new connection on 'vconn'.
836 : : * Connects this vconn to a controller. */
837 : : static void
838 : 0 : add_snooper(struct connmgr *mgr, struct vconn *vconn)
839 : : {
840 : : struct ofconn *ofconn, *best;
841 : :
842 : : /* Pick a controller for monitoring. */
843 : 0 : best = NULL;
844 [ # # ]: 0 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
845 [ # # ]: 0 : if (ofconn->type == OFCONN_PRIMARY
846 [ # # ][ # # ]: 0 : && (!best || snoop_preference(ofconn) > snoop_preference(best))) {
847 : 0 : best = ofconn;
848 : : }
849 : : }
850 : :
851 [ # # ]: 0 : if (best) {
852 : 0 : rconn_add_monitor(best->rconn, vconn);
853 : : } else {
854 [ # # ]: 0 : VLOG_INFO_RL(&rl, "no controller connection to snoop");
855 : 0 : vconn_close(vconn);
856 : : }
857 : 0 : }
858 : :
859 : : /* Public ofconn functions. */
860 : :
861 : : /* Returns the connection type, either OFCONN_PRIMARY or OFCONN_SERVICE. */
862 : : enum ofconn_type
863 : 35802 : ofconn_get_type(const struct ofconn *ofconn)
864 : : {
865 : 35802 : return ofconn->type;
866 : : }
867 : :
868 : : /* If a master election id is defined, stores it into '*idp' and returns
869 : : * true. Otherwise, stores UINT64_MAX into '*idp' and returns false. */
870 : : bool
871 : 24 : ofconn_get_master_election_id(const struct ofconn *ofconn, uint64_t *idp)
872 : : {
873 : 48 : *idp = (ofconn->connmgr->master_election_id_defined
874 : 18 : ? ofconn->connmgr->master_election_id
875 [ + + ]: 24 : : UINT64_MAX);
876 : 24 : return ofconn->connmgr->master_election_id_defined;
877 : : }
878 : :
879 : : /* Sets the master election id.
880 : : *
881 : : * Returns true if successful, false if the id is stale
882 : : */
883 : : bool
884 : 18 : ofconn_set_master_election_id(struct ofconn *ofconn, uint64_t id)
885 : : {
886 [ + + ]: 18 : if (ofconn->connmgr->master_election_id_defined
887 [ + + ]: 11 : &&
888 : : /* Unsigned difference interpreted as a two's complement signed
889 : : * value */
890 : 11 : (int64_t)(id - ofconn->connmgr->master_election_id) < 0) {
891 : 2 : return false;
892 : : }
893 : 16 : ofconn->connmgr->master_election_id = id;
894 : 16 : ofconn->connmgr->master_election_id_defined = true;
895 : :
896 : 16 : return true;
897 : : }
898 : :
899 : : /* Returns the role configured for 'ofconn'.
900 : : *
901 : : * The default role, if no other role has been set, is OFPCR12_ROLE_EQUAL. */
902 : : enum ofp12_controller_role
903 : 22 : ofconn_get_role(const struct ofconn *ofconn)
904 : : {
905 : 22 : return ofconn->role;
906 : : }
907 : :
908 : : void
909 : 2 : ofconn_send_role_status(struct ofconn *ofconn, uint32_t role, uint8_t reason)
910 : : {
911 : : struct ofputil_role_status status;
912 : : struct ofpbuf *buf;
913 : :
914 : 2 : status.reason = reason;
915 : 2 : status.role = role;
916 : 2 : ofconn_get_master_election_id(ofconn, &status.generation_id);
917 : :
918 : 2 : buf = ofputil_encode_role_status(&status, ofconn_get_protocol(ofconn));
919 [ + + ]: 2 : if (buf) {
920 : 1 : ofconn_send(ofconn, buf, NULL);
921 : : }
922 : 2 : }
923 : :
924 : : /* Changes 'ofconn''s role to 'role'. If 'role' is OFPCR12_ROLE_MASTER then
925 : : * any existing master is demoted to a slave. */
926 : : void
927 : 18 : ofconn_set_role(struct ofconn *ofconn, enum ofp12_controller_role role)
928 : : {
929 [ + - ][ + + ]: 18 : if (role != ofconn->role && role == OFPCR12_ROLE_MASTER) {
930 : : struct ofconn *other;
931 : :
932 [ + + ]: 24 : LIST_FOR_EACH (other, node, &ofconn->connmgr->all_conns) {
933 [ + + ]: 15 : if (other->role == OFPCR12_ROLE_MASTER) {
934 : 2 : other->role = OFPCR12_ROLE_SLAVE;
935 : 2 : ofconn_send_role_status(other, OFPCR12_ROLE_SLAVE, OFPCRR_MASTER_REQUEST);
936 : : }
937 : : }
938 : : }
939 : 18 : ofconn->role = role;
940 : 18 : }
941 : :
942 : : void
943 : 159 : ofconn_set_invalid_ttl_to_controller(struct ofconn *ofconn, bool enable)
944 : : {
945 : 159 : struct ofputil_async_cfg ac = ofconn_get_async_config(ofconn);
946 : 159 : uint32_t bit = 1u << OFPR_INVALID_TTL;
947 [ + + ]: 159 : if (enable) {
948 : 30 : ac.master[OAM_PACKET_IN] |= bit;
949 : : } else {
950 : 129 : ac.master[OAM_PACKET_IN] &= ~bit;
951 : : }
952 : 159 : ofconn_set_async_config(ofconn, &ac);
953 : 159 : }
954 : :
955 : : bool
956 : 282 : ofconn_get_invalid_ttl_to_controller(struct ofconn *ofconn)
957 : : {
958 : 282 : struct ofputil_async_cfg ac = ofconn_get_async_config(ofconn);
959 : 282 : uint32_t bit = 1u << OFPR_INVALID_TTL;
960 : 282 : return (ac.master[OAM_PACKET_IN] & bit) != 0;
961 : : }
962 : :
963 : : /* Returns the currently configured protocol for 'ofconn', one of OFPUTIL_P_*.
964 : : *
965 : : * Returns OFPUTIL_P_NONE, which is not a valid protocol, if 'ofconn' hasn't
966 : : * completed version negotiation. This can't happen if at least one OpenFlow
967 : : * message, other than OFPT_HELLO, has been received on the connection (such as
968 : : * in ofproto.c's message handling code), since version negotiation is a
969 : : * prerequisite for starting to receive messages. This means that
970 : : * OFPUTIL_P_NONE is a special case that most callers need not worry about. */
971 : : enum ofputil_protocol
972 : 38763 : ofconn_get_protocol(const struct ofconn *ofconn)
973 : : {
974 [ + + + - ]: 41633 : if (ofconn->protocol == OFPUTIL_P_NONE &&
975 : 2870 : rconn_is_connected(ofconn->rconn)) {
976 : 2870 : int version = rconn_get_version(ofconn->rconn);
977 [ + + ]: 2870 : if (version > 0) {
978 : 2868 : ofconn_set_protocol(CONST_CAST(struct ofconn *, ofconn),
979 : : ofputil_protocol_from_ofp_version(version));
980 : : }
981 : : }
982 : :
983 : 38763 : return ofconn->protocol;
984 : : }
985 : :
986 : : /* Sets the protocol for 'ofconn' to 'protocol' (one of OFPUTIL_P_*).
987 : : *
988 : : * (This doesn't actually send anything to accomplish this. Presumably the
989 : : * caller already did that.) */
990 : : void
991 : 10202 : ofconn_set_protocol(struct ofconn *ofconn, enum ofputil_protocol protocol)
992 : : {
993 : 10202 : ofconn->protocol = protocol;
994 : 10202 : }
995 : :
996 : : /* Returns the currently configured packet in format for 'ofconn', one of
997 : : * NXPIF_*.
998 : : *
999 : : * The default, if no other format has been set, is NXPIF_STANDARD. */
1000 : : enum nx_packet_in_format
1001 : 0 : ofconn_get_packet_in_format(struct ofconn *ofconn)
1002 : : {
1003 : 0 : return ofconn->packet_in_format;
1004 : : }
1005 : :
1006 : : /* Sets the packet in format for 'ofconn' to 'packet_in_format' (one of
1007 : : * NXPIF_*). */
1008 : : void
1009 : 211 : ofconn_set_packet_in_format(struct ofconn *ofconn,
1010 : : enum nx_packet_in_format packet_in_format)
1011 : : {
1012 : 211 : ofconn->packet_in_format = packet_in_format;
1013 : 211 : }
1014 : :
1015 : : /* Sets the controller connection ID for 'ofconn' to 'controller_id'.
1016 : : *
1017 : : * The connection controller ID is used for OFPP_CONTROLLER and
1018 : : * NXAST_CONTROLLER actions. See "struct nx_action_controller" for details. */
1019 : : void
1020 : 8 : ofconn_set_controller_id(struct ofconn *ofconn, uint16_t controller_id)
1021 : : {
1022 : 8 : ofconn->controller_id = controller_id;
1023 : 8 : }
1024 : :
1025 : : /* Returns the default miss send length for 'ofconn'. */
1026 : : int
1027 : 290 : ofconn_get_miss_send_len(const struct ofconn *ofconn)
1028 : : {
1029 : 290 : return ofconn->miss_send_len;
1030 : : }
1031 : :
1032 : : /* Sets the default miss send length for 'ofconn' to 'miss_send_len'. */
1033 : : void
1034 : 218 : ofconn_set_miss_send_len(struct ofconn *ofconn, int miss_send_len)
1035 : : {
1036 : 218 : ofconn->miss_send_len = miss_send_len;
1037 : 218 : }
1038 : :
1039 : : void
1040 : 167 : ofconn_set_async_config(struct ofconn *ofconn,
1041 : : const struct ofputil_async_cfg *ac)
1042 : : {
1043 [ + + ]: 167 : if (!ofconn->async_cfg) {
1044 : 135 : ofconn->async_cfg = xmalloc(sizeof *ofconn->async_cfg);
1045 : : }
1046 : 167 : *ofconn->async_cfg = *ac;
1047 : 167 : }
1048 : :
1049 : : struct ofputil_async_cfg
1050 : 2019 : ofconn_get_async_config(const struct ofconn *ofconn)
1051 : : {
1052 [ + + ]: 2019 : if (ofconn->async_cfg) {
1053 : 706 : return *ofconn->async_cfg;
1054 : : }
1055 : :
1056 : 1313 : int version = rconn_get_version(ofconn->rconn);
1057 [ - + ]: 1313 : return (version < 0 || !ofconn->enable_async_msgs
1058 : : ? OFPUTIL_ASYNC_CFG_INIT
1059 [ + + ]: 1313 : : ofputil_async_cfg_default(version));
1060 : : }
1061 : :
1062 : : /* Sends 'msg' on 'ofconn', accounting it as a reply. (If there is a
1063 : : * sufficient number of OpenFlow replies in-flight on a single ofconn, then the
1064 : : * connmgr will stop accepting new OpenFlow requests on that ofconn until the
1065 : : * controller has accepted some of the replies.) */
1066 : : void
1067 : 16938 : ofconn_send_reply(const struct ofconn *ofconn, struct ofpbuf *msg)
1068 : : {
1069 : 16938 : ofconn_send(ofconn, msg, ofconn->reply_counter);
1070 : 16938 : }
1071 : :
1072 : : /* Sends each of the messages in list 'replies' on 'ofconn' in order,
1073 : : * accounting them as replies. */
1074 : : void
1075 : 546 : ofconn_send_replies(const struct ofconn *ofconn, struct ovs_list *replies)
1076 : : {
1077 : : struct ofpbuf *reply;
1078 : :
1079 [ + + ]: 1132 : LIST_FOR_EACH_POP (reply, list_node, replies) {
1080 : 586 : ofconn_send_reply(ofconn, reply);
1081 : : }
1082 : 546 : }
1083 : :
1084 : : /* Sends 'error' on 'ofconn', as a reply to 'request'. Only at most the
1085 : : * first 64 bytes of 'request' are used. */
1086 : : void
1087 : 624 : ofconn_send_error(const struct ofconn *ofconn,
1088 : : const struct ofp_header *request, enum ofperr error)
1089 : : {
1090 : : static struct vlog_rate_limit err_rl = VLOG_RATE_LIMIT_INIT(10, 10);
1091 : : struct ofpbuf *reply;
1092 : :
1093 : 624 : reply = ofperr_encode_reply(error, request);
1094 [ + + ]: 624 : if (!VLOG_DROP_INFO(&err_rl)) {
1095 : : const char *type_name;
1096 : : size_t request_len;
1097 : : enum ofpraw raw;
1098 : :
1099 : 333 : request_len = ntohs(request->length);
1100 : 333 : type_name = (!ofpraw_decode_partial(&raw, request,
1101 : : MIN(64, request_len))
1102 : 333 : ? ofpraw_get_name(raw)
1103 [ + - ]: 333 : : "invalid");
1104 : :
1105 [ + - ]: 333 : VLOG_INFO("%s: sending %s error reply to %s message",
1106 : : rconn_get_name(ofconn->rconn), ofperr_to_string(error),
1107 : : type_name);
1108 : : }
1109 : 624 : ofconn_send_reply(ofconn, reply);
1110 : 624 : }
1111 : :
1112 : : /* Reports that a flow_mod operation of the type specified by 'command' was
1113 : : * successfully executed by 'ofconn', so that the connmgr can log it. */
1114 : : void
1115 : 33513 : ofconn_report_flow_mod(struct ofconn *ofconn,
1116 : : enum ofp_flow_mod_command command)
1117 : : {
1118 : : long long int now;
1119 : :
1120 [ + + + - ]: 33513 : switch (command) {
1121 : : case OFPFC_ADD:
1122 : 26722 : ofconn->n_add++;
1123 : 26722 : break;
1124 : :
1125 : : case OFPFC_MODIFY:
1126 : : case OFPFC_MODIFY_STRICT:
1127 : 379 : ofconn->n_modify++;
1128 : 379 : break;
1129 : :
1130 : : case OFPFC_DELETE:
1131 : : case OFPFC_DELETE_STRICT:
1132 : 6412 : ofconn->n_delete++;
1133 : 6412 : break;
1134 : : }
1135 : :
1136 : 33513 : now = time_msec();
1137 [ + + ]: 33513 : if (ofconn->next_op_report == LLONG_MAX) {
1138 : 1008 : ofconn->first_op = now;
1139 : 1008 : ofconn->next_op_report = MAX(now + 10 * 1000, ofconn->op_backoff);
1140 : 1008 : ofconn->op_backoff = ofconn->next_op_report + 60 * 1000;
1141 : : }
1142 : 33513 : ofconn->last_op = now;
1143 : 33513 : }
1144 : :
1145 : : /* OpenFlow 1.4 bundles. */
1146 : :
1147 : : static inline uint32_t
1148 : 1095 : bundle_hash(uint32_t id)
1149 : : {
1150 : 1095 : return hash_int(id, 0);
1151 : : }
1152 : :
1153 : : struct ofp_bundle *
1154 : 968 : ofconn_get_bundle(struct ofconn *ofconn, uint32_t id)
1155 : : {
1156 : : struct ofp_bundle *bundle;
1157 : :
1158 [ + + ][ - + ]: 968 : HMAP_FOR_EACH_IN_BUCKET(bundle, node, bundle_hash(id), &ofconn->bundles) {
1159 [ + - ]: 835 : if (bundle->id == id) {
1160 : 835 : return bundle;
1161 : : }
1162 : : }
1163 : :
1164 : 133 : return NULL;
1165 : : }
1166 : :
1167 : : enum ofperr
1168 : 127 : ofconn_insert_bundle(struct ofconn *ofconn, struct ofp_bundle *bundle)
1169 : : {
1170 : : /* XXX: Check the limit of open bundles */
1171 : :
1172 : 127 : hmap_insert(&ofconn->bundles, &bundle->node, bundle_hash(bundle->id));
1173 : :
1174 : 127 : return 0;
1175 : : }
1176 : :
1177 : : enum ofperr
1178 : 127 : ofconn_remove_bundle(struct ofconn *ofconn, struct ofp_bundle *bundle)
1179 : : {
1180 : 127 : hmap_remove(&ofconn->bundles, &bundle->node);
1181 : :
1182 : 127 : return 0;
1183 : : }
1184 : :
1185 : : static void
1186 : 3420 : bundle_remove_all(struct ofconn *ofconn)
1187 : : {
1188 : : struct ofp_bundle *b, *next;
1189 : :
1190 [ + + ][ - + ]: 3422 : HMAP_FOR_EACH_SAFE (b, next, node, &ofconn->bundles) {
[ + + ]
1191 : 2 : ofp_bundle_remove__(ofconn, b, false);
1192 : : }
1193 : 3420 : }
1194 : :
1195 : : /* Private ofconn functions. */
1196 : :
1197 : : static const char *
1198 : 1 : ofconn_get_target(const struct ofconn *ofconn)
1199 : : {
1200 : 1 : return rconn_get_target(ofconn->rconn);
1201 : : }
1202 : :
1203 : : static struct ofconn *
1204 : 3420 : ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type,
1205 : : bool enable_async_msgs)
1206 : : {
1207 : : struct ofconn *ofconn;
1208 : :
1209 : 3420 : ofconn = xzalloc(sizeof *ofconn);
1210 : 3420 : ofconn->connmgr = mgr;
1211 : 3420 : ovs_list_push_back(&mgr->all_conns, &ofconn->node);
1212 : 3420 : ofconn->rconn = rconn;
1213 : 3420 : ofconn->type = type;
1214 : 3420 : ofconn->enable_async_msgs = enable_async_msgs;
1215 : :
1216 : 3420 : hmap_init(&ofconn->monitors);
1217 : 3420 : ovs_list_init(&ofconn->updates);
1218 : :
1219 : 3420 : hmap_init(&ofconn->bundles);
1220 : :
1221 : 3420 : ofconn_flush(ofconn);
1222 : :
1223 : 3420 : return ofconn;
1224 : : }
1225 : :
1226 : : /* Clears all of the state in 'ofconn' that should not persist from one
1227 : : * connection to the next. */
1228 : : static void
1229 : 6888 : ofconn_flush(struct ofconn *ofconn)
1230 : : OVS_REQUIRES(ofproto_mutex)
1231 : : {
1232 : : struct ofmonitor *monitor, *next_monitor;
1233 : : int i;
1234 : :
1235 : 6888 : ofconn_log_flow_mods(ofconn);
1236 : :
1237 : 6888 : ofconn->role = OFPCR12_ROLE_EQUAL;
1238 : 6888 : ofconn_set_protocol(ofconn, OFPUTIL_P_NONE);
1239 : 6888 : ofconn->packet_in_format = NXPIF_STANDARD;
1240 : :
1241 : 6888 : rconn_packet_counter_destroy(ofconn->packet_in_counter);
1242 : 6888 : ofconn->packet_in_counter = rconn_packet_counter_create();
1243 [ + + ]: 20664 : for (i = 0; i < N_SCHEDULERS; i++) {
1244 [ - + ]: 13776 : if (ofconn->schedulers[i]) {
1245 : : int rate, burst;
1246 : :
1247 : 0 : pinsched_get_limits(ofconn->schedulers[i], &rate, &burst);
1248 : 0 : pinsched_destroy(ofconn->schedulers[i]);
1249 : 0 : ofconn->schedulers[i] = pinsched_create(rate, burst);
1250 : : }
1251 : : }
1252 : 13776 : ofconn->miss_send_len = (ofconn->type == OFCONN_PRIMARY
1253 : : ? OFP_DEFAULT_MISS_SEND_LEN
1254 [ + + ]: 6888 : : 0);
1255 : 6888 : ofconn->controller_id = 0;
1256 : :
1257 : 6888 : rconn_packet_counter_destroy(ofconn->reply_counter);
1258 : 6888 : ofconn->reply_counter = rconn_packet_counter_create();
1259 : :
1260 : 6888 : free(ofconn->async_cfg);
1261 : 6888 : ofconn->async_cfg = NULL;
1262 : :
1263 : 6888 : ofconn->n_add = ofconn->n_delete = ofconn->n_modify = 0;
1264 : 6888 : ofconn->first_op = ofconn->last_op = LLONG_MIN;
1265 : 6888 : ofconn->next_op_report = LLONG_MAX;
1266 : 6888 : ofconn->op_backoff = LLONG_MIN;
1267 : :
1268 [ + + ][ - + ]: 6892 : HMAP_FOR_EACH_SAFE (monitor, next_monitor, ofconn_node,
[ + + ]
1269 : : &ofconn->monitors) {
1270 : 4 : ofmonitor_destroy(monitor);
1271 : : }
1272 : 6888 : rconn_packet_counter_destroy(ofconn->monitor_counter);
1273 : 6888 : ofconn->monitor_counter = rconn_packet_counter_create();
1274 : 6888 : ofpbuf_list_delete(&ofconn->updates); /* ...but it should be empty. */
1275 : 6888 : }
1276 : :
1277 : : static void
1278 : 3420 : ofconn_destroy(struct ofconn *ofconn)
1279 : : OVS_REQUIRES(ofproto_mutex)
1280 : : {
1281 : 3420 : ofconn_flush(ofconn);
1282 : :
1283 [ + + ]: 3420 : if (ofconn->type == OFCONN_PRIMARY) {
1284 : 1 : hmap_remove(&ofconn->connmgr->controllers, &ofconn->hmap_node);
1285 : : }
1286 : :
1287 : 3420 : bundle_remove_all(ofconn);
1288 : 3420 : hmap_destroy(&ofconn->bundles);
1289 : :
1290 : 3420 : hmap_destroy(&ofconn->monitors);
1291 : 3420 : ovs_list_remove(&ofconn->node);
1292 : 3420 : rconn_destroy(ofconn->rconn);
1293 : 3420 : rconn_packet_counter_destroy(ofconn->packet_in_counter);
1294 : 3420 : rconn_packet_counter_destroy(ofconn->reply_counter);
1295 : 3420 : rconn_packet_counter_destroy(ofconn->monitor_counter);
1296 : 3420 : free(ofconn);
1297 : 3420 : }
1298 : :
1299 : : /* Reconfigures 'ofconn' to match 'c'. 'ofconn' and 'c' must have the same
1300 : : * target. */
1301 : : static void
1302 : 1 : ofconn_reconfigure(struct ofconn *ofconn, const struct ofproto_controller *c)
1303 : : {
1304 : : int probe_interval;
1305 : :
1306 : 1 : ofconn->band = c->band;
1307 : 1 : ofconn->enable_async_msgs = c->enable_async_msgs;
1308 : :
1309 : 1 : rconn_set_max_backoff(ofconn->rconn, c->max_backoff);
1310 : :
1311 [ + - ]: 1 : probe_interval = c->probe_interval ? MAX(c->probe_interval, 5) : 0;
1312 : 1 : rconn_set_probe_interval(ofconn->rconn, probe_interval);
1313 : :
1314 : 1 : ofconn_set_rate_limit(ofconn, c->rate_limit, c->burst_limit);
1315 : :
1316 : : /* If dscp value changed reconnect. */
1317 [ - + ]: 1 : if (c->dscp != rconn_get_dscp(ofconn->rconn)) {
1318 : 0 : rconn_set_dscp(ofconn->rconn, c->dscp);
1319 : 0 : rconn_reconnect(ofconn->rconn);
1320 : : }
1321 : 1 : }
1322 : :
1323 : : /* Returns true if it makes sense for 'ofconn' to receive and process OpenFlow
1324 : : * messages. */
1325 : : static bool
1326 : 259682 : ofconn_may_recv(const struct ofconn *ofconn)
1327 : : {
1328 : 259682 : int count = rconn_packet_counter_n_packets(ofconn->reply_counter);
1329 : 259682 : return count < OFCONN_REPLY_MAX;
1330 : : }
1331 : :
1332 : : static void
1333 : 104006 : ofconn_run(struct ofconn *ofconn,
1334 : : void (*handle_openflow)(struct ofconn *,
1335 : : const struct ofpbuf *ofp_msg))
1336 : : {
1337 : 104006 : struct connmgr *mgr = ofconn->connmgr;
1338 : : size_t i;
1339 : :
1340 [ + + ]: 312018 : for (i = 0; i < N_SCHEDULERS; i++) {
1341 : : struct ovs_list txq;
1342 : :
1343 : 208012 : pinsched_run(ofconn->schedulers[i], &txq);
1344 : 208012 : do_send_packet_ins(ofconn, &txq);
1345 : : }
1346 : :
1347 : 104006 : rconn_run(ofconn->rconn);
1348 : :
1349 : : /* Limit the number of iterations to avoid starving other tasks. */
1350 [ + + ][ + - ]: 156725 : for (i = 0; i < 50 && ofconn_may_recv(ofconn); i++) {
1351 : 156406 : struct ofpbuf *of_msg = rconn_recv(ofconn->rconn);
1352 [ + + ]: 156406 : if (!of_msg) {
1353 : 103687 : break;
1354 : : }
1355 : :
1356 [ - + ]: 52719 : if (mgr->fail_open) {
1357 : 0 : fail_open_maybe_recover(mgr->fail_open);
1358 : : }
1359 : :
1360 : 52719 : handle_openflow(ofconn, of_msg);
1361 : 52719 : ofpbuf_delete(of_msg);
1362 : : }
1363 : :
1364 [ + + ]: 104006 : if (time_msec() >= ofconn->next_op_report) {
1365 : 16 : ofconn_log_flow_mods(ofconn);
1366 : : }
1367 : :
1368 : 104006 : ovs_mutex_lock(&ofproto_mutex);
1369 [ + + ]: 104006 : if (!rconn_is_alive(ofconn->rconn)) {
1370 : 3390 : ofconn_destroy(ofconn);
1371 [ + + ]: 100616 : } else if (!rconn_is_connected(ofconn->rconn)) {
1372 : 48 : ofconn_flush(ofconn);
1373 : : }
1374 : 104006 : ovs_mutex_unlock(&ofproto_mutex);
1375 : 104006 : }
1376 : :
1377 : : static void
1378 : 103276 : ofconn_wait(struct ofconn *ofconn)
1379 : : {
1380 : : int i;
1381 : :
1382 [ + + ]: 309828 : for (i = 0; i < N_SCHEDULERS; i++) {
1383 : 206552 : pinsched_wait(ofconn->schedulers[i]);
1384 : : }
1385 : 103276 : rconn_run_wait(ofconn->rconn);
1386 [ + - ]: 103276 : if (ofconn_may_recv(ofconn)) {
1387 : 103276 : rconn_recv_wait(ofconn->rconn);
1388 : : }
1389 [ + + ]: 103276 : if (ofconn->next_op_report != LLONG_MAX) {
1390 : 33362 : poll_timer_wait_until(ofconn->next_op_report);
1391 : : }
1392 : 103276 : }
1393 : :
1394 : : static void
1395 : 6904 : ofconn_log_flow_mods(struct ofconn *ofconn)
1396 : : {
1397 : 6904 : int n_flow_mods = ofconn->n_add + ofconn->n_delete + ofconn->n_modify;
1398 [ + + ]: 6904 : if (n_flow_mods) {
1399 : 1008 : long long int ago = (time_msec() - ofconn->first_op) / 1000;
1400 : 1008 : long long int interval = (ofconn->last_op - ofconn->first_op) / 1000;
1401 : : struct ds s;
1402 : :
1403 : 1008 : ds_init(&s);
1404 : 1008 : ds_put_format(&s, "%d flow_mods ", n_flow_mods);
1405 [ + + ]: 1008 : if (interval == ago) {
1406 : 963 : ds_put_format(&s, "in the last %lld s", ago);
1407 [ + + ]: 45 : } else if (interval) {
1408 : 31 : ds_put_format(&s, "in the %lld s starting %lld s ago",
1409 : : interval, ago);
1410 : : } else {
1411 : 14 : ds_put_format(&s, "%lld s ago", ago);
1412 : : }
1413 : :
1414 : 1008 : ds_put_cstr(&s, " (");
1415 [ + + ]: 1008 : if (ofconn->n_add) {
1416 : 777 : ds_put_format(&s, "%d adds, ", ofconn->n_add);
1417 : : }
1418 [ + + ]: 1008 : if (ofconn->n_delete) {
1419 : 256 : ds_put_format(&s, "%d deletes, ", ofconn->n_delete);
1420 : : }
1421 [ + + ]: 1008 : if (ofconn->n_modify) {
1422 : 82 : ds_put_format(&s, "%d modifications, ", ofconn->n_modify);
1423 : : }
1424 : 1008 : s.length -= 2;
1425 : 1008 : ds_put_char(&s, ')');
1426 : :
1427 [ + - ]: 1008 : VLOG_INFO("%s: %s", rconn_get_name(ofconn->rconn), ds_cstr(&s));
1428 : 1008 : ds_destroy(&s);
1429 : :
1430 : 1008 : ofconn->n_add = ofconn->n_delete = ofconn->n_modify = 0;
1431 : : }
1432 : 6904 : ofconn->next_op_report = LLONG_MAX;
1433 : 6904 : }
1434 : :
1435 : : /* Returns true if 'ofconn' should receive asynchronous messages of the given
1436 : : * OAM_* 'type' and 'reason', which should be a OFPR_* value for OAM_PACKET_IN,
1437 : : * a OFPPR_* value for OAM_PORT_STATUS, or an OFPRR_* value for
1438 : : * OAM_FLOW_REMOVED. Returns false if the message should not be sent on
1439 : : * 'ofconn'. */
1440 : : static bool
1441 : 2986 : ofconn_receives_async_msg(const struct ofconn *ofconn,
1442 : : enum ofputil_async_msg_type type,
1443 : : unsigned int reason)
1444 : : {
1445 [ - + ]: 2986 : ovs_assert(reason < 32);
1446 [ - + ]: 2986 : ovs_assert((unsigned int) type < OAM_N_TYPES);
1447 : :
1448 : : /* Keep the following code in sync with the documentation in the
1449 : : * "Asynchronous Messages" section in DESIGN. */
1450 : :
1451 [ + + ][ + + ]: 2986 : if (ofconn->type == OFCONN_SERVICE && !ofconn->miss_send_len) {
1452 : : /* Service connections don't get asynchronous messages unless they have
1453 : : * explicitly asked for them by setting a nonzero miss send length. */
1454 : 1417 : return false;
1455 : : }
1456 : :
1457 : 1569 : struct ofputil_async_cfg ac = ofconn_get_async_config(ofconn);
1458 : 3138 : uint32_t *masks = (ofconn->role == OFPCR12_ROLE_SLAVE
1459 : : ? ac.slave
1460 [ + + ]: 1569 : : ac.master);
1461 : 2986 : return (masks[type] & (1u << reason)) != 0;
1462 : : }
1463 : :
1464 : : /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the
1465 : : * packet rather than to send the packet to the controller.
1466 : : *
1467 : : * This function returns true to indicate that a packet_in message
1468 : : * for a "table-miss" should be sent to at least one controller.
1469 : : * That is there is at least one controller with controller_id 0
1470 : : * which connected using an OpenFlow version earlier than OpenFlow1.3.
1471 : : *
1472 : : * False otherwise.
1473 : : *
1474 : : * This logic assumes that "table-miss" packet_in messages
1475 : : * are always sent to controller_id 0. */
1476 : : bool
1477 : 3904 : connmgr_wants_packet_in_on_miss(struct connmgr *mgr) OVS_EXCLUDED(ofproto_mutex)
1478 : : {
1479 : : struct ofconn *ofconn;
1480 : :
1481 : 3904 : ovs_mutex_lock(&ofproto_mutex);
1482 [ + + ]: 4905 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
1483 : 1135 : enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
1484 : :
1485 [ + - ][ + + ]: 1135 : if (ofconn->controller_id == 0 &&
1486 [ + + ]: 1134 : (protocol == OFPUTIL_P_NONE ||
1487 : 1134 : ofputil_protocol_to_ofp_version(protocol) < OFP13_VERSION)) {
1488 : 134 : ovs_mutex_unlock(&ofproto_mutex);
1489 : 134 : return true;
1490 : : }
1491 : : }
1492 : 3770 : ovs_mutex_unlock(&ofproto_mutex);
1493 : :
1494 : 3770 : return false;
1495 : : }
1496 : :
1497 : : /* Returns a human-readable name for an OpenFlow connection between 'mgr' and
1498 : : * 'target', suitable for use in log messages for identifying the connection.
1499 : : *
1500 : : * The name is dynamically allocated. The caller should free it (with free())
1501 : : * when it is no longer needed. */
1502 : : static char *
1503 : 3420 : ofconn_make_name(const struct connmgr *mgr, const char *target)
1504 : : {
1505 : 3420 : return xasprintf("%s<->%s", mgr->name, target);
1506 : : }
1507 : :
1508 : : static void
1509 : 3420 : ofconn_set_rate_limit(struct ofconn *ofconn, int rate, int burst)
1510 : : {
1511 : : int i;
1512 : :
1513 [ + + ]: 10260 : for (i = 0; i < N_SCHEDULERS; i++) {
1514 : 6840 : struct pinsched **s = &ofconn->schedulers[i];
1515 : :
1516 [ - + ]: 6840 : if (rate > 0) {
1517 [ # # ]: 0 : if (!*s) {
1518 : 0 : *s = pinsched_create(rate, burst);
1519 : : } else {
1520 : 0 : pinsched_set_limits(*s, rate, burst);
1521 : : }
1522 : : } else {
1523 : 6840 : pinsched_destroy(*s);
1524 : 6840 : *s = NULL;
1525 : : }
1526 : : }
1527 : 3420 : }
1528 : :
1529 : : static void
1530 : 20061 : ofconn_send(const struct ofconn *ofconn, struct ofpbuf *msg,
1531 : : struct rconn_packet_counter *counter)
1532 : : {
1533 : 20061 : ofpmsg_update_length(msg);
1534 : 20061 : rconn_send(ofconn->rconn, msg, counter);
1535 : 20061 : }
1536 : :
1537 : : /* Sending asynchronous messages. */
1538 : :
1539 : : /* Sends an OFPT_PORT_STATUS message with 'opp' and 'reason' to appropriate
1540 : : * controllers managed by 'mgr'. For messages caused by a controller
1541 : : * OFPT_PORT_MOD, specify 'source' as the controller connection that sent the
1542 : : * request; otherwise, specify 'source' as NULL. */
1543 : : void
1544 : 4050 : connmgr_send_port_status(struct connmgr *mgr, struct ofconn *source,
1545 : : const struct ofputil_phy_port *pp, uint8_t reason)
1546 : : {
1547 : : /* XXX Should limit the number of queued port status change messages. */
1548 : : struct ofputil_port_status ps;
1549 : : struct ofconn *ofconn;
1550 : :
1551 : 4050 : ps.reason = reason;
1552 : 4050 : ps.desc = *pp;
1553 [ + + ]: 5173 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
1554 [ + + ]: 1123 : if (ofconn_receives_async_msg(ofconn, OAM_PORT_STATUS, reason)) {
1555 : : struct ofpbuf *msg;
1556 : :
1557 : : /* Before 1.5, OpenFlow specified that OFPT_PORT_MOD should not
1558 : : * generate OFPT_PORT_STATUS messages. That requirement was a
1559 : : * relic of how OpenFlow originally supported a single controller,
1560 : : * so that one could expect the controller to already know the
1561 : : * changes it had made.
1562 : : *
1563 : : * EXT-338 changes OpenFlow 1.5 OFPT_PORT_MOD to send
1564 : : * OFPT_PORT_STATUS messages to every controller. This is
1565 : : * obviously more useful in the multi-controller case. We could
1566 : : * always implement it that way in OVS, but that would risk
1567 : : * confusing controllers that are intended for single-controller
1568 : : * use only. (Imagine a controller that generates an OFPT_PORT_MOD
1569 : : * in response to any OFPT_PORT_STATUS!)
1570 : : *
1571 : : * So this compromises: for OpenFlow 1.4 and earlier, it generates
1572 : : * OFPT_PORT_STATUS for OFPT_PORT_MOD, but not back to the
1573 : : * originating controller. In a single-controller environment, in
1574 : : * particular, this means that it will never generate
1575 : : * OFPT_PORT_STATUS for OFPT_PORT_MOD at all. */
1576 [ - + ]: 458 : if (ofconn == source
1577 [ # # ]: 0 : && rconn_get_version(ofconn->rconn) < OFP15_VERSION) {
1578 : 0 : continue;
1579 : : }
1580 : :
1581 : 458 : msg = ofputil_encode_port_status(&ps, ofconn_get_protocol(ofconn));
1582 : 458 : ofconn_send(ofconn, msg, NULL);
1583 : : }
1584 : : }
1585 : 4050 : }
1586 : :
1587 : : /* Sends an OFPT_REQUESTFORWARD message with 'request' and 'reason' to
1588 : : * appropriate controllers managed by 'mgr'. For messages caused by a
1589 : : * controller OFPT_GROUP_MOD and OFPT_METER_MOD, specify 'source' as the
1590 : : * controller connection that sent the request; otherwise, specify 'source'
1591 : : * as NULL. */
1592 : : void
1593 : 176 : connmgr_send_requestforward(struct connmgr *mgr, const struct ofconn *source,
1594 : : const struct ofputil_requestforward *rf)
1595 : : {
1596 : : struct ofconn *ofconn;
1597 : :
1598 [ + + ]: 409 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
1599 [ + + ]: 233 : if (ofconn_receives_async_msg(ofconn, OAM_REQUESTFORWARD, rf->reason)
1600 [ + - ]: 6 : && rconn_get_version(ofconn->rconn) >= OFP14_VERSION
1601 [ + + ]: 6 : && ofconn != source) {
1602 : 4 : enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
1603 : 4 : ofconn_send(ofconn, ofputil_encode_requestforward(rf, protocol),
1604 : : NULL);
1605 : : }
1606 : : }
1607 : 176 : }
1608 : :
1609 : : /* Sends an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message based on 'fr' to
1610 : : * appropriate controllers managed by 'mgr'. */
1611 : : void
1612 : 38 : connmgr_send_flow_removed(struct connmgr *mgr,
1613 : : const struct ofputil_flow_removed *fr)
1614 : : {
1615 : : struct ofconn *ofconn;
1616 : :
1617 [ + + ]: 113 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
1618 [ + + ]: 75 : if (ofconn_receives_async_msg(ofconn, OAM_FLOW_REMOVED, fr->reason)) {
1619 : : struct ofpbuf *msg;
1620 : :
1621 : : /* Account flow expirations as replies to OpenFlow requests. That
1622 : : * works because preventing OpenFlow requests from being processed
1623 : : * also prevents new flows from being added (and expiring). (It
1624 : : * also prevents processing OpenFlow requests that would not add
1625 : : * new flows, so it is imperfect.) */
1626 : 18 : msg = ofputil_encode_flow_removed(fr, ofconn_get_protocol(ofconn));
1627 : 18 : ofconn_send_reply(ofconn, msg);
1628 : : }
1629 : : }
1630 : 38 : }
1631 : :
1632 : : /* Sends an OFPT_TABLE_STATUS message with 'reason' to appropriate controllers
1633 : : * managed by 'mgr'. When the table state changes, the controller needs to be
1634 : : * informed with the OFPT_TABLE_STATUS message. The reason values
1635 : : * OFPTR_VACANCY_DOWN and OFPTR_VACANCY_UP identify a vacancy message. The
1636 : : * vacancy events are generated when the remaining space in the flow table
1637 : : * changes and crosses one of the vacancy thereshold specified by
1638 : : * OFPT_TABLE_MOD. */
1639 : : void
1640 : 3 : connmgr_send_table_status(struct connmgr *mgr,
1641 : : const struct ofputil_table_desc *td,
1642 : : uint8_t reason)
1643 : : {
1644 : : struct ofputil_table_status ts;
1645 : : struct ofconn *ofconn;
1646 : :
1647 : 3 : ts.reason = reason;
1648 : 3 : ts.desc = *td;
1649 : :
1650 [ + + ]: 9 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
1651 [ + + ]: 6 : if (ofconn_receives_async_msg(ofconn, OAM_TABLE_STATUS, reason)) {
1652 : : struct ofpbuf *msg;
1653 : :
1654 : 3 : msg = ofputil_encode_table_status(&ts,
1655 : : ofconn_get_protocol(ofconn));
1656 [ + - ]: 3 : if (msg) {
1657 : 3 : ofconn_send(ofconn, msg, NULL);
1658 : : }
1659 : : }
1660 : : }
1661 : 3 : }
1662 : :
1663 : : /* Given 'pin', sends an OFPT_PACKET_IN message to each OpenFlow controller as
1664 : : * necessary according to their individual configurations. */
1665 : : void
1666 : 1051 : connmgr_send_async_msg(struct connmgr *mgr,
1667 : : const struct ofproto_async_msg *am)
1668 : : {
1669 : : struct ofconn *ofconn;
1670 : :
1671 [ + + ]: 2656 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
1672 : 1605 : enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
1673 [ + + ][ + - ]: 1605 : if (protocol == OFPUTIL_P_NONE || !rconn_is_connected(ofconn->rconn)
1674 [ + + ]: 1604 : || ofconn->controller_id != am->controller_id
1675 [ + + ]: 1549 : || !ofconn_receives_async_msg(ofconn, am->oam,
1676 : 1549 : am->pin.up.public.reason)) {
1677 : 614 : continue;
1678 : : }
1679 : :
1680 : 991 : struct ofpbuf *msg = ofputil_encode_packet_in_private(
1681 : : &am->pin.up, protocol, ofconn->packet_in_format);
1682 : :
1683 : : struct ovs_list txq;
1684 [ + + ]: 987 : bool is_miss = (am->pin.up.public.reason == OFPR_NO_MATCH ||
1685 [ + + ][ + + ]: 1978 : am->pin.up.public.reason == OFPR_EXPLICIT_MISS ||
1686 : 975 : am->pin.up.public.reason == OFPR_IMPLICIT_MISS);
1687 : 991 : pinsched_send(ofconn->schedulers[is_miss],
1688 : : am->pin.up.public.flow_metadata.flow.in_port.ofp_port,
1689 : : msg, &txq);
1690 : 991 : do_send_packet_ins(ofconn, &txq);
1691 : : }
1692 : 1051 : }
1693 : :
1694 : : static void
1695 : 209003 : do_send_packet_ins(struct ofconn *ofconn, struct ovs_list *txq)
1696 : : {
1697 : : struct ofpbuf *pin;
1698 : :
1699 [ + + ]: 209994 : LIST_FOR_EACH_POP (pin, list_node, txq) {
1700 [ - + ]: 991 : if (rconn_send_with_limit(ofconn->rconn, pin,
1701 : : ofconn->packet_in_counter, 100) == EAGAIN) {
1702 : : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
1703 : :
1704 [ # # ]: 0 : VLOG_INFO_RL(&rl, "%s: dropping packet-in due to queue overflow",
1705 : : rconn_get_name(ofconn->rconn));
1706 : : }
1707 : : }
1708 : 209003 : }
1709 : :
1710 : : /* Fail-open settings. */
1711 : :
1712 : : /* Returns the failure handling mode (OFPROTO_FAIL_SECURE or
1713 : : * OFPROTO_FAIL_STANDALONE) for 'mgr'. */
1714 : : enum ofproto_fail_mode
1715 : 0 : connmgr_get_fail_mode(const struct connmgr *mgr)
1716 : : {
1717 : 0 : return mgr->fail_mode;
1718 : : }
1719 : :
1720 : : /* Sets the failure handling mode for 'mgr' to 'fail_mode' (either
1721 : : * OFPROTO_FAIL_SECURE or OFPROTO_FAIL_STANDALONE). */
1722 : : void
1723 : 4700 : connmgr_set_fail_mode(struct connmgr *mgr, enum ofproto_fail_mode fail_mode)
1724 : : {
1725 [ + + ]: 4700 : if (mgr->fail_mode != fail_mode) {
1726 : 145 : mgr->fail_mode = fail_mode;
1727 : 145 : update_fail_open(mgr);
1728 [ + - ]: 145 : if (!connmgr_has_controllers(mgr)) {
1729 : 145 : ofproto_flush_flows(mgr->ofproto);
1730 : : }
1731 : : }
1732 : 4700 : }
1733 : :
1734 : : /* Fail-open implementation. */
1735 : :
1736 : : /* Returns the longest probe interval among the primary controllers configured
1737 : : * on 'mgr'. Returns 0 if there are no primary controllers. */
1738 : : int
1739 : 0 : connmgr_get_max_probe_interval(const struct connmgr *mgr)
1740 : : {
1741 : : const struct ofconn *ofconn;
1742 : : int max_probe_interval;
1743 : :
1744 : 0 : max_probe_interval = 0;
1745 [ # # ][ # # ]: 0 : HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
1746 : 0 : int probe_interval = rconn_get_probe_interval(ofconn->rconn);
1747 : 0 : max_probe_interval = MAX(max_probe_interval, probe_interval);
1748 : : }
1749 : 0 : return max_probe_interval;
1750 : : }
1751 : :
1752 : : /* Returns the number of seconds for which all of 'mgr's primary controllers
1753 : : * have been disconnected. Returns 0 if 'mgr' has no primary controllers. */
1754 : : int
1755 : 0 : connmgr_failure_duration(const struct connmgr *mgr)
1756 : : {
1757 : : const struct ofconn *ofconn;
1758 : : int min_failure_duration;
1759 : :
1760 [ # # ]: 0 : if (!connmgr_has_controllers(mgr)) {
1761 : 0 : return 0;
1762 : : }
1763 : :
1764 : 0 : min_failure_duration = INT_MAX;
1765 [ # # ][ # # ]: 0 : HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
1766 : 0 : int failure_duration = rconn_failure_duration(ofconn->rconn);
1767 : 0 : min_failure_duration = MIN(min_failure_duration, failure_duration);
1768 : : }
1769 : 0 : return min_failure_duration;
1770 : : }
1771 : :
1772 : : /* Returns true if at least one primary controller is connected (regardless of
1773 : : * whether those controllers are believed to have authenticated and accepted
1774 : : * this switch), false if none of them are connected. */
1775 : : bool
1776 : 0 : connmgr_is_any_controller_connected(const struct connmgr *mgr)
1777 : : {
1778 : : const struct ofconn *ofconn;
1779 : :
1780 [ # # ][ # # ]: 0 : HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
1781 [ # # ]: 0 : if (rconn_is_connected(ofconn->rconn)) {
1782 : 0 : return true;
1783 : : }
1784 : : }
1785 : 0 : return false;
1786 : : }
1787 : :
1788 : : /* Returns true if at least one primary controller is believed to have
1789 : : * authenticated and accepted this switch, false otherwise. */
1790 : : bool
1791 : 0 : connmgr_is_any_controller_admitted(const struct connmgr *mgr)
1792 : : {
1793 : : const struct ofconn *ofconn;
1794 : :
1795 [ # # ][ # # ]: 0 : HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
1796 [ # # ]: 0 : if (rconn_is_admitted(ofconn->rconn)) {
1797 : 0 : return true;
1798 : : }
1799 : : }
1800 : 0 : return false;
1801 : : }
1802 : :
1803 : : /* In-band configuration. */
1804 : :
1805 : : static bool any_extras_changed(const struct connmgr *,
1806 : : const struct sockaddr_in *extras, size_t n);
1807 : :
1808 : : /* Sets the 'n' TCP port addresses in 'extras' as ones to which 'mgr''s
1809 : : * in-band control should guarantee access, in the same way that in-band
1810 : : * control guarantees access to OpenFlow controllers. */
1811 : : void
1812 : 4700 : connmgr_set_extra_in_band_remotes(struct connmgr *mgr,
1813 : : const struct sockaddr_in *extras, size_t n)
1814 : : {
1815 [ + - ]: 4700 : if (!any_extras_changed(mgr, extras, n)) {
1816 : 4700 : return;
1817 : : }
1818 : :
1819 : 0 : free(mgr->extra_in_band_remotes);
1820 : 0 : mgr->n_extra_remotes = n;
1821 : 0 : mgr->extra_in_band_remotes = xmemdup(extras, n * sizeof *extras);
1822 : :
1823 : 0 : update_in_band_remotes(mgr);
1824 : : }
1825 : :
1826 : : /* Sets the OpenFlow queue used by flows set up by in-band control on
1827 : : * 'mgr' to 'queue_id'. If 'queue_id' is negative, then in-band control
1828 : : * flows will use the default queue. */
1829 : : void
1830 : 4700 : connmgr_set_in_band_queue(struct connmgr *mgr, int queue_id)
1831 : : {
1832 [ - + ]: 4700 : if (queue_id != mgr->in_band_queue) {
1833 : 0 : mgr->in_band_queue = queue_id;
1834 : 0 : update_in_band_remotes(mgr);
1835 : : }
1836 : 4700 : }
1837 : :
1838 : : static bool
1839 : 4700 : any_extras_changed(const struct connmgr *mgr,
1840 : : const struct sockaddr_in *extras, size_t n)
1841 : : {
1842 : : size_t i;
1843 : :
1844 [ - + ]: 4700 : if (n != mgr->n_extra_remotes) {
1845 : 0 : return true;
1846 : : }
1847 : :
1848 [ - + ]: 4700 : for (i = 0; i < n; i++) {
1849 : 0 : const struct sockaddr_in *old = &mgr->extra_in_band_remotes[i];
1850 : 0 : const struct sockaddr_in *new = &extras[i];
1851 : :
1852 [ # # ][ # # ]: 0 : if (old->sin_addr.s_addr != new->sin_addr.s_addr ||
1853 : 0 : old->sin_port != new->sin_port) {
1854 : 0 : return true;
1855 : : }
1856 : : }
1857 : :
1858 : 4700 : return false;
1859 : : }
1860 : :
1861 : : /* In-band implementation. */
1862 : :
1863 : : bool
1864 : 23059 : connmgr_has_in_band(struct connmgr *mgr)
1865 : : {
1866 : 23059 : return mgr->in_band != NULL;
1867 : : }
1868 : :
1869 : : /* Fail-open and in-band implementation. */
1870 : :
1871 : : /* Called by 'ofproto' after all flows have been flushed, to allow fail-open
1872 : : * and standalone mode to re-create their flows.
1873 : : *
1874 : : * In-band control has more sophisticated code that manages flows itself. */
1875 : : void
1876 : 146 : connmgr_flushed(struct connmgr *mgr)
1877 : : OVS_EXCLUDED(ofproto_mutex)
1878 : : {
1879 [ - + ]: 146 : if (mgr->fail_open) {
1880 : 0 : fail_open_flushed(mgr->fail_open);
1881 : : }
1882 : :
1883 : : /* If there are no controllers and we're in standalone mode, set up a flow
1884 : : * that matches every packet and directs them to OFPP_NORMAL (which goes to
1885 : : * us). Otherwise, the switch is in secure mode and we won't pass any
1886 : : * traffic until a controller has been defined and it tells us to do so. */
1887 [ + + ]: 146 : if (!connmgr_has_controllers(mgr)
1888 [ + - ]: 145 : && mgr->fail_mode == OFPROTO_FAIL_STANDALONE) {
1889 : : struct ofpbuf ofpacts;
1890 : : struct match match;
1891 : :
1892 : 145 : ofpbuf_init(&ofpacts, OFPACT_OUTPUT_SIZE);
1893 : 145 : ofpact_put_OUTPUT(&ofpacts)->port = OFPP_NORMAL;
1894 : :
1895 : 145 : match_init_catchall(&match);
1896 : 145 : ofproto_add_flow(mgr->ofproto, &match, 0, ofpacts.data,
1897 : 145 : ofpacts.size);
1898 : :
1899 : 145 : ofpbuf_uninit(&ofpacts);
1900 : : }
1901 : 146 : }
1902 : :
1903 : : /* Returns the number of hidden rules created by the in-band and fail-open
1904 : : * implementations in table 0. (Subtracting this count from the number of
1905 : : * rules in the table 0 classifier, as maintained in struct oftable, yields
1906 : : * the number of flows that OVS should report via OpenFlow for table 0.) */
1907 : : int
1908 : 10 : connmgr_count_hidden_rules(const struct connmgr *mgr)
1909 : : {
1910 : 10 : int n_hidden = 0;
1911 [ + + ]: 10 : if (mgr->in_band) {
1912 : 1 : n_hidden += in_band_count_rules(mgr->in_band);
1913 : : }
1914 [ - + ]: 10 : if (mgr->fail_open) {
1915 : 0 : n_hidden += fail_open_count_rules(mgr->fail_open);
1916 : : }
1917 : 10 : return n_hidden;
1918 : : }
1919 : :
1920 : : /* Creates a new ofservice for 'target' in 'mgr'. Returns 0 if successful,
1921 : : * otherwise a positive errno value.
1922 : : *
1923 : : * ofservice_reconfigure() must be called to fully configure the new
1924 : : * ofservice. */
1925 : : static int
1926 : 750 : ofservice_create(struct connmgr *mgr, const char *target,
1927 : : uint32_t allowed_versions, uint8_t dscp)
1928 : : {
1929 : : struct ofservice *ofservice;
1930 : : struct pvconn *pvconn;
1931 : : int error;
1932 : :
1933 : 750 : error = pvconn_open(target, allowed_versions, dscp, &pvconn);
1934 [ - + ]: 750 : if (error) {
1935 : 0 : return error;
1936 : : }
1937 : :
1938 : 750 : ofservice = xzalloc(sizeof *ofservice);
1939 : 750 : hmap_insert(&mgr->services, &ofservice->node, hash_string(target, 0));
1940 : 750 : ofservice->pvconn = pvconn;
1941 : 750 : ofservice->allowed_versions = allowed_versions;
1942 : :
1943 : 750 : return 0;
1944 : : }
1945 : :
1946 : : static void
1947 : 750 : ofservice_destroy(struct connmgr *mgr, struct ofservice *ofservice)
1948 : : {
1949 : 750 : hmap_remove(&mgr->services, &ofservice->node);
1950 : 750 : pvconn_close(ofservice->pvconn);
1951 : 750 : free(ofservice);
1952 : 750 : }
1953 : :
1954 : : static void
1955 : 4701 : ofservice_reconfigure(struct ofservice *ofservice,
1956 : : const struct ofproto_controller *c)
1957 : : {
1958 : 4701 : ofservice->probe_interval = c->probe_interval;
1959 : 4701 : ofservice->rate_limit = c->rate_limit;
1960 : 4701 : ofservice->burst_limit = c->burst_limit;
1961 : 4701 : ofservice->enable_async_msgs = c->enable_async_msgs;
1962 : 4701 : ofservice->dscp = c->dscp;
1963 : 4701 : }
1964 : :
1965 : : /* Finds and returns the ofservice within 'mgr' that has the given
1966 : : * 'target', or a null pointer if none exists. */
1967 : : static struct ofservice *
1968 : 4701 : ofservice_lookup(struct connmgr *mgr, const char *target)
1969 : : {
1970 : : struct ofservice *ofservice;
1971 : :
1972 [ + + ][ - + ]: 4701 : HMAP_FOR_EACH_WITH_HASH (ofservice, node, hash_string(target, 0),
1973 : : &mgr->services) {
1974 [ + - ]: 3951 : if (!strcmp(pvconn_get_name(ofservice->pvconn), target)) {
1975 : 3951 : return ofservice;
1976 : : }
1977 : : }
1978 : 750 : return NULL;
1979 : : }
1980 : :
1981 : : /* Flow monitors (NXST_FLOW_MONITOR). */
1982 : :
1983 : : /* A counter incremented when something significant happens to an OpenFlow
1984 : : * rule.
1985 : : *
1986 : : * - When a rule is added, its 'add_seqno' and 'modify_seqno' are set to
1987 : : * the current value (which is then incremented).
1988 : : *
1989 : : * - When a rule is modified, its 'modify_seqno' is set to the current
1990 : : * value (which is then incremented).
1991 : : *
1992 : : * Thus, by comparing an old value of monitor_seqno against a rule's
1993 : : * 'add_seqno', one can tell whether the rule was added before or after the old
1994 : : * value was read, and similarly for 'modify_seqno'.
1995 : : *
1996 : : * 32 bits should normally be sufficient (and would be nice, to save space in
1997 : : * each rule) but then we'd have to have some special cases for wraparound.
1998 : : *
1999 : : * We initialize monitor_seqno to 1 to allow 0 to be used as an invalid
2000 : : * value. */
2001 : : static uint64_t monitor_seqno = 1;
2002 : :
2003 : 71674 : COVERAGE_DEFINE(ofmonitor_pause);
2004 : 71674 : COVERAGE_DEFINE(ofmonitor_resume);
2005 : :
2006 : : enum ofperr
2007 : 4 : ofmonitor_create(const struct ofputil_flow_monitor_request *request,
2008 : : struct ofconn *ofconn, struct ofmonitor **monitorp)
2009 : : OVS_REQUIRES(ofproto_mutex)
2010 : : {
2011 : : struct ofmonitor *m;
2012 : :
2013 : 4 : *monitorp = NULL;
2014 : :
2015 : 4 : m = ofmonitor_lookup(ofconn, request->id);
2016 [ - + ]: 4 : if (m) {
2017 : 0 : return OFPERR_OFPMOFC_MONITOR_EXISTS;
2018 : : }
2019 : :
2020 : 4 : m = xmalloc(sizeof *m);
2021 : 4 : m->ofconn = ofconn;
2022 : 4 : hmap_insert(&ofconn->monitors, &m->ofconn_node, hash_int(request->id, 0));
2023 : 4 : m->id = request->id;
2024 : 4 : m->flags = request->flags;
2025 : 4 : m->out_port = request->out_port;
2026 : 4 : m->table_id = request->table_id;
2027 : 4 : minimatch_init(&m->match, &request->match);
2028 : :
2029 : 4 : *monitorp = m;
2030 : 4 : return 0;
2031 : : }
2032 : :
2033 : : struct ofmonitor *
2034 : 4 : ofmonitor_lookup(struct ofconn *ofconn, uint32_t id)
2035 : : OVS_REQUIRES(ofproto_mutex)
2036 : : {
2037 : : struct ofmonitor *m;
2038 : :
2039 [ - + ][ - + ]: 4 : HMAP_FOR_EACH_IN_BUCKET (m, ofconn_node, hash_int(id, 0),
2040 : : &ofconn->monitors) {
2041 [ # # ]: 0 : if (m->id == id) {
2042 : 0 : return m;
2043 : : }
2044 : : }
2045 : 4 : return NULL;
2046 : : }
2047 : :
2048 : : void
2049 : 4 : ofmonitor_destroy(struct ofmonitor *m)
2050 : : OVS_REQUIRES(ofproto_mutex)
2051 : : {
2052 [ + - ]: 4 : if (m) {
2053 : 4 : minimatch_destroy(&m->match);
2054 : 4 : hmap_remove(&m->ofconn->monitors, &m->ofconn_node);
2055 : 4 : free(m);
2056 : : }
2057 : 4 : }
2058 : :
2059 : : void
2060 : 57573 : ofmonitor_report(struct connmgr *mgr, struct rule *rule,
2061 : : enum nx_flow_update_event event,
2062 : : enum ofp_flow_removed_reason reason,
2063 : : const struct ofconn *abbrev_ofconn, ovs_be32 abbrev_xid,
2064 : : const struct rule_actions *old_actions)
2065 : : OVS_REQUIRES(ofproto_mutex)
2066 : : {
2067 : : enum nx_flow_monitor_flags update;
2068 : : struct ofconn *ofconn;
2069 : :
2070 [ + + ]: 57573 : if (rule_is_hidden(rule)) {
2071 : 14 : return;
2072 : : }
2073 : :
2074 [ + + + - ]: 57559 : switch (event) {
2075 : : case NXFME_ADDED:
2076 : 31032 : update = NXFMF_ADD;
2077 : 31032 : rule->add_seqno = rule->modify_seqno = monitor_seqno++;
2078 : 31032 : break;
2079 : :
2080 : : case NXFME_DELETED:
2081 : 26152 : update = NXFMF_DELETE;
2082 : 26152 : break;
2083 : :
2084 : : case NXFME_MODIFIED:
2085 : 375 : update = NXFMF_MODIFY;
2086 : 375 : rule->modify_seqno = monitor_seqno++;
2087 : 375 : break;
2088 : :
2089 : : default:
2090 : : case NXFME_ABBREV:
2091 : 0 : OVS_NOT_REACHED();
2092 : : }
2093 : :
2094 [ + + ]: 133525 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
2095 : 75966 : enum nx_flow_monitor_flags flags = 0;
2096 : : struct ofmonitor *m;
2097 : :
2098 [ + + ]: 75966 : if (ofconn->monitor_paused) {
2099 : : /* Only send NXFME_DELETED notifications for flows that were added
2100 : : * before we paused. */
2101 [ + + ]: 11719 : if (event != NXFME_DELETED
2102 [ + + ]: 7168 : || rule->add_seqno > ofconn->monitor_paused) {
2103 : 9100 : continue;
2104 : : }
2105 : : }
2106 : :
2107 [ + + ][ - + ]: 72159 : HMAP_FOR_EACH (m, ofconn_node, &ofconn->monitors) {
2108 [ + - ]: 5293 : if (m->flags & update
2109 [ - + ][ # # ]: 5293 : && (m->table_id == 0xff || m->table_id == rule->table_id)
2110 [ + + ]: 5293 : && (ofproto_rule_has_out_port(rule, m->out_port)
2111 [ + - ]: 2 : || (old_actions
2112 [ + + ]: 2 : && ofpacts_output_to_port(old_actions->ofpacts,
2113 : 2 : old_actions->ofpacts_len,
2114 : : m->out_port)))
2115 [ + - ]: 5292 : && cls_rule_is_loose_match(&rule->cr, &m->match)) {
2116 : 5292 : flags |= m->flags;
2117 : : }
2118 : : }
2119 : :
2120 [ + + ]: 66866 : if (flags) {
2121 [ + + ]: 5292 : if (ovs_list_is_empty(&ofconn->updates)) {
2122 : 2655 : ofputil_start_flow_update(&ofconn->updates);
2123 : 2655 : ofconn->sent_abbrev_update = false;
2124 : : }
2125 : :
2126 [ + + ][ + + ]: 5292 : if (flags & NXFMF_OWN || ofconn != abbrev_ofconn
2127 [ - + ]: 5292 : || ofconn->monitor_paused) {
2128 : : struct ofputil_flow_update fu;
2129 : : struct match match;
2130 : :
2131 : 5289 : fu.event = event;
2132 [ + + ]: 5289 : fu.reason = event == NXFME_DELETED ? reason : 0;
2133 : 5289 : fu.table_id = rule->table_id;
2134 : 5289 : fu.cookie = rule->flow_cookie;
2135 : 5289 : minimatch_expand(&rule->cr.match, &match);
2136 : 5289 : fu.match = &match;
2137 : 5289 : fu.priority = rule->cr.priority;
2138 : :
2139 : 5289 : ovs_mutex_lock(&rule->mutex);
2140 : 5289 : fu.idle_timeout = rule->idle_timeout;
2141 : 5289 : fu.hard_timeout = rule->hard_timeout;
2142 : 5289 : ovs_mutex_unlock(&rule->mutex);
2143 : :
2144 [ + - ]: 5289 : if (flags & NXFMF_ACTIONS) {
2145 : 5289 : const struct rule_actions *actions = rule_get_actions(rule);
2146 : 5289 : fu.ofpacts = actions->ofpacts;
2147 : 5289 : fu.ofpacts_len = actions->ofpacts_len;
2148 : : } else {
2149 : 0 : fu.ofpacts = NULL;
2150 : 0 : fu.ofpacts_len = 0;
2151 : : }
2152 : 5289 : ofputil_append_flow_update(&fu, &ofconn->updates);
2153 [ + + ]: 3 : } else if (!ofconn->sent_abbrev_update) {
2154 : : struct ofputil_flow_update fu;
2155 : :
2156 : 1 : fu.event = NXFME_ABBREV;
2157 : 1 : fu.xid = abbrev_xid;
2158 : 1 : ofputil_append_flow_update(&fu, &ofconn->updates);
2159 : :
2160 : 1 : ofconn->sent_abbrev_update = true;
2161 : : }
2162 : : }
2163 : : }
2164 : : }
2165 : :
2166 : : void
2167 : 39931 : ofmonitor_flush(struct connmgr *mgr)
2168 : : OVS_REQUIRES(ofproto_mutex)
2169 : : {
2170 : : struct ofconn *ofconn;
2171 : :
2172 [ + + ]: 101211 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
2173 : : struct ofpbuf *msg;
2174 : :
2175 [ + + ]: 63936 : LIST_FOR_EACH_POP (msg, list_node, &ofconn->updates) {
2176 : : unsigned int n_bytes;
2177 : :
2178 : 2656 : ofconn_send(ofconn, msg, ofconn->monitor_counter);
2179 : 2656 : n_bytes = rconn_packet_counter_n_bytes(ofconn->monitor_counter);
2180 [ + + ][ + + ]: 2656 : if (!ofconn->monitor_paused && n_bytes > 128 * 1024) {
2181 : : struct ofpbuf *pause;
2182 : :
2183 : 1 : COVERAGE_INC(ofmonitor_pause);
2184 : 1 : ofconn->monitor_paused = monitor_seqno++;
2185 : 1 : pause = ofpraw_alloc_xid(OFPRAW_NXT_FLOW_MONITOR_PAUSED,
2186 : : OFP10_VERSION, htonl(0), 0);
2187 : 1 : ofconn_send(ofconn, pause, ofconn->monitor_counter);
2188 : : }
2189 : : }
2190 : : }
2191 : 39931 : }
2192 : :
2193 : : static void
2194 : 1 : ofmonitor_resume(struct ofconn *ofconn)
2195 : : OVS_REQUIRES(ofproto_mutex)
2196 : : {
2197 : : struct rule_collection rules;
2198 : : struct ofpbuf *resumed;
2199 : : struct ofmonitor *m;
2200 : : struct ovs_list msgs;
2201 : :
2202 : 1 : rule_collection_init(&rules);
2203 [ + + ][ - + ]: 2 : HMAP_FOR_EACH (m, ofconn_node, &ofconn->monitors) {
2204 : 1 : ofmonitor_collect_resume_rules(m, ofconn->monitor_paused, &rules);
2205 : : }
2206 : :
2207 : 1 : ovs_list_init(&msgs);
2208 : 1 : ofmonitor_compose_refresh_updates(&rules, &msgs);
2209 : :
2210 : 1 : resumed = ofpraw_alloc_xid(OFPRAW_NXT_FLOW_MONITOR_RESUMED, OFP10_VERSION,
2211 : : htonl(0), 0);
2212 : 1 : ovs_list_push_back(&msgs, &resumed->list_node);
2213 : 1 : ofconn_send_replies(ofconn, &msgs);
2214 : :
2215 : 1 : ofconn->monitor_paused = 0;
2216 : 1 : }
2217 : :
2218 : : static bool
2219 : 203892 : ofmonitor_may_resume(const struct ofconn *ofconn)
2220 : : OVS_REQUIRES(ofproto_mutex)
2221 : : {
2222 : 203892 : return (ofconn->monitor_paused != 0
2223 [ + + ][ + + ]: 203892 : && !rconn_packet_counter_n_packets(ofconn->monitor_counter));
2224 : : }
2225 : :
2226 : : static void
2227 : 157605 : ofmonitor_run(struct connmgr *mgr)
2228 : : {
2229 : : struct ofconn *ofconn;
2230 : :
2231 : 157605 : ovs_mutex_lock(&ofproto_mutex);
2232 [ + + ]: 258221 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
2233 [ + + ]: 100616 : if (ofmonitor_may_resume(ofconn)) {
2234 : 1 : COVERAGE_INC(ofmonitor_resume);
2235 : 1 : ofmonitor_resume(ofconn);
2236 : : }
2237 : : }
2238 : 157605 : ovs_mutex_unlock(&ofproto_mutex);
2239 : 157605 : }
2240 : :
2241 : : static void
2242 : 153645 : ofmonitor_wait(struct connmgr *mgr)
2243 : : {
2244 : : struct ofconn *ofconn;
2245 : :
2246 : 153645 : ovs_mutex_lock(&ofproto_mutex);
2247 [ + + ]: 256921 : LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
2248 [ - + ]: 103276 : if (ofmonitor_may_resume(ofconn)) {
2249 : 0 : poll_immediate_wake();
2250 : : }
2251 : : }
2252 : 153645 : ovs_mutex_unlock(&ofproto_mutex);
2253 : 153645 : }
2254 : :
2255 : : void
2256 : 1051 : ofproto_async_msg_free(struct ofproto_async_msg *am)
2257 : : {
2258 : 1051 : free(am->pin.up.public.packet);
2259 : 1051 : free(am->pin.up.public.userdata);
2260 : 1051 : free(am->pin.up.stack);
2261 : 1051 : free(am->pin.up.actions);
2262 : 1051 : free(am->pin.up.action_set);
2263 : 1051 : free(am);
2264 : 1051 : }
|