userspace: Define and use struct eth_addr.
[cascardo/ovs.git] / ovn / northd / ovn-northd.c
1 /*
2  * Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at:
5  *
6  *     http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14
15 #include <config.h>
16
17 #include <getopt.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20
21 #include "command-line.h"
22 #include "daemon.h"
23 #include "dirs.h"
24 #include "dynamic-string.h"
25 #include "fatal-signal.h"
26 #include "hash.h"
27 #include "hmap.h"
28 #include "json.h"
29 #include "ovn/lib/lex.h"
30 #include "ovn/lib/ovn-nb-idl.h"
31 #include "ovn/lib/ovn-sb-idl.h"
32 #include "poll-loop.h"
33 #include "smap.h"
34 #include "stream.h"
35 #include "stream-ssl.h"
36 #include "unixctl.h"
37 #include "util.h"
38 #include "uuid.h"
39 #include "openvswitch/vlog.h"
40
41 VLOG_DEFINE_THIS_MODULE(ovn_northd);
42
43 static unixctl_cb_func ovn_northd_exit;
44
45 struct northd_context {
46     struct ovsdb_idl *ovnnb_idl;
47     struct ovsdb_idl *ovnsb_idl;
48     struct ovsdb_idl_txn *ovnnb_txn;
49     struct ovsdb_idl_txn *ovnsb_txn;
50 };
51
52 static const char *ovnnb_db;
53 static const char *ovnsb_db;
54
55 static const char *default_db(void);
56
57
58 /* Ingress pipeline stages.
59  *
60  * These must be listed in the order that the stages will be executed. */
61 #define INGRESS_STAGES                         \
62     INGRESS_STAGE(PORT_SEC, port_sec)          \
63     INGRESS_STAGE(L2_LKUP, l2_lkup)
64
65 enum ingress_stage {
66 #define INGRESS_STAGE(NAME, STR) S_IN_##NAME,
67     INGRESS_STAGES
68 #undef INGRESS_STAGE
69     INGRESS_N_STAGES
70 };
71
72 /* Egress pipeline stages.
73  *
74  * These must be listed in the order that the stages will be executed. */
75 #define EGRESS_STAGES                         \
76     EGRESS_STAGE(ACL, acl)                    \
77     EGRESS_STAGE(PORT_SEC, port_sec)
78
79 enum egress_stage {
80 #define EGRESS_STAGE(NAME, STR) S_OUT_##NAME,
81     EGRESS_STAGES
82 #undef EGRESS_STAGE
83     EGRESS_N_STAGES
84 };
85
86 static void
87 usage(void)
88 {
89     printf("\
90 %s: OVN northbound management daemon\n\
91 usage: %s [OPTIONS]\n\
92 \n\
93 Options:\n\
94   --ovnnb-db=DATABASE       connect to ovn-nb database at DATABASE\n\
95                             (default: %s)\n\
96   --ovnsb-db=DATABASE       connect to ovn-sb database at DATABASE\n\
97                             (default: %s)\n\
98   -h, --help                display this help message\n\
99   -o, --options             list available options\n\
100   -V, --version             display version information\n\
101 ", program_name, program_name, default_db(), default_db());
102     daemon_usage();
103     vlog_usage();
104     stream_usage("database", true, true, false);
105 }
106 \f
107 struct tnlid_node {
108     struct hmap_node hmap_node;
109     uint32_t tnlid;
110 };
111
112 static void
113 destroy_tnlids(struct hmap *tnlids)
114 {
115     struct tnlid_node *node, *next;
116     HMAP_FOR_EACH_SAFE (node, next, hmap_node, tnlids) {
117         hmap_remove(tnlids, &node->hmap_node);
118         free(node);
119     }
120     hmap_destroy(tnlids);
121 }
122
123 static void
124 add_tnlid(struct hmap *set, uint32_t tnlid)
125 {
126     struct tnlid_node *node = xmalloc(sizeof *node);
127     hmap_insert(set, &node->hmap_node, hash_int(tnlid, 0));
128     node->tnlid = tnlid;
129 }
130
131 static bool
132 tnlid_in_use(const struct hmap *set, uint32_t tnlid)
133 {
134     const struct tnlid_node *node;
135     HMAP_FOR_EACH_IN_BUCKET (node, hmap_node, hash_int(tnlid, 0), set) {
136         if (node->tnlid == tnlid) {
137             return true;
138         }
139     }
140     return false;
141 }
142
143 static uint32_t
144 allocate_tnlid(struct hmap *set, const char *name, uint32_t max,
145                uint32_t *hint)
146 {
147     for (uint32_t tnlid = *hint + 1; tnlid != *hint;
148          tnlid = tnlid + 1 <= max ? tnlid + 1 : 1) {
149         if (!tnlid_in_use(set, tnlid)) {
150             add_tnlid(set, tnlid);
151             *hint = tnlid;
152             return tnlid;
153         }
154     }
155
156     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
157     VLOG_WARN_RL(&rl, "all %s tunnel ids exhausted", name);
158     return 0;
159 }
160 \f
161 /* The 'key' comes from nb->header_.uuid or sb->external_ids:logical-switch. */
162 struct ovn_datapath {
163     struct hmap_node key_node;  /* Index on 'key'. */
164     struct uuid key;            /* nb->header_.uuid. */
165
166     const struct nbrec_logical_switch *nb;   /* May be NULL. */
167     const struct sbrec_datapath_binding *sb; /* May be NULL. */
168
169     struct ovs_list list;       /* In list of similar records. */
170
171     struct hmap port_tnlids;
172     uint32_t port_key_hint;
173
174     bool has_unknown;
175 };
176
177 static struct ovn_datapath *
178 ovn_datapath_create(struct hmap *datapaths, const struct uuid *key,
179                     const struct nbrec_logical_switch *nb,
180                     const struct sbrec_datapath_binding *sb)
181 {
182     struct ovn_datapath *od = xzalloc(sizeof *od);
183     od->key = *key;
184     od->sb = sb;
185     od->nb = nb;
186     hmap_init(&od->port_tnlids);
187     od->port_key_hint = 0;
188     hmap_insert(datapaths, &od->key_node, uuid_hash(&od->key));
189     return od;
190 }
191
192 static void
193 ovn_datapath_destroy(struct hmap *datapaths, struct ovn_datapath *od)
194 {
195     if (od) {
196         /* Don't remove od->list.  It is used within build_datapaths() as a
197          * private list and once we've exited that function it is not safe to
198          * use it. */
199         hmap_remove(datapaths, &od->key_node);
200         destroy_tnlids(&od->port_tnlids);
201         free(od);
202     }
203 }
204
205 static struct ovn_datapath *
206 ovn_datapath_find(struct hmap *datapaths, const struct uuid *uuid)
207 {
208     struct ovn_datapath *od;
209
210     HMAP_FOR_EACH_WITH_HASH (od, key_node, uuid_hash(uuid), datapaths) {
211         if (uuid_equals(uuid, &od->key)) {
212             return od;
213         }
214     }
215     return NULL;
216 }
217
218 static struct ovn_datapath *
219 ovn_datapath_from_sbrec(struct hmap *datapaths,
220                         const struct sbrec_datapath_binding *sb)
221 {
222     struct uuid key;
223
224     if (!smap_get_uuid(&sb->external_ids, "logical-switch", &key)) {
225         return NULL;
226     }
227     return ovn_datapath_find(datapaths, &key);
228 }
229
230 static void
231 join_datapaths(struct northd_context *ctx, struct hmap *datapaths,
232                struct ovs_list *sb_only, struct ovs_list *nb_only,
233                struct ovs_list *both)
234 {
235     hmap_init(datapaths);
236     list_init(sb_only);
237     list_init(nb_only);
238     list_init(both);
239
240     const struct sbrec_datapath_binding *sb, *sb_next;
241     SBREC_DATAPATH_BINDING_FOR_EACH_SAFE (sb, sb_next, ctx->ovnsb_idl) {
242         struct uuid key;
243         if (!smap_get_uuid(&sb->external_ids, "logical-switch", &key)) {
244             ovsdb_idl_txn_add_comment(ctx->ovnsb_txn,
245                                       "deleting Datapath_Binding "UUID_FMT" that "
246                                       "lacks external-ids:logical-switch",
247                          UUID_ARGS(&sb->header_.uuid));
248             sbrec_datapath_binding_delete(sb);
249             continue;
250         }
251
252         if (ovn_datapath_find(datapaths, &key)) {
253             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
254             VLOG_INFO_RL(&rl, "deleting Datapath_Binding "UUID_FMT" with "
255                          "duplicate external-ids:logical-switch "UUID_FMT,
256                          UUID_ARGS(&sb->header_.uuid), UUID_ARGS(&key));
257             sbrec_datapath_binding_delete(sb);
258             continue;
259         }
260
261         struct ovn_datapath *od = ovn_datapath_create(datapaths, &key,
262                                                       NULL, sb);
263         list_push_back(sb_only, &od->list);
264     }
265
266     const struct nbrec_logical_switch *nb;
267     NBREC_LOGICAL_SWITCH_FOR_EACH (nb, ctx->ovnnb_idl) {
268         struct ovn_datapath *od = ovn_datapath_find(datapaths,
269                                                     &nb->header_.uuid);
270         if (od) {
271             od->nb = nb;
272             list_remove(&od->list);
273             list_push_back(both, &od->list);
274         } else {
275             od = ovn_datapath_create(datapaths, &nb->header_.uuid, nb, NULL);
276             list_push_back(nb_only, &od->list);
277         }
278     }
279 }
280
281 static uint32_t
282 ovn_datapath_allocate_key(struct hmap *dp_tnlids)
283 {
284     static uint32_t hint;
285     return allocate_tnlid(dp_tnlids, "datapath", (1u << 24) - 1, &hint);
286 }
287
288 static void
289 build_datapaths(struct northd_context *ctx, struct hmap *datapaths)
290 {
291     struct ovs_list sb_only, nb_only, both;
292
293     join_datapaths(ctx, datapaths, &sb_only, &nb_only, &both);
294
295     if (!list_is_empty(&nb_only)) {
296         /* First index the in-use datapath tunnel IDs. */
297         struct hmap dp_tnlids = HMAP_INITIALIZER(&dp_tnlids);
298         struct ovn_datapath *od;
299         LIST_FOR_EACH (od, list, &both) {
300             add_tnlid(&dp_tnlids, od->sb->tunnel_key);
301         }
302
303         /* Add southbound record for each unmatched northbound record. */
304         LIST_FOR_EACH (od, list, &nb_only) {
305             uint16_t tunnel_key = ovn_datapath_allocate_key(&dp_tnlids);
306             if (!tunnel_key) {
307                 break;
308             }
309
310             od->sb = sbrec_datapath_binding_insert(ctx->ovnsb_txn);
311
312             struct smap external_ids = SMAP_INITIALIZER(&external_ids);
313             char uuid_s[UUID_LEN + 1];
314             sprintf(uuid_s, UUID_FMT, UUID_ARGS(&od->nb->header_.uuid));
315             smap_add(&external_ids, "logical-switch", uuid_s);
316             sbrec_datapath_binding_set_external_ids(od->sb, &external_ids);
317             smap_destroy(&external_ids);
318
319             sbrec_datapath_binding_set_tunnel_key(od->sb, tunnel_key);
320         }
321         destroy_tnlids(&dp_tnlids);
322     }
323
324     /* Delete southbound records without northbound matches. */
325     struct ovn_datapath *od, *next;
326     LIST_FOR_EACH_SAFE (od, next, list, &sb_only) {
327         list_remove(&od->list);
328         sbrec_datapath_binding_delete(od->sb);
329         ovn_datapath_destroy(datapaths, od);
330     }
331 }
332 \f
333 struct ovn_port {
334     struct hmap_node key_node;  /* Index on 'key'. */
335     const char *key;            /* nb->name and sb->logical_port */
336
337     const struct nbrec_logical_port *nb; /* May be NULL. */
338     const struct sbrec_port_binding *sb; /* May be NULL. */
339
340     struct ovn_datapath *od;
341
342     struct ovs_list list;       /* In list of similar records. */
343 };
344
345 static struct ovn_port *
346 ovn_port_create(struct hmap *ports, const char *key,
347                 const struct nbrec_logical_port *nb,
348                 const struct sbrec_port_binding *sb)
349 {
350     struct ovn_port *op = xzalloc(sizeof *op);
351     op->key = key;
352     op->sb = sb;
353     op->nb = nb;
354     hmap_insert(ports, &op->key_node, hash_string(op->key, 0));
355     return op;
356 }
357
358 static void
359 ovn_port_destroy(struct hmap *ports, struct ovn_port *port)
360 {
361     if (port) {
362         /* Don't remove port->list.  It is used within build_ports() as a
363          * private list and once we've exited that function it is not safe to
364          * use it. */
365         hmap_remove(ports, &port->key_node);
366         free(port);
367     }
368 }
369
370 static struct ovn_port *
371 ovn_port_find(struct hmap *ports, const char *name)
372 {
373     struct ovn_port *op;
374
375     HMAP_FOR_EACH_WITH_HASH (op, key_node, hash_string(name, 0), ports) {
376         if (!strcmp(op->key, name)) {
377             return op;
378         }
379     }
380     return NULL;
381 }
382
383 static uint32_t
384 ovn_port_allocate_key(struct ovn_datapath *od)
385 {
386     return allocate_tnlid(&od->port_tnlids, "port",
387                           (1u << 15) - 1, &od->port_key_hint);
388 }
389
390 static void
391 join_logical_ports(struct northd_context *ctx,
392                    struct hmap *datapaths, struct hmap *ports,
393                    struct ovs_list *sb_only, struct ovs_list *nb_only,
394                    struct ovs_list *both)
395 {
396     hmap_init(ports);
397     list_init(sb_only);
398     list_init(nb_only);
399     list_init(both);
400
401     const struct sbrec_port_binding *sb;
402     SBREC_PORT_BINDING_FOR_EACH (sb, ctx->ovnsb_idl) {
403         struct ovn_port *op = ovn_port_create(ports, sb->logical_port,
404                                               NULL, sb);
405         list_push_back(sb_only, &op->list);
406     }
407
408     struct ovn_datapath *od;
409     HMAP_FOR_EACH (od, key_node, datapaths) {
410         for (size_t i = 0; i < od->nb->n_ports; i++) {
411             const struct nbrec_logical_port *nb = od->nb->ports[i];
412             struct ovn_port *op = ovn_port_find(ports, nb->name);
413             if (op) {
414                 op->nb = nb;
415                 list_remove(&op->list);
416                 list_push_back(both, &op->list);
417             } else {
418                 op = ovn_port_create(ports, nb->name, nb, NULL);
419                 list_push_back(nb_only, &op->list);
420             }
421             op->od = od;
422         }
423     }
424 }
425
426 static void
427 ovn_port_update_sbrec(const struct ovn_port *op)
428 {
429     sbrec_port_binding_set_type(op->sb, op->nb->type);
430     sbrec_port_binding_set_options(op->sb, &op->nb->options);
431     sbrec_port_binding_set_datapath(op->sb, op->od->sb);
432     sbrec_port_binding_set_parent_port(op->sb, op->nb->parent_name);
433     sbrec_port_binding_set_tag(op->sb, op->nb->tag, op->nb->n_tag);
434     sbrec_port_binding_set_mac(op->sb, (const char **) op->nb->macs,
435                                op->nb->n_macs);
436 }
437
438 static void
439 build_ports(struct northd_context *ctx, struct hmap *datapaths,
440             struct hmap *ports)
441 {
442     struct ovs_list sb_only, nb_only, both;
443
444     join_logical_ports(ctx, datapaths, ports, &sb_only, &nb_only, &both);
445
446     /* For logical ports that are in both databases, update the southbound
447      * record based on northbound data.  Also index the in-use tunnel_keys. */
448     struct ovn_port *op, *next;
449     LIST_FOR_EACH_SAFE (op, next, list, &both) {
450         ovn_port_update_sbrec(op);
451
452         add_tnlid(&op->od->port_tnlids, op->sb->tunnel_key);
453         if (op->sb->tunnel_key > op->od->port_key_hint) {
454             op->od->port_key_hint = op->sb->tunnel_key;
455         }
456     }
457
458     /* Add southbound record for each unmatched northbound record. */
459     LIST_FOR_EACH_SAFE (op, next, list, &nb_only) {
460         uint16_t tunnel_key = ovn_port_allocate_key(op->od);
461         if (!tunnel_key) {
462             continue;
463         }
464
465         op->sb = sbrec_port_binding_insert(ctx->ovnsb_txn);
466         ovn_port_update_sbrec(op);
467
468         sbrec_port_binding_set_logical_port(op->sb, op->key);
469         sbrec_port_binding_set_tunnel_key(op->sb, tunnel_key);
470     }
471
472     /* Delete southbound records without northbound matches. */
473     LIST_FOR_EACH_SAFE(op, next, list, &sb_only) {
474         list_remove(&op->list);
475         sbrec_port_binding_delete(op->sb);
476         ovn_port_destroy(ports, op);
477     }
478 }
479 \f
480 #define OVN_MIN_MULTICAST 32768
481 #define OVN_MAX_MULTICAST 65535
482
483 struct multicast_group {
484     const char *name;
485     uint16_t key;               /* OVN_MIN_MULTICAST...OVN_MAX_MULTICAST. */
486 };
487
488 #define MC_FLOOD "_MC_flood"
489 static const struct multicast_group mc_flood = { MC_FLOOD, 65535 };
490
491 #define MC_UNKNOWN "_MC_unknown"
492 static const struct multicast_group mc_unknown = { MC_UNKNOWN, 65534 };
493
494 static bool
495 multicast_group_equal(const struct multicast_group *a,
496                       const struct multicast_group *b)
497 {
498     return !strcmp(a->name, b->name) && a->key == b->key;
499 }
500
501 /* Multicast group entry. */
502 struct ovn_multicast {
503     struct hmap_node hmap_node; /* Index on 'datapath' and 'key'. */
504     struct ovn_datapath *datapath;
505     const struct multicast_group *group;
506
507     struct ovn_port **ports;
508     size_t n_ports, allocated_ports;
509 };
510
511 static uint32_t
512 ovn_multicast_hash(const struct ovn_datapath *datapath,
513                    const struct multicast_group *group)
514 {
515     return hash_pointer(datapath, group->key);
516 }
517
518 static struct ovn_multicast *
519 ovn_multicast_find(struct hmap *mcgroups, struct ovn_datapath *datapath,
520                    const struct multicast_group *group)
521 {
522     struct ovn_multicast *mc;
523
524     HMAP_FOR_EACH_WITH_HASH (mc, hmap_node,
525                              ovn_multicast_hash(datapath, group), mcgroups) {
526         if (mc->datapath == datapath
527             && multicast_group_equal(mc->group, group)) {
528             return mc;
529         }
530     }
531     return NULL;
532 }
533
534 static void
535 ovn_multicast_add(struct hmap *mcgroups, const struct multicast_group *group,
536                   struct ovn_port *port)
537 {
538     struct ovn_datapath *od = port->od;
539     struct ovn_multicast *mc = ovn_multicast_find(mcgroups, od, group);
540     if (!mc) {
541         mc = xmalloc(sizeof *mc);
542         hmap_insert(mcgroups, &mc->hmap_node, ovn_multicast_hash(od, group));
543         mc->datapath = od;
544         mc->group = group;
545         mc->n_ports = 0;
546         mc->allocated_ports = 4;
547         mc->ports = xmalloc(mc->allocated_ports * sizeof *mc->ports);
548     }
549     if (mc->n_ports >= mc->allocated_ports) {
550         mc->ports = x2nrealloc(mc->ports, &mc->allocated_ports,
551                                sizeof *mc->ports);
552     }
553     mc->ports[mc->n_ports++] = port;
554 }
555
556 static void
557 ovn_multicast_destroy(struct hmap *mcgroups, struct ovn_multicast *mc)
558 {
559     if (mc) {
560         hmap_remove(mcgroups, &mc->hmap_node);
561         free(mc->ports);
562         free(mc);
563     }
564 }
565
566 static void
567 ovn_multicast_update_sbrec(const struct ovn_multicast *mc,
568                            const struct sbrec_multicast_group *sb)
569 {
570     struct sbrec_port_binding **ports = xmalloc(mc->n_ports * sizeof *ports);
571     for (size_t i = 0; i < mc->n_ports; i++) {
572         ports[i] = CONST_CAST(struct sbrec_port_binding *, mc->ports[i]->sb);
573     }
574     sbrec_multicast_group_set_ports(sb, ports, mc->n_ports);
575     free(ports);
576 }
577 \f
578 /* Logical flow generation.
579  *
580  * This code generates the Logical_Flow table in the southbound database, as a
581  * function of most of the northbound database.
582  */
583
584 struct ovn_lflow {
585     struct hmap_node hmap_node;
586
587     struct ovn_datapath *od;
588     enum ovn_pipeline { P_IN, P_OUT } pipeline;
589     uint8_t table_id;
590     uint16_t priority;
591     char *match;
592     char *actions;
593 };
594
595 static size_t
596 ovn_lflow_hash(const struct ovn_lflow *lflow)
597 {
598     size_t hash = uuid_hash(&lflow->od->key);
599     hash = hash_2words((lflow->table_id << 16) | lflow->priority, hash);
600     hash = hash_string(lflow->match, hash);
601     return hash_string(lflow->actions, hash);
602 }
603
604 static bool
605 ovn_lflow_equal(const struct ovn_lflow *a, const struct ovn_lflow *b)
606 {
607     return (a->od == b->od
608             && a->pipeline == b->pipeline
609             && a->table_id == b->table_id
610             && a->priority == b->priority
611             && !strcmp(a->match, b->match)
612             && !strcmp(a->actions, b->actions));
613 }
614
615 static void
616 ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od,
617               enum ovn_pipeline pipeline, uint8_t table_id, uint16_t priority,
618               char *match, char *actions)
619 {
620     lflow->od = od;
621     lflow->pipeline = pipeline;
622     lflow->table_id = table_id;
623     lflow->priority = priority;
624     lflow->match = match;
625     lflow->actions = actions;
626 }
627
628 static const char *
629 ingress_stage_to_str(int stage) {
630     switch (stage) {
631 #define INGRESS_STAGE(NAME, STR) case S_IN_##NAME: return #STR;
632     INGRESS_STAGES
633 #undef INGRESS_STAGE
634         default: return "<unknown>";
635     }
636 }
637
638 static const char *
639 egress_stage_to_str(int stage) {
640     switch (stage) {
641 #define EGRESS_STAGE(NAME, STR) case S_OUT_##NAME: return #STR;
642     EGRESS_STAGES
643 #undef EGRESS_STAGE
644         default: return "<unknown>";
645     }
646 }
647
648 /* Adds a row with the specified contents to the Logical_Flow table. */
649 static void
650 ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od,
651               enum ovn_pipeline pipeline, uint8_t table_id, uint16_t priority,
652               const char *match, const char *actions)
653 {
654     struct ovn_lflow *lflow = xmalloc(sizeof *lflow);
655     ovn_lflow_init(lflow, od, pipeline, table_id, priority,
656                    xstrdup(match), xstrdup(actions));
657     hmap_insert(lflow_map, &lflow->hmap_node, ovn_lflow_hash(lflow));
658 }
659
660 static struct ovn_lflow *
661 ovn_lflow_find(struct hmap *lflows, struct ovn_datapath *od,
662                enum ovn_pipeline pipeline, uint8_t table_id, uint16_t priority,
663                const char *match, const char *actions)
664 {
665     struct ovn_lflow target;
666     ovn_lflow_init(&target, od, pipeline, table_id, priority,
667                    CONST_CAST(char *, match), CONST_CAST(char *, actions));
668
669     struct ovn_lflow *lflow;
670     HMAP_FOR_EACH_WITH_HASH (lflow, hmap_node, ovn_lflow_hash(&target),
671                              lflows) {
672         if (ovn_lflow_equal(lflow, &target)) {
673             return lflow;
674         }
675     }
676     return NULL;
677 }
678
679 static void
680 ovn_lflow_destroy(struct hmap *lflows, struct ovn_lflow *lflow)
681 {
682     if (lflow) {
683         hmap_remove(lflows, &lflow->hmap_node);
684         free(lflow->match);
685         free(lflow->actions);
686         free(lflow);
687     }
688 }
689
690 /* Appends port security constraints on L2 address field 'eth_addr_field'
691  * (e.g. "eth.src" or "eth.dst") to 'match'.  'port_security', with
692  * 'n_port_security' elements, is the collection of port_security constraints
693  * from an OVN_NB Logical_Port row. */
694 static void
695 build_port_security(const char *eth_addr_field,
696                     char **port_security, size_t n_port_security,
697                     struct ds *match)
698 {
699     size_t base_len = match->length;
700     ds_put_format(match, " && %s == {", eth_addr_field);
701
702     size_t n = 0;
703     for (size_t i = 0; i < n_port_security; i++) {
704         struct eth_addr ea;
705
706         if (eth_addr_from_string(port_security[i], &ea)) {
707             ds_put_format(match, ETH_ADDR_FMT, ETH_ADDR_ARGS(ea));
708             ds_put_char(match, ' ');
709             n++;
710         }
711     }
712     ds_chomp(match, ' ');
713     ds_put_cstr(match, "}");
714
715     if (!n) {
716         match->length = base_len;
717     }
718 }
719
720 static bool
721 lport_is_enabled(const struct nbrec_logical_port *lport)
722 {
723     return !lport->enabled || *lport->enabled;
724 }
725
726 /* Updates the Logical_Flow and Multicast_Group tables in the OVN_SB database,
727  * constructing their contents based on the OVN_NB database. */
728 static void
729 build_lflows(struct northd_context *ctx, struct hmap *datapaths,
730              struct hmap *ports)
731 {
732     struct hmap lflows = HMAP_INITIALIZER(&lflows);
733     struct hmap mcgroups = HMAP_INITIALIZER(&mcgroups);
734
735     /* Ingress table 0: Admission control framework (priorities 0 and 100). */
736     struct ovn_datapath *od;
737     HMAP_FOR_EACH (od, key_node, datapaths) {
738         /* Logical VLANs not supported. */
739         ovn_lflow_add(&lflows, od, P_IN, S_IN_PORT_SEC, 100, "vlan.present",
740                       "drop;");
741
742         /* Broadcast/multicast source address is invalid. */
743         ovn_lflow_add(&lflows, od, P_IN, S_IN_PORT_SEC, 100, "eth.src[40]",
744                       "drop;");
745
746         /* Port security flows have priority 50 (see below) and will continue
747          * to the next table if packet source is acceptable. */
748
749         /* Otherwise drop the packet. */
750         ovn_lflow_add(&lflows, od, P_IN, S_IN_PORT_SEC, 0, "1", "drop;");
751     }
752
753     /* Ingress table 0: Ingress port security (priority 50). */
754     struct ovn_port *op;
755     HMAP_FOR_EACH (op, key_node, ports) {
756         struct ds match = DS_EMPTY_INITIALIZER;
757         ds_put_cstr(&match, "inport == ");
758         json_string_escape(op->key, &match);
759         build_port_security("eth.src",
760                             op->nb->port_security, op->nb->n_port_security,
761                             &match);
762         ovn_lflow_add(&lflows, op->od, P_IN, S_IN_PORT_SEC, 50, ds_cstr(&match),
763                       lport_is_enabled(op->nb) ? "next;" : "drop;");
764         ds_destroy(&match);
765     }
766
767     /* Ingress table 1: Destination lookup, broadcast and multicast handling
768      * (priority 100). */
769     HMAP_FOR_EACH (op, key_node, ports) {
770         if (lport_is_enabled(op->nb)) {
771             ovn_multicast_add(&mcgroups, &mc_flood, op);
772         }
773     }
774     HMAP_FOR_EACH (od, key_node, datapaths) {
775         ovn_lflow_add(&lflows, od, P_IN, S_IN_L2_LKUP, 100, "eth.dst[40]",
776                       "outport = \""MC_FLOOD"\"; output;");
777     }
778
779     /* Ingress table 1: Destination lookup, unicast handling (priority 50), */
780     HMAP_FOR_EACH (op, key_node, ports) {
781         for (size_t i = 0; i < op->nb->n_macs; i++) {
782             struct eth_addr mac;
783
784             if (eth_addr_from_string(op->nb->macs[i], &mac)) {
785                 struct ds match, actions;
786
787                 ds_init(&match);
788                 ds_put_format(&match, "eth.dst == %s", op->nb->macs[i]);
789
790                 ds_init(&actions);
791                 ds_put_cstr(&actions, "outport = ");
792                 json_string_escape(op->nb->name, &actions);
793                 ds_put_cstr(&actions, "; output;");
794                 ovn_lflow_add(&lflows, op->od, P_IN, S_IN_L2_LKUP, 50,
795                               ds_cstr(&match), ds_cstr(&actions));
796                 ds_destroy(&actions);
797                 ds_destroy(&match);
798             } else if (!strcmp(op->nb->macs[i], "unknown")) {
799                 ovn_multicast_add(&mcgroups, &mc_unknown, op);
800                 op->od->has_unknown = true;
801             } else {
802                 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
803
804                 VLOG_INFO_RL(&rl, "%s: invalid syntax '%s' in macs column",
805                              op->nb->name, op->nb->macs[i]);
806             }
807         }
808     }
809
810     /* Ingress table 1: Destination lookup for unknown MACs (priority 0). */
811     HMAP_FOR_EACH (od, key_node, datapaths) {
812         if (od->has_unknown) {
813             ovn_lflow_add(&lflows, od, P_IN, S_IN_L2_LKUP, 0, "1",
814                           "outport = \""MC_UNKNOWN"\"; output;");
815         }
816     }
817
818     /* Egress table 0: ACLs (any priority). */
819     HMAP_FOR_EACH (od, key_node, datapaths) {
820         for (size_t i = 0; i < od->nb->n_acls; i++) {
821             const struct nbrec_acl *acl = od->nb->acls[i];
822             const char *action;
823
824             action = (!strcmp(acl->action, "allow") ||
825                       !strcmp(acl->action, "allow-related"))
826                 ? "next;" : "drop;";
827             ovn_lflow_add(&lflows, od, P_OUT, S_OUT_ACL, acl->priority,
828                           acl->match, action);
829         }
830     }
831     HMAP_FOR_EACH (od, key_node, datapaths) {
832         ovn_lflow_add(&lflows, od, P_OUT, S_OUT_ACL, 0, "1", "next;");
833     }
834
835     /* Egress table 1: Egress port security multicast/broadcast (priority
836      * 100). */
837     HMAP_FOR_EACH (od, key_node, datapaths) {
838         ovn_lflow_add(&lflows, od, P_OUT, S_OUT_PORT_SEC, 100, "eth.dst[40]",
839                       "output;");
840     }
841
842     /* Egress table 1: Egress port security (priority 50). */
843     HMAP_FOR_EACH (op, key_node, ports) {
844         struct ds match;
845
846         ds_init(&match);
847         ds_put_cstr(&match, "outport == ");
848         json_string_escape(op->key, &match);
849         build_port_security("eth.dst",
850                             op->nb->port_security, op->nb->n_port_security,
851                             &match);
852
853         ovn_lflow_add(&lflows, op->od, P_OUT, S_OUT_PORT_SEC, 50,
854                       ds_cstr(&match),
855                       lport_is_enabled(op->nb) ? "output;" : "drop;");
856
857         ds_destroy(&match);
858     }
859
860     /* Push changes to the Logical_Flow table to database. */
861     const struct sbrec_logical_flow *sbflow, *next_sbflow;
862     SBREC_LOGICAL_FLOW_FOR_EACH_SAFE (sbflow, next_sbflow, ctx->ovnsb_idl) {
863         struct ovn_datapath *od
864             = ovn_datapath_from_sbrec(datapaths, sbflow->logical_datapath);
865         if (!od) {
866             sbrec_logical_flow_delete(sbflow);
867             continue;
868         }
869
870         struct ovn_lflow *lflow = ovn_lflow_find(
871             &lflows, od, (!strcmp(sbflow->pipeline, "ingress") ? P_IN : P_OUT),
872             sbflow->table_id, sbflow->priority,
873             sbflow->match, sbflow->actions);
874         if (lflow) {
875             ovn_lflow_destroy(&lflows, lflow);
876         } else {
877             sbrec_logical_flow_delete(sbflow);
878         }
879     }
880     struct ovn_lflow *lflow, *next_lflow;
881     HMAP_FOR_EACH_SAFE (lflow, next_lflow, hmap_node, &lflows) {
882         sbflow = sbrec_logical_flow_insert(ctx->ovnsb_txn);
883         sbrec_logical_flow_set_logical_datapath(sbflow, lflow->od->sb);
884         sbrec_logical_flow_set_pipeline(
885             sbflow, lflow->pipeline == P_IN ? "ingress" : "egress");
886         sbrec_logical_flow_set_table_id(sbflow, lflow->table_id);
887         sbrec_logical_flow_set_priority(sbflow, lflow->priority);
888         sbrec_logical_flow_set_match(sbflow, lflow->match);
889         sbrec_logical_flow_set_actions(sbflow, lflow->actions);
890
891         struct smap external_ids = SMAP_INITIALIZER(&external_ids);
892         smap_add(&external_ids, "stage-name",
893                  lflow->pipeline == P_IN ?
894                   ingress_stage_to_str(lflow->table_id) :
895                   egress_stage_to_str(lflow->table_id));
896         sbrec_logical_flow_set_external_ids(sbflow, &external_ids);
897         smap_destroy(&external_ids);
898
899         ovn_lflow_destroy(&lflows, lflow);
900     }
901     hmap_destroy(&lflows);
902
903     /* Push changes to the Multicast_Group table to database. */
904     const struct sbrec_multicast_group *sbmc, *next_sbmc;
905     SBREC_MULTICAST_GROUP_FOR_EACH_SAFE (sbmc, next_sbmc, ctx->ovnsb_idl) {
906         struct ovn_datapath *od = ovn_datapath_from_sbrec(datapaths,
907                                                           sbmc->datapath);
908         if (!od) {
909             sbrec_multicast_group_delete(sbmc);
910             continue;
911         }
912
913         struct multicast_group group = { .name = sbmc->name,
914                                          .key = sbmc->tunnel_key };
915         struct ovn_multicast *mc = ovn_multicast_find(&mcgroups, od, &group);
916         if (mc) {
917             ovn_multicast_update_sbrec(mc, sbmc);
918             ovn_multicast_destroy(&mcgroups, mc);
919         } else {
920             sbrec_multicast_group_delete(sbmc);
921         }
922     }
923     struct ovn_multicast *mc, *next_mc;
924     HMAP_FOR_EACH_SAFE (mc, next_mc, hmap_node, &mcgroups) {
925         sbmc = sbrec_multicast_group_insert(ctx->ovnsb_txn);
926         sbrec_multicast_group_set_datapath(sbmc, mc->datapath->sb);
927         sbrec_multicast_group_set_name(sbmc, mc->group->name);
928         sbrec_multicast_group_set_tunnel_key(sbmc, mc->group->key);
929         ovn_multicast_update_sbrec(mc, sbmc);
930         ovn_multicast_destroy(&mcgroups, mc);
931     }
932     hmap_destroy(&mcgroups);
933 }
934 \f
935 static void
936 ovnnb_db_changed(struct northd_context *ctx)
937 {
938     VLOG_DBG("ovn-nb db contents have changed.");
939
940     struct hmap datapaths, ports;
941     build_datapaths(ctx, &datapaths);
942     build_ports(ctx, &datapaths, &ports);
943     build_lflows(ctx, &datapaths, &ports);
944
945     struct ovn_datapath *dp, *next_dp;
946     HMAP_FOR_EACH_SAFE (dp, next_dp, key_node, &datapaths) {
947         ovn_datapath_destroy(&datapaths, dp);
948     }
949     hmap_destroy(&datapaths);
950
951     struct ovn_port *port, *next_port;
952     HMAP_FOR_EACH_SAFE (port, next_port, key_node, &ports) {
953         ovn_port_destroy(&ports, port);
954     }
955     hmap_destroy(&ports);
956 }
957
958 /*
959  * The only change we get notified about is if the 'chassis' column of the
960  * 'Port_Binding' table changes.  When this column is not empty, it means we
961  * need to set the corresponding logical port as 'up' in the northbound DB.
962  */
963 static void
964 ovnsb_db_changed(struct northd_context *ctx)
965 {
966     struct hmap lports_hmap;
967     const struct sbrec_port_binding *sb;
968     const struct nbrec_logical_port *nb;
969
970     struct lport_hash_node {
971         struct hmap_node node;
972         const struct nbrec_logical_port *nb;
973     } *hash_node, *hash_node_next;
974
975     VLOG_DBG("Recalculating port up states for ovn-nb db.");
976
977     hmap_init(&lports_hmap);
978
979     NBREC_LOGICAL_PORT_FOR_EACH(nb, ctx->ovnnb_idl) {
980         hash_node = xzalloc(sizeof *hash_node);
981         hash_node->nb = nb;
982         hmap_insert(&lports_hmap, &hash_node->node, hash_string(nb->name, 0));
983     }
984
985     SBREC_PORT_BINDING_FOR_EACH(sb, ctx->ovnsb_idl) {
986         nb = NULL;
987         HMAP_FOR_EACH_WITH_HASH(hash_node, node,
988                                 hash_string(sb->logical_port, 0),
989                                 &lports_hmap) {
990             if (!strcmp(sb->logical_port, hash_node->nb->name)) {
991                 nb = hash_node->nb;
992                 break;
993             }
994         }
995
996         if (!nb) {
997             /* The logical port doesn't exist for this port binding.  This can
998              * happen under normal circumstances when ovn-northd hasn't gotten
999              * around to pruning the Port_Binding yet. */
1000             continue;
1001         }
1002
1003         if (sb->chassis && (!nb->up || !*nb->up)) {
1004             bool up = true;
1005             nbrec_logical_port_set_up(nb, &up, 1);
1006         } else if (!sb->chassis && (!nb->up || *nb->up)) {
1007             bool up = false;
1008             nbrec_logical_port_set_up(nb, &up, 1);
1009         }
1010     }
1011
1012     HMAP_FOR_EACH_SAFE(hash_node, hash_node_next, node, &lports_hmap) {
1013         hmap_remove(&lports_hmap, &hash_node->node);
1014         free(hash_node);
1015     }
1016     hmap_destroy(&lports_hmap);
1017 }
1018 \f
1019
1020 static char *default_db_;
1021
1022 static const char *
1023 default_db(void)
1024 {
1025     if (!default_db_) {
1026         default_db_ = xasprintf("unix:%s/db.sock", ovs_rundir());
1027     }
1028     return default_db_;
1029 }
1030
1031 static void
1032 parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1033 {
1034     enum {
1035         DAEMON_OPTION_ENUMS,
1036         VLOG_OPTION_ENUMS,
1037     };
1038     static const struct option long_options[] = {
1039         {"ovnsb-db", required_argument, NULL, 'd'},
1040         {"ovnnb-db", required_argument, NULL, 'D'},
1041         {"help", no_argument, NULL, 'h'},
1042         {"options", no_argument, NULL, 'o'},
1043         {"version", no_argument, NULL, 'V'},
1044         DAEMON_LONG_OPTIONS,
1045         VLOG_LONG_OPTIONS,
1046         STREAM_SSL_LONG_OPTIONS,
1047         {NULL, 0, NULL, 0},
1048     };
1049     char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
1050
1051     for (;;) {
1052         int c;
1053
1054         c = getopt_long(argc, argv, short_options, long_options, NULL);
1055         if (c == -1) {
1056             break;
1057         }
1058
1059         switch (c) {
1060         DAEMON_OPTION_HANDLERS;
1061         VLOG_OPTION_HANDLERS;
1062         STREAM_SSL_OPTION_HANDLERS;
1063
1064         case 'd':
1065             ovnsb_db = optarg;
1066             break;
1067
1068         case 'D':
1069             ovnnb_db = optarg;
1070             break;
1071
1072         case 'h':
1073             usage();
1074             exit(EXIT_SUCCESS);
1075
1076         case 'o':
1077             ovs_cmdl_print_options(long_options);
1078             exit(EXIT_SUCCESS);
1079
1080         case 'V':
1081             ovs_print_version(0, 0);
1082             exit(EXIT_SUCCESS);
1083
1084         default:
1085             break;
1086         }
1087     }
1088
1089     if (!ovnsb_db) {
1090         ovnsb_db = default_db();
1091     }
1092
1093     if (!ovnnb_db) {
1094         ovnnb_db = default_db();
1095     }
1096
1097     free(short_options);
1098 }
1099
1100 static void
1101 add_column_noalert(struct ovsdb_idl *idl,
1102                    const struct ovsdb_idl_column *column)
1103 {
1104     ovsdb_idl_add_column(idl, column);
1105     ovsdb_idl_omit_alert(idl, column);
1106 }
1107
1108 int
1109 main(int argc, char *argv[])
1110 {
1111     extern struct vlog_module VLM_reconnect;
1112     struct ovsdb_idl *ovnnb_idl, *ovnsb_idl;
1113     unsigned int ovnnb_seqno, ovn_seqno;
1114     int res = EXIT_SUCCESS;
1115     struct northd_context ctx = {
1116         .ovnsb_txn = NULL,
1117     };
1118     bool ovnnb_changes_pending = false;
1119     bool ovn_changes_pending = false;
1120     struct unixctl_server *unixctl;
1121     int retval;
1122     bool exiting;
1123
1124     fatal_ignore_sigpipe();
1125     set_program_name(argv[0]);
1126     service_start(&argc, &argv);
1127     vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
1128     vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN);
1129     parse_options(argc, argv);
1130
1131     daemonize_start();
1132
1133     retval = unixctl_server_create(NULL, &unixctl);
1134     if (retval) {
1135         exit(EXIT_FAILURE);
1136     }
1137     unixctl_command_register("exit", "", 0, 0, ovn_northd_exit, &exiting);
1138
1139     daemonize_complete();
1140
1141     nbrec_init();
1142     sbrec_init();
1143
1144     /* We want to detect all changes to the ovn-nb db. */
1145     ctx.ovnnb_idl = ovnnb_idl = ovsdb_idl_create(ovnnb_db,
1146             &nbrec_idl_class, true, true);
1147
1148     ctx.ovnsb_idl = ovnsb_idl = ovsdb_idl_create(ovnsb_db,
1149             &sbrec_idl_class, false, true);
1150
1151     ovsdb_idl_add_table(ovnsb_idl, &sbrec_table_logical_flow);
1152     add_column_noalert(ovnsb_idl, &sbrec_logical_flow_col_logical_datapath);
1153     add_column_noalert(ovnsb_idl, &sbrec_logical_flow_col_pipeline);
1154     add_column_noalert(ovnsb_idl, &sbrec_logical_flow_col_table_id);
1155     add_column_noalert(ovnsb_idl, &sbrec_logical_flow_col_priority);
1156     add_column_noalert(ovnsb_idl, &sbrec_logical_flow_col_match);
1157     add_column_noalert(ovnsb_idl, &sbrec_logical_flow_col_actions);
1158
1159     ovsdb_idl_add_table(ovnsb_idl, &sbrec_table_multicast_group);
1160     add_column_noalert(ovnsb_idl, &sbrec_multicast_group_col_datapath);
1161     add_column_noalert(ovnsb_idl, &sbrec_multicast_group_col_tunnel_key);
1162     add_column_noalert(ovnsb_idl, &sbrec_multicast_group_col_name);
1163     add_column_noalert(ovnsb_idl, &sbrec_multicast_group_col_ports);
1164
1165     ovsdb_idl_add_table(ovnsb_idl, &sbrec_table_datapath_binding);
1166     add_column_noalert(ovnsb_idl, &sbrec_datapath_binding_col_tunnel_key);
1167     add_column_noalert(ovnsb_idl, &sbrec_datapath_binding_col_external_ids);
1168
1169     ovsdb_idl_add_table(ovnsb_idl, &sbrec_table_port_binding);
1170     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_datapath);
1171     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_logical_port);
1172     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_tunnel_key);
1173     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_parent_port);
1174     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_tag);
1175     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_type);
1176     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_options);
1177     add_column_noalert(ovnsb_idl, &sbrec_port_binding_col_mac);
1178     ovsdb_idl_add_column(ovnsb_idl, &sbrec_port_binding_col_chassis);
1179
1180     /*
1181      * The loop here just runs the IDL in a loop waiting for the seqno to
1182      * change, which indicates that the contents of the db have changed.
1183      *
1184      * If the contents of the ovn-nb db change, the mappings to the ovn-sb
1185      * db must be recalculated.
1186      *
1187      * If the contents of the ovn-sb db change, it means the 'up' state of
1188      * a port may have changed, as that's the only type of change ovn-northd is
1189      * watching for.
1190      */
1191
1192     ovnnb_seqno = ovsdb_idl_get_seqno(ovnnb_idl);
1193     ovn_seqno = ovsdb_idl_get_seqno(ovnsb_idl);
1194     exiting = false;
1195     while (!exiting) {
1196         ovsdb_idl_run(ovnnb_idl);
1197         ovsdb_idl_run(ovnsb_idl);
1198         unixctl_server_run(unixctl);
1199
1200         if (!ovsdb_idl_is_alive(ovnnb_idl)) {
1201             int retval = ovsdb_idl_get_last_error(ovnnb_idl);
1202             VLOG_ERR("%s: database connection failed (%s)",
1203                     ovnnb_db, ovs_retval_to_string(retval));
1204             res = EXIT_FAILURE;
1205             break;
1206         }
1207
1208         if (!ovsdb_idl_is_alive(ovnsb_idl)) {
1209             int retval = ovsdb_idl_get_last_error(ovnsb_idl);
1210             VLOG_ERR("%s: database connection failed (%s)",
1211                     ovnsb_db, ovs_retval_to_string(retval));
1212             res = EXIT_FAILURE;
1213             break;
1214         }
1215
1216         if (ovnnb_seqno != ovsdb_idl_get_seqno(ovnnb_idl)) {
1217             ovnnb_seqno = ovsdb_idl_get_seqno(ovnnb_idl);
1218             ovnnb_changes_pending = true;
1219         }
1220
1221         if (ovn_seqno != ovsdb_idl_get_seqno(ovnsb_idl)) {
1222             ovn_seqno = ovsdb_idl_get_seqno(ovnsb_idl);
1223             ovn_changes_pending = true;
1224         }
1225
1226         /*
1227          * If there are any pending changes, we delay recalculating the
1228          * necessary updates until after an existing transaction finishes.
1229          * This avoids the possibility of rapid updates causing ovn-northd to
1230          * never be able to successfully make the corresponding updates to the
1231          * other db.  Instead, pending changes are batched up until the next
1232          * time we get a chance to calculate the new state and apply it.
1233          */
1234
1235         if (ovnnb_changes_pending && !ctx.ovnsb_txn) {
1236             /*
1237              * The OVN-nb db contents have changed, so create a transaction for
1238              * updating the OVN-sb DB.
1239              */
1240             ctx.ovnsb_txn = ovsdb_idl_txn_create(ctx.ovnsb_idl);
1241             ovsdb_idl_txn_add_comment(ctx.ovnsb_txn,
1242                                       "ovn-northd: northbound db changed");
1243             ovnnb_db_changed(&ctx);
1244             ovnnb_changes_pending = false;
1245         }
1246
1247         if (ovn_changes_pending && !ctx.ovnnb_txn) {
1248             /*
1249              * The OVN-sb db contents have changed, so create a transaction for
1250              * updating the northbound DB.
1251              */
1252             ctx.ovnnb_txn = ovsdb_idl_txn_create(ctx.ovnnb_idl);
1253             ovsdb_idl_txn_add_comment(ctx.ovnnb_txn,
1254                                       "ovn-northd: southbound db changed");
1255             ovnsb_db_changed(&ctx);
1256             ovn_changes_pending = false;
1257         }
1258
1259         if (ctx.ovnnb_txn) {
1260             enum ovsdb_idl_txn_status txn_status;
1261             txn_status = ovsdb_idl_txn_commit(ctx.ovnnb_txn);
1262             switch (txn_status) {
1263             case TXN_UNCOMMITTED:
1264             case TXN_INCOMPLETE:
1265                 /* Come back around and try to commit this transaction again */
1266                 break;
1267             case TXN_ABORTED:
1268             case TXN_TRY_AGAIN:
1269             case TXN_NOT_LOCKED:
1270             case TXN_ERROR:
1271                 /* Something went wrong, so try creating a new transaction. */
1272                 ovn_changes_pending = true;
1273             case TXN_UNCHANGED:
1274             case TXN_SUCCESS:
1275                 ovsdb_idl_txn_destroy(ctx.ovnnb_txn);
1276                 ctx.ovnnb_txn = NULL;
1277             }
1278         }
1279
1280         if (ctx.ovnsb_txn) {
1281             enum ovsdb_idl_txn_status txn_status;
1282             txn_status = ovsdb_idl_txn_commit(ctx.ovnsb_txn);
1283             switch (txn_status) {
1284             case TXN_UNCOMMITTED:
1285             case TXN_INCOMPLETE:
1286                 /* Come back around and try to commit this transaction again */
1287                 break;
1288             case TXN_ABORTED:
1289             case TXN_TRY_AGAIN:
1290             case TXN_NOT_LOCKED:
1291             case TXN_ERROR:
1292                 /* Something went wrong, so try creating a new transaction. */
1293                 ovnnb_changes_pending = true;
1294             case TXN_UNCHANGED:
1295             case TXN_SUCCESS:
1296                 ovsdb_idl_txn_destroy(ctx.ovnsb_txn);
1297                 ctx.ovnsb_txn = NULL;
1298             }
1299         }
1300
1301         if (ovnnb_seqno == ovsdb_idl_get_seqno(ovnnb_idl) &&
1302                 ovn_seqno == ovsdb_idl_get_seqno(ovnsb_idl)) {
1303             ovsdb_idl_wait(ovnnb_idl);
1304             ovsdb_idl_wait(ovnsb_idl);
1305             if (ctx.ovnnb_txn) {
1306                 ovsdb_idl_txn_wait(ctx.ovnnb_txn);
1307             }
1308             if (ctx.ovnsb_txn) {
1309                 ovsdb_idl_txn_wait(ctx.ovnsb_txn);
1310             }
1311             unixctl_server_wait(unixctl);
1312             if (exiting) {
1313                 poll_immediate_wake();
1314             }
1315             poll_block();
1316         }
1317         if (should_service_stop()) {
1318             exiting = true;
1319         }
1320     }
1321
1322     unixctl_server_destroy(unixctl);
1323     ovsdb_idl_destroy(ovnsb_idl);
1324     ovsdb_idl_destroy(ovnnb_idl);
1325     service_stop();
1326
1327     free(default_db_);
1328
1329     exit(res);
1330 }
1331
1332 static void
1333 ovn_northd_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
1334                 const char *argv[] OVS_UNUSED, void *exiting_)
1335 {
1336     bool *exiting = exiting_;
1337     *exiting = true;
1338
1339     unixctl_command_reply(conn, NULL);
1340 }