d10dcc65c1e48e2be2e958cfb6a0feefaaddec90
[cascardo/ovs.git] / ovn / controller / ofctrl.c
1 /* Copyright (c) 2015, 2016 Nicira, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <config.h>
17 #include "bitmap.h"
18 #include "byte-order.h"
19 #include "dirs.h"
20 #include "flow.h"
21 #include "hash.h"
22 #include "hindex.h"
23 #include "hmap.h"
24 #include "ofctrl.h"
25 #include "openflow/openflow.h"
26 #include "openvswitch/dynamic-string.h"
27 #include "openvswitch/list.h"
28 #include "openvswitch/match.h"
29 #include "openvswitch/ofp-actions.h"
30 #include "openvswitch/ofp-msgs.h"
31 #include "openvswitch/ofp-parse.h"
32 #include "openvswitch/ofp-print.h"
33 #include "openvswitch/ofp-util.h"
34 #include "openvswitch/ofpbuf.h"
35 #include "openvswitch/vlog.h"
36 #include "ovn-controller.h"
37 #include "ovn/lib/actions.h"
38 #include "physical.h"
39 #include "rconn.h"
40 #include "socket-util.h"
41 #include "util.h"
42 #include "vswitch-idl.h"
43
44 VLOG_DEFINE_THIS_MODULE(ofctrl);
45
46 /* An OpenFlow flow. */
47 struct ovn_flow {
48     struct hmap_node match_hmap_node; /* For match based hashing. */
49     struct hindex_node uuid_hindex_node; /* For uuid based hashing. */
50     struct ovs_list list_node; /* For handling lists of flows. */
51
52     /* Key. */
53     uint8_t table_id;
54     uint16_t priority;
55     struct match match;
56
57     /* Data. UUID is used for disambiguation. */
58     struct uuid uuid;
59     struct ofpact *ofpacts;
60     size_t ofpacts_len;
61 };
62
63 static uint32_t ovn_flow_match_hash(const struct ovn_flow *);
64 static void ovn_flow_lookup(struct hmap *, const struct ovn_flow *target,
65                             struct ovs_list *answers);
66 static char *ovn_flow_to_string(const struct ovn_flow *);
67 static void ovn_flow_log(const struct ovn_flow *, const char *action);
68 static void ovn_flow_destroy(struct ovn_flow *);
69
70 static ovs_be32 queue_msg(struct ofpbuf *);
71 static void queue_flow_mod(struct ofputil_flow_mod *);
72
73 /* OpenFlow connection to the switch. */
74 static struct rconn *swconn;
75
76 static void queue_group_mod(struct ofputil_group_mod *);
77
78 /* Last seen sequence number for 'swconn'.  When this differs from
79  * rconn_get_connection_seqno(rconn), 'swconn' has reconnected. */
80 static unsigned int seqno;
81
82 /* Connection state machine. */
83 #define STATES                                  \
84     STATE(S_NEW)                                \
85     STATE(S_TLV_TABLE_REQUESTED)                \
86     STATE(S_TLV_TABLE_MOD_SENT)                 \
87     STATE(S_CLEAR_FLOWS)                        \
88     STATE(S_UPDATE_FLOWS)
89 enum ofctrl_state {
90 #define STATE(NAME) NAME,
91     STATES
92 #undef STATE
93 };
94
95 /* Current state. */
96 static enum ofctrl_state state;
97
98 /* Transaction IDs for messages in flight to the switch. */
99 static ovs_be32 xid, xid2;
100
101 /* Counter for in-flight OpenFlow messages on 'swconn'.  We only send a new
102  * round of flow table modifications to the switch when the counter falls to
103  * zero, to avoid unbounded buffering. */
104 static struct rconn_packet_counter *tx_counter;
105
106 /* Flow table of "struct ovn_flow"s, that holds the flow table currently
107  * installed in the switch. */
108 static struct hmap installed_flows;
109
110 /* A reference to the group_table. */
111 static struct group_table *groups;
112
113 /* MFF_* field ID for our Geneve option.  In S_TLV_TABLE_MOD_SENT, this is
114  * the option we requested (we don't know whether we obtained it yet).  In
115  * S_CLEAR_FLOWS or S_UPDATE_FLOWS, this is really the option we have. */
116 static enum mf_field_id mff_ovn_geneve;
117
118 static void ovn_flow_table_destroy(void);
119
120 static void ovn_group_table_clear(struct group_table *group_table,
121                                   bool existing);
122
123 static void ofctrl_recv(const struct ofp_header *, enum ofptype);
124
125 static struct hmap match_flow_table = HMAP_INITIALIZER(&match_flow_table);
126 static struct hindex uuid_flow_table = HINDEX_INITIALIZER(&uuid_flow_table);
127
128 void
129 ofctrl_init(void)
130 {
131     swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION);
132     tx_counter = rconn_packet_counter_create();
133     hmap_init(&installed_flows);
134 }
135 \f
136 /* S_NEW, for a new connection.
137  *
138  * Sends NXT_TLV_TABLE_REQUEST and transitions to
139  * S_TLV_TABLE_REQUESTED. */
140
141 static void
142 run_S_NEW(void)
143 {
144     struct ofpbuf *buf = ofpraw_alloc(OFPRAW_NXT_TLV_TABLE_REQUEST,
145                                       rconn_get_version(swconn), 0);
146     xid = queue_msg(buf);
147     state = S_TLV_TABLE_REQUESTED;
148 }
149
150 static void
151 recv_S_NEW(const struct ofp_header *oh OVS_UNUSED,
152            enum ofptype type OVS_UNUSED)
153 {
154     OVS_NOT_REACHED();
155 }
156 \f
157 /* S_TLV_TABLE_REQUESTED, when NXT_TLV_TABLE_REQUEST has been sent
158  * and we're waiting for a reply.
159  *
160  * If we receive an NXT_TLV_TABLE_REPLY:
161  *
162  *     - If it contains our tunnel metadata option, assign its field ID to
163  *       mff_ovn_geneve and transition to S_CLEAR_FLOWS.
164  *
165  *     - Otherwise, if there is an unused tunnel metadata field ID, send
166  *       NXT_TLV_TABLE_MOD and OFPT_BARRIER_REQUEST, and transition to
167  *       S_TLV_TABLE_MOD_SENT.
168  *
169  *     - Otherwise, log an error, disable Geneve, and transition to
170  *       S_CLEAR_FLOWS.
171  *
172  * If we receive an OFPT_ERROR:
173  *
174  *     - Log an error, disable Geneve, and transition to S_CLEAR_FLOWS. */
175
176 static void
177 run_S_TLV_TABLE_REQUESTED(void)
178 {
179 }
180
181 static void
182 recv_S_TLV_TABLE_REQUESTED(const struct ofp_header *oh, enum ofptype type)
183 {
184     if (oh->xid != xid) {
185         ofctrl_recv(oh, type);
186     } else if (type == OFPTYPE_NXT_TLV_TABLE_REPLY) {
187         struct ofputil_tlv_table_reply reply;
188         enum ofperr error = ofputil_decode_tlv_table_reply(oh, &reply);
189         if (error) {
190             VLOG_ERR("failed to decode TLV table request (%s)",
191                      ofperr_to_string(error));
192             goto error;
193         }
194
195         const struct ofputil_tlv_map *map;
196         uint64_t md_free = UINT64_MAX;
197         BUILD_ASSERT(TUN_METADATA_NUM_OPTS == 64);
198
199         LIST_FOR_EACH (map, list_node, &reply.mappings) {
200             if (map->option_class == OVN_GENEVE_CLASS
201                 && map->option_type == OVN_GENEVE_TYPE
202                 && map->option_len == OVN_GENEVE_LEN) {
203                 if (map->index >= TUN_METADATA_NUM_OPTS) {
204                     VLOG_ERR("desired Geneve tunnel option 0x%"PRIx16","
205                              "%"PRIu8",%"PRIu8" already in use with "
206                              "unsupported index %"PRIu16,
207                              map->option_class, map->option_type,
208                              map->option_len, map->index);
209                     goto error;
210                 } else {
211                     mff_ovn_geneve = MFF_TUN_METADATA0 + map->index;
212                     state = S_CLEAR_FLOWS;
213                     return;
214                 }
215             }
216
217             if (map->index < TUN_METADATA_NUM_OPTS) {
218                 md_free &= ~(UINT64_C(1) << map->index);
219             }
220         }
221
222         VLOG_DBG("OVN Geneve option not found");
223         if (!md_free) {
224             VLOG_ERR("no Geneve options free for use by OVN");
225             goto error;
226         }
227
228         unsigned int index = rightmost_1bit_idx(md_free);
229         mff_ovn_geneve = MFF_TUN_METADATA0 + index;
230         struct ofputil_tlv_map tm;
231         tm.option_class = OVN_GENEVE_CLASS;
232         tm.option_type = OVN_GENEVE_TYPE;
233         tm.option_len = OVN_GENEVE_LEN;
234         tm.index = index;
235
236         struct ofputil_tlv_table_mod ttm;
237         ttm.command = NXTTMC_ADD;
238         ovs_list_init(&ttm.mappings);
239         ovs_list_push_back(&ttm.mappings, &tm.list_node);
240
241         xid = queue_msg(ofputil_encode_tlv_table_mod(OFP13_VERSION, &ttm));
242         xid2 = queue_msg(ofputil_encode_barrier_request(OFP13_VERSION));
243         state = S_TLV_TABLE_MOD_SENT;
244     } else if (type == OFPTYPE_ERROR) {
245         VLOG_ERR("switch refused to allocate Geneve option (%s)",
246                  ofperr_to_string(ofperr_decode_msg(oh, NULL)));
247         goto error;
248     } else {
249         char *s = ofp_to_string(oh, ntohs(oh->length), 1);
250         VLOG_ERR("unexpected reply to TLV table request (%s)",
251                  s);
252         free(s);
253         goto error;
254     }
255     return;
256
257 error:
258     mff_ovn_geneve = 0;
259     state = S_CLEAR_FLOWS;
260 }
261 \f
262 /* S_TLV_TABLE_MOD_SENT, when NXT_TLV_TABLE_MOD and OFPT_BARRIER_REQUEST
263  * have been sent and we're waiting for a reply to one or the other.
264  *
265  * If we receive an OFPT_ERROR:
266  *
267  *     - If the error is NXTTMFC_ALREADY_MAPPED or NXTTMFC_DUP_ENTRY, we
268  *       raced with some other controller.  Transition to S_NEW.
269  *
270  *     - Otherwise, log an error, disable Geneve, and transition to
271  *       S_CLEAR_FLOWS.
272  *
273  * If we receive OFPT_BARRIER_REPLY:
274  *
275  *     - Set the tunnel metadata field ID to the one that we requested.
276  *       Transition to S_CLEAR_FLOWS.
277  */
278
279 static void
280 run_S_TLV_TABLE_MOD_SENT(void)
281 {
282 }
283
284 static void
285 recv_S_TLV_TABLE_MOD_SENT(const struct ofp_header *oh, enum ofptype type)
286 {
287     if (oh->xid != xid && oh->xid != xid2) {
288         ofctrl_recv(oh, type);
289     } else if (oh->xid == xid2 && type == OFPTYPE_BARRIER_REPLY) {
290         state = S_CLEAR_FLOWS;
291     } else if (oh->xid == xid && type == OFPTYPE_ERROR) {
292         enum ofperr error = ofperr_decode_msg(oh, NULL);
293         if (error == OFPERR_NXTTMFC_ALREADY_MAPPED ||
294             error == OFPERR_NXTTMFC_DUP_ENTRY) {
295             VLOG_INFO("raced with another controller adding "
296                       "Geneve option (%s); trying again",
297                       ofperr_to_string(error));
298             state = S_NEW;
299         } else {
300             VLOG_ERR("error adding Geneve option (%s)",
301                      ofperr_to_string(error));
302             goto error;
303         }
304     } else {
305         char *s = ofp_to_string(oh, ntohs(oh->length), 1);
306         VLOG_ERR("unexpected reply to Geneve option allocation request (%s)",
307                  s);
308         free(s);
309         goto error;
310     }
311     return;
312
313 error:
314     state = S_CLEAR_FLOWS;
315 }
316 \f
317 /* S_CLEAR_FLOWS, after we've established a Geneve metadata field ID and it's
318  * time to set up some flows.
319  *
320  * Sends an OFPT_TABLE_MOD to clear all flows, then transitions to
321  * S_UPDATE_FLOWS. */
322
323 static void
324 run_S_CLEAR_FLOWS(void)
325 {
326     /* Send a flow_mod to delete all flows. */
327     struct ofputil_flow_mod fm = {
328         .match = MATCH_CATCHALL_INITIALIZER,
329         .table_id = OFPTT_ALL,
330         .command = OFPFC_DELETE,
331     };
332     queue_flow_mod(&fm);
333     VLOG_DBG("clearing all flows");
334
335     struct ofputil_group_mod gm;
336     memset(&gm, 0, sizeof gm);
337     gm.command = OFPGC11_DELETE;
338     gm.group_id = OFPG_ALL;
339     gm.command_bucket_id = OFPG15_BUCKET_ALL;
340     ovs_list_init(&gm.buckets);
341     queue_group_mod(&gm);
342     ofputil_bucket_list_destroy(&gm.buckets);
343
344     /* Clear installed_flows, to match the state of the switch. */
345     ovn_flow_table_clear();
346
347     /* Clear existing groups, to match the state of the switch. */
348     if (groups) {
349         ovn_group_table_clear(groups, true);
350     }
351
352     state = S_UPDATE_FLOWS;
353 }
354
355 static void
356 recv_S_CLEAR_FLOWS(const struct ofp_header *oh, enum ofptype type)
357 {
358     ofctrl_recv(oh, type);
359 }
360 \f
361 /* S_UPDATE_FLOWS, for maintaining the flow table over time.
362  *
363  * Compare the installed flows to the ones we want.  Send OFPT_FLOW_MOD as
364  * necessary.
365  *
366  * This is a terminal state.  We only transition out of it if the connection
367  * drops. */
368
369 static void
370 run_S_UPDATE_FLOWS(void)
371 {
372     /* Nothing to do here.
373      *
374      * Being in this state enables ofctrl_put() to work, however. */
375 }
376
377 static void
378 recv_S_UPDATE_FLOWS(const struct ofp_header *oh, enum ofptype type)
379 {
380     ofctrl_recv(oh, type);
381 }
382 \f
383 /* Runs the OpenFlow state machine against 'br_int', which is local to the
384  * hypervisor on which we are running.  Attempts to negotiate a Geneve option
385  * field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE.  If successful,
386  * returns the MFF_* field ID for the option, otherwise returns 0. */
387 enum mf_field_id
388 ofctrl_run(const struct ovsrec_bridge *br_int)
389 {
390     if (br_int) {
391         char *target;
392         target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
393         if (strcmp(target, rconn_get_target(swconn))) {
394             VLOG_INFO("%s: connecting to switch", target);
395             rconn_connect(swconn, target, target);
396         }
397         free(target);
398     } else {
399         rconn_disconnect(swconn);
400     }
401
402     rconn_run(swconn);
403
404     if (!rconn_is_connected(swconn)) {
405         return 0;
406     }
407     if (seqno != rconn_get_connection_seqno(swconn)) {
408         seqno = rconn_get_connection_seqno(swconn);
409         state = S_NEW;
410     }
411
412     enum ofctrl_state old_state;
413     do {
414         old_state = state;
415         switch (state) {
416 #define STATE(NAME) case NAME: run_##NAME(); break;
417             STATES
418 #undef STATE
419         default:
420             OVS_NOT_REACHED();
421         }
422     } while (state != old_state);
423
424     for (int i = 0; state == old_state && i < 50; i++) {
425         struct ofpbuf *msg = rconn_recv(swconn);
426         if (!msg) {
427             break;
428         }
429
430         const struct ofp_header *oh = msg->data;
431         enum ofptype type;
432         enum ofperr error;
433
434         error = ofptype_decode(&type, oh);
435         if (!error) {
436             switch (state) {
437 #define STATE(NAME) case NAME: recv_##NAME(oh, type); break;
438                 STATES
439 #undef STATE
440             default:
441                 OVS_NOT_REACHED();
442             }
443         } else {
444             char *s = ofp_to_string(oh, ntohs(oh->length), 1);
445             VLOG_WARN("could not decode OpenFlow message (%s): %s",
446                       ofperr_to_string(error), s);
447             free(s);
448         }
449
450         ofpbuf_delete(msg);
451     }
452
453     return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS
454             ? mff_ovn_geneve : 0);
455 }
456
457 void
458 ofctrl_wait(void)
459 {
460     rconn_run_wait(swconn);
461     rconn_recv_wait(swconn);
462 }
463
464 void
465 ofctrl_destroy(void)
466 {
467     rconn_destroy(swconn);
468     ovn_flow_table_destroy();
469     rconn_packet_counter_destroy(tx_counter);
470 }
471 \f
472 static ovs_be32
473 queue_msg(struct ofpbuf *msg)
474 {
475     const struct ofp_header *oh = msg->data;
476     ovs_be32 xid = oh->xid;
477     rconn_send(swconn, msg, tx_counter);
478     return xid;
479 }
480
481 static void
482 log_openflow_rl(struct vlog_rate_limit *rl, enum vlog_level level,
483                 const struct ofp_header *oh, const char *title)
484 {
485     if (!vlog_should_drop(&this_module, level, rl)) {
486         char *s = ofp_to_string(oh, ntohs(oh->length), 2);
487         vlog(&this_module, level, "%s: %s", title, s);
488         free(s);
489     }
490 }
491
492 static void
493 ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
494 {
495     if (type == OFPTYPE_ECHO_REQUEST) {
496         queue_msg(make_echo_reply(oh));
497     } else if (type == OFPTYPE_ERROR) {
498         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
499         log_openflow_rl(&rl, VLL_INFO, oh, "OpenFlow error");
500     } else if (type != OFPTYPE_ECHO_REPLY &&
501                type != OFPTYPE_BARRIER_REPLY &&
502                type != OFPTYPE_PACKET_IN &&
503                type != OFPTYPE_PORT_STATUS &&
504                type != OFPTYPE_FLOW_REMOVED) {
505         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
506         log_openflow_rl(&rl, VLL_DBG, oh, "OpenFlow packet ignored");
507     }
508 }
509 \f
510 /* Flow table interfaces to the rest of ovn-controller. */
511
512 /* Adds a flow to the collection associated with 'uuid'.  The flow has the
513  * specified 'match' and 'actions' to the OpenFlow table numbered 'table_id'
514  * with the given 'priority'.  The caller retains ownership of 'match' and
515  * 'actions'.
516  *
517  * Any number of flows may be associated with a given UUID.  The flows with a
518  * given UUID must have a unique (table_id, priority, match) tuple.  A
519  * duplicate within a generally indicates a bug in the ovn-controller code that
520  * generated it, so this functions logs a warning.
521  *
522  * (table_id, priority, match) tuples should also be unique for flows with
523  * different UUIDs, but it doesn't necessarily indicate a bug in
524  * ovn-controller, for two reasons.  First, these duplicates could be caused by
525  * logical flows generated by ovn-northd, which aren't ovn-controller's fault;
526  * perhaps something should warn about these but the root cause is different.
527  * Second, these duplicates might be transient, that is, they might go away
528  * before the next call to ofctrl_run() if a call to ofctrl_remove_flows()
529  * removes one or the other.
530  *
531  * This just assembles the desired flow tables in memory.  Nothing is actually
532  * sent to the switch until a later call to ofctrl_run(). */
533 void
534 ofctrl_add_flow(uint8_t table_id, uint16_t priority,
535                 const struct match *match, const struct ofpbuf *actions,
536                 const struct uuid *uuid)
537 {
538     /* Structure that uses table_id+priority+various things as hashes. */
539     struct ovn_flow *f = xmalloc(sizeof *f);
540     f->table_id = table_id;
541     f->priority = priority;
542     f->match = *match;
543     f->ofpacts = xmemdup(actions->data, actions->size);
544     f->ofpacts_len = actions->size;
545     f->uuid = *uuid;
546     f->match_hmap_node.hash = ovn_flow_match_hash(f);
547     f->uuid_hindex_node.hash = uuid_hash(&f->uuid);
548
549     /* Check to see if other flows exist with the same key (table_id priority,
550      * match criteria) and uuid.  If so, discard this flow and log a
551      * warning. */
552     struct ovs_list existing;
553     ovn_flow_lookup(&match_flow_table, f, &existing);
554     struct ovn_flow *d;
555     LIST_FOR_EACH (d, list_node, &existing) {
556         if (uuid_equals(&f->uuid, &d->uuid)) {
557             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
558             char *s = ovn_flow_to_string(f);
559             VLOG_WARN_RL(&rl, "found duplicate flow %s for parent "UUID_FMT,
560                          s, UUID_ARGS(&f->uuid));
561             ovn_flow_destroy(f);
562             free(s);
563             return;
564         }
565     }
566
567     /* Otherwise, add the flow. */
568     hmap_insert(&match_flow_table, &f->match_hmap_node,
569                 f->match_hmap_node.hash);
570     hindex_insert(&uuid_flow_table, &f->uuid_hindex_node,
571                 f->uuid_hindex_node.hash);
572 }
573
574 /* Removes a bundles of flows from the flow table. */
575 void
576 ofctrl_remove_flows(const struct uuid *uuid)
577 {
578     struct ovn_flow *f, *next;
579     HINDEX_FOR_EACH_WITH_HASH_SAFE (f, next, uuid_hindex_node, uuid_hash(uuid),
580                                     &uuid_flow_table) {
581         if (uuid_equals(&f->uuid, uuid)) {
582             hmap_remove(&match_flow_table, &f->match_hmap_node);
583             hindex_remove(&uuid_flow_table, &f->uuid_hindex_node);
584             ovn_flow_destroy(f);
585         }
586     }
587 }
588
589 /* Shortcut to remove all flows matching the supplied UUID and add this
590  * flow. */
591 void
592 ofctrl_set_flow(uint8_t table_id, uint16_t priority,
593                 const struct match *match, const struct ofpbuf *actions,
594                 const struct uuid *uuid)
595 {
596     ofctrl_remove_flows(uuid);
597     ofctrl_add_flow(table_id, priority, match, actions, uuid);
598 }
599 \f
600 /* ovn_flow. */
601
602 /* Duplicate an ovn_flow structure. */
603 struct ovn_flow *
604 ofctrl_dup_flow(struct ovn_flow *src)
605 {
606     struct ovn_flow *dst = xmalloc(sizeof *dst);
607     dst->table_id = src->table_id;
608     dst->priority = src->priority;
609     dst->match = src->match;
610     dst->ofpacts = xmemdup(src->ofpacts, src->ofpacts_len);
611     dst->ofpacts_len = src->ofpacts_len;
612     dst->uuid = src->uuid;
613     dst->match_hmap_node.hash = ovn_flow_match_hash(dst);
614     dst->uuid_hindex_node.hash = uuid_hash(&src->uuid);
615     return dst;
616 }
617
618 /* Returns a hash of the match key in 'f'. */
619 static uint32_t
620 ovn_flow_match_hash(const struct ovn_flow *f)
621 {
622     return hash_2words((f->table_id << 16) | f->priority,
623                        match_hash(&f->match, 0));
624 }
625
626 /* Compare two flows and return -1, 0, 1 based on whether a if less than,
627  * equal to or greater than b. */
628 static int
629 ovn_flow_compare_flows(struct ovn_flow *a, struct ovn_flow *b)
630 {
631     return uuid_compare_3way(&a->uuid, &b->uuid);
632 }
633
634 /* Given a list of ovn_flows, goes through the list and returns
635  * a single flow, in a deterministic way. */
636 static struct ovn_flow *
637 ovn_flow_select_from_list(struct ovs_list *flows)
638 {
639     struct ovn_flow *candidate;
640     struct ovn_flow *answer = NULL;
641     LIST_FOR_EACH (candidate, list_node, flows) {
642         if (!answer || ovn_flow_compare_flows(candidate, answer) < 0) {
643             answer = candidate;
644         }
645     }
646     return answer;
647 }
648
649 /* Initializes and files in the supplied list with ovn_flows from 'flow_table'
650  * whose key is identical to 'target''s key. */
651 static void
652 ovn_flow_lookup(struct hmap *flow_table, const struct ovn_flow *target,
653                 struct ovs_list *answer)
654 {
655     struct ovn_flow *f;
656
657     ovs_list_init(answer);
658     HMAP_FOR_EACH_WITH_HASH (f, match_hmap_node, target->match_hmap_node.hash,
659                              flow_table) {
660         if (f->table_id == target->table_id
661             && f->priority == target->priority
662             && match_equal(&f->match, &target->match)) {
663             ovs_list_push_back(answer, &f->list_node);
664         }
665     }
666 }
667
668 static char *
669 ovn_flow_to_string(const struct ovn_flow *f)
670 {
671     struct ds s = DS_EMPTY_INITIALIZER;
672     ds_put_format(&s, "table_id=%"PRIu8", ", f->table_id);
673     ds_put_format(&s, "priority=%"PRIu16", ", f->priority);
674     match_format(&f->match, &s, OFP_DEFAULT_PRIORITY);
675     ds_put_cstr(&s, ", actions=");
676     ofpacts_format(f->ofpacts, f->ofpacts_len, &s);
677     return ds_steal_cstr(&s);
678 }
679
680 static void
681 ovn_flow_log(const struct ovn_flow *f, const char *action)
682 {
683     if (VLOG_IS_DBG_ENABLED()) {
684         char *s = ovn_flow_to_string(f);
685         VLOG_DBG("%s flow: %s", action, s);
686         free(s);
687     }
688 }
689
690 static void
691 ovn_flow_destroy(struct ovn_flow *f)
692 {
693     if (f) {
694         free(f->ofpacts);
695         free(f);
696     }
697 }
698 \f
699 /* Flow tables of struct ovn_flow. */
700
701 void
702 ovn_flow_table_clear(void)
703 {
704     struct ovn_flow *f, *next;
705     HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, &match_flow_table) {
706         hmap_remove(&match_flow_table, &f->match_hmap_node);
707         hindex_remove(&uuid_flow_table, &f->uuid_hindex_node);
708         ovn_flow_destroy(f);
709     }
710 }
711
712 static void
713 ovn_flow_table_destroy(void)
714 {
715     ovn_flow_table_clear();
716     hmap_destroy(&match_flow_table);
717     hindex_destroy(&uuid_flow_table);
718 }
719 \f
720 /* Flow table update. */
721
722 static void
723 queue_flow_mod(struct ofputil_flow_mod *fm)
724 {
725     fm->buffer_id = UINT32_MAX;
726     fm->out_port = OFPP_ANY;
727     fm->out_group = OFPG_ANY;
728     queue_msg(ofputil_encode_flow_mod(fm, OFPUTIL_P_OF13_OXM));
729 }
730
731 \f
732 /* group_table. */
733
734 /* Finds and returns a group_info in 'existing_groups' whose key is identical
735  * to 'target''s key, or NULL if there is none. */
736 static struct group_info *
737 ovn_group_lookup(struct hmap *exisiting_groups,
738                  const struct group_info *target)
739 {
740     struct group_info *e;
741
742     HMAP_FOR_EACH_WITH_HASH(e, hmap_node, target->hmap_node.hash,
743                             exisiting_groups) {
744         if (e->group_id == target->group_id) {
745             return e;
746         }
747    }
748     return NULL;
749 }
750
751 /* Clear either desired_groups or existing_groups in group_table. */
752 static void
753 ovn_group_table_clear(struct group_table *group_table, bool existing)
754 {
755     struct group_info *g, *next;
756     struct hmap *target_group = existing
757                                 ? &group_table->existing_groups
758                                 : &group_table->desired_groups;
759
760     HMAP_FOR_EACH_SAFE (g, next, hmap_node, target_group) {
761         hmap_remove(target_group, &g->hmap_node);
762         bitmap_set0(group_table->group_ids, g->group_id);
763         ds_destroy(&g->group);
764         free(g);
765     }
766 }
767
768 static void
769 queue_group_mod(struct ofputil_group_mod *gm)
770 {
771     queue_msg(ofputil_encode_group_mod(OFP13_VERSION, gm));
772 }
773 \f
774
775 /* Replaces the flow table on the switch, if possible, by the flows in added
776  * with ofctrl_add_flow().
777  *
778  * Replaces the group table on the switch, if possible, by the groups in
779  * 'group_table->desired_groups'. Regardless of whether the group table
780  * is updated, this deletes all the groups from the
781  * 'group_table->desired_groups' and frees them. (The hmap itself isn't
782  * destroyed.)
783  *
784  * This should be called after ofctrl_run() within the main loop. */
785 void
786 ofctrl_put(struct group_table *group_table)
787 {
788     if (!groups) {
789         groups = group_table;
790     }
791
792     /* The flow table can be updated if the connection to the switch is up and
793      * in the correct state and not backlogged with existing flow_mods.  (Our
794      * criteria for being backlogged appear very conservative, but the socket
795      * between ovn-controller and OVS provides some buffering.) */
796     if (state != S_UPDATE_FLOWS
797         || rconn_packet_counter_n_packets(tx_counter)) {
798         ovn_group_table_clear(group_table, false);
799         return;
800     }
801
802     /* Iterate through all the desired groups. If there are new ones,
803      * add them to the switch. */
804     struct group_info *desired;
805     HMAP_FOR_EACH(desired, hmap_node, &group_table->desired_groups) {
806         if (!ovn_group_lookup(&group_table->existing_groups, desired)) {
807             /* Create and install new group. */
808             struct ofputil_group_mod gm;
809             enum ofputil_protocol usable_protocols;
810             char *error;
811             struct ds group_string = DS_EMPTY_INITIALIZER;
812             ds_put_format(&group_string, "group_id=%u,%s",
813                           desired->group_id, ds_cstr(&desired->group));
814
815             error = parse_ofp_group_mod_str(&gm, OFPGC11_ADD,
816                                             ds_cstr(&group_string),
817                                             &usable_protocols);
818             if (!error) {
819                 queue_group_mod(&gm);
820             } else {
821                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
822                 VLOG_ERR_RL(&rl, "new group %s %s", error,
823                          ds_cstr(&group_string));
824                 free(error);
825             }
826             ds_destroy(&group_string);
827             ofputil_bucket_list_destroy(&gm.buckets);
828         }
829     }
830
831     /* Iterate through all of the installed flows.  If any of them are no
832      * longer desired, delete them; if any of them should have different
833      * actions, update them. */
834     struct ovn_flow *i, *next;
835     HMAP_FOR_EACH_SAFE (i, next, match_hmap_node, &installed_flows) {
836         struct ovs_list matches;
837         ovn_flow_lookup(&match_flow_table, i, &matches);
838         if (ovs_list_is_empty(&matches)) {
839             /* Installed flow is no longer desirable.  Delete it from the
840              * switch and from installed_flows. */
841             struct ofputil_flow_mod fm = {
842                 .match = i->match,
843                 .priority = i->priority,
844                 .table_id = i->table_id,
845                 .command = OFPFC_DELETE_STRICT,
846             };
847             queue_flow_mod(&fm);
848             ovn_flow_log(i, "removing installed");
849
850             hmap_remove(&installed_flows, &i->match_hmap_node);
851             ovn_flow_destroy(i);
852         } else {
853             /* Since we still have desired flows that match this key,
854              * select one and compare both its actions and uuid.
855              * If the actions aren't the same, queue and update
856              * action for the install flow.  If the uuid has changed
857              * update that as well. */
858             struct ovn_flow *d = ovn_flow_select_from_list(&matches);
859             if (!uuid_equals(&i->uuid, &d->uuid)) {
860                 /* Update installed flow's UUID. */
861                 i->uuid = d->uuid;
862             }
863             if (!ofpacts_equal(i->ofpacts, i->ofpacts_len,
864                                d->ofpacts, d->ofpacts_len)) {
865                 /* Update actions in installed flow. */
866                 struct ofputil_flow_mod fm = {
867                     .match = i->match,
868                     .priority = i->priority,
869                     .table_id = i->table_id,
870                     .ofpacts = d->ofpacts,
871                     .ofpacts_len = d->ofpacts_len,
872                     .command = OFPFC_MODIFY_STRICT,
873                 };
874                 queue_flow_mod(&fm);
875                 ovn_flow_log(i, "updating installed");
876
877                 /* Replace 'i''s actions by 'd''s. */
878                 free(i->ofpacts);
879                 i->ofpacts = xmemdup(d->ofpacts, d->ofpacts_len);
880                 i->ofpacts_len = d->ofpacts_len;
881             }
882         }
883     }
884
885     /* Iterate through the desired flows and add those that aren't found
886      * in the installed flow table. */
887     struct ovn_flow *c;
888     HMAP_FOR_EACH (c, match_hmap_node, &match_flow_table) {
889         struct ovs_list matches;
890         ovn_flow_lookup(&installed_flows, c, &matches);
891         if (ovs_list_is_empty(&matches)) {
892             /* We have a key that isn't in the installed flows, so
893              * look back into the desired flow list for all flows
894              * that match this key, and select the one to be installed. */
895             struct ovs_list candidates;
896             ovn_flow_lookup(&match_flow_table, c, &candidates);
897             struct ovn_flow *d = ovn_flow_select_from_list(&candidates);
898             /* Send flow_mod to add flow. */
899             struct ofputil_flow_mod fm = {
900                 .match = d->match,
901                 .priority = d->priority,
902                 .table_id = d->table_id,
903                 .ofpacts = d->ofpacts,
904                 .ofpacts_len = d->ofpacts_len,
905                 .command = OFPFC_ADD,
906             };
907             queue_flow_mod(&fm);
908             ovn_flow_log(d, "adding installed");
909
910             /* Copy 'd' from 'flow_table' to installed_flows. */
911             struct ovn_flow *new_node = ofctrl_dup_flow(d);
912             hmap_insert(&installed_flows, &new_node->match_hmap_node,
913                         new_node->match_hmap_node.hash);
914         }
915     }
916
917     /* Iterate through the installed groups from previous runs. If they
918      * are not needed delete them. */
919     struct group_info *installed, *next_group;
920     HMAP_FOR_EACH_SAFE(installed, next_group, hmap_node,
921                        &group_table->existing_groups) {
922         if (!ovn_group_lookup(&group_table->desired_groups, installed)) {
923             /* Delete the group. */
924             struct ofputil_group_mod gm;
925             enum ofputil_protocol usable_protocols;
926             char *error;
927             struct ds group_string = DS_EMPTY_INITIALIZER;
928             ds_put_format(&group_string, "group_id=%u", installed->group_id);
929
930             error = parse_ofp_group_mod_str(&gm, OFPGC11_DELETE,
931                                             ds_cstr(&group_string),
932                                             &usable_protocols);
933             if (!error) {
934                 queue_group_mod(&gm);
935             } else {
936                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
937                 VLOG_ERR_RL(&rl, "Error deleting group %d: %s",
938                          installed->group_id, error);
939                 free(error);
940             }
941             ds_destroy(&group_string);
942             ofputil_bucket_list_destroy(&gm.buckets);
943
944             /* Remove 'installed' from 'group_table->existing_groups' */
945             hmap_remove(&group_table->existing_groups, &installed->hmap_node);
946             ds_destroy(&installed->group);
947
948             /* Dealloc group_id. */
949             bitmap_set0(group_table->group_ids, installed->group_id);
950             free(installed);
951         }
952     }
953
954     /* Move the contents of desired_groups to existing_groups. */
955     HMAP_FOR_EACH_SAFE(desired, next_group, hmap_node,
956                        &group_table->desired_groups) {
957         hmap_remove(&group_table->desired_groups, &desired->hmap_node);
958         if (!ovn_group_lookup(&group_table->existing_groups, desired)) {
959             hmap_insert(&group_table->existing_groups, &desired->hmap_node,
960                         desired->hmap_node.hash);
961         } else {
962             ds_destroy(&desired->group);
963             free(desired);
964         }
965     }
966 }