On Fri, Sep 3, 2021 at 8:24 AM Mark Gray <[email protected]> wrote: > > This commit splits northd into two parts. One part, ovn-northd.c, > is responsible for the `ovn-northd` application, and the other is > responsible for northd processing. > > This takes one step towards a more modular northd code base. > > Signed-off-by: Mark Gray <[email protected]>
I think the first 2 patches of this series can be considered for 21.09. Acked-by: Numan Siddique <[email protected]> Numan > --- > northd/automake.mk | 2 + > northd/northd.c | 1106 +------------------------------------------ > northd/northd.h | 42 ++ > northd/ovn-northd.c | 1100 ++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 1160 insertions(+), 1090 deletions(-) > create mode 100644 northd/northd.h > create mode 100644 northd/ovn-northd.c > > diff --git a/northd/automake.mk b/northd/automake.mk > index 306b533a486b..35ad8c09d9ba 100644 > --- a/northd/automake.mk > +++ b/northd/automake.mk > @@ -2,6 +2,8 @@ > bin_PROGRAMS += northd/ovn-northd > northd_ovn_northd_SOURCES = \ > northd/northd.c \ > + northd/northd.h \ > + northd/ovn-northd.c \ > northd/ipam.c \ > northd/ipam.h > northd_ovn_northd_LDADD = \ > diff --git a/northd/northd.c b/northd/northd.c > index e9a8492880e4..4a5260701fee 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -14,17 +14,13 @@ > > #include <config.h> > > -#include <getopt.h> > #include <stdlib.h> > #include <stdio.h> > > #include "bitmap.h" > -#include "command-line.h" > -#include "daemon.h" > #include "dirs.h" > #include "ipam.h" > #include "openvswitch/dynamic-string.h" > -#include "fatal-signal.h" > #include "hash.h" > #include "hmapx.h" > #include "openvswitch/hmap.h" > @@ -40,13 +36,12 @@ > #include "lib/ovn-util.h" > #include "lib/lb.h" > #include "memory.h" > -#include "ovs-numa.h" > +#include "northd.h" > #include "lib/ovn-parallel-hmap.h" > #include "ovn/actions.h" > #include "ovn/features.h" > #include "ovn/logical-fields.h" > #include "packets.h" > -#include "openvswitch/poll-loop.h" > #include "simap.h" > #include "smap.h" > #include "sset.h" > @@ -54,41 +49,12 @@ > #include "stopwatch.h" > #include "lib/stopwatch-names.h" > #include "stream.h" > -#include "stream-ssl.h" > #include "timeval.h" > -#include "unixctl.h" > #include "util.h" > #include "uuid.h" > #include "openvswitch/vlog.h" > > -VLOG_DEFINE_THIS_MODULE(ovn_northd); > - > -static unixctl_cb_func ovn_northd_exit; > -static unixctl_cb_func ovn_northd_pause; > -static unixctl_cb_func ovn_northd_resume; > -static unixctl_cb_func ovn_northd_is_paused; > -static unixctl_cb_func ovn_northd_status; > -static unixctl_cb_func cluster_state_reset_cmd; > - > -struct northd_context { > - struct ovsdb_idl *ovnnb_idl; > - struct ovsdb_idl *ovnsb_idl; > - struct ovsdb_idl_txn *ovnnb_txn; > - struct ovsdb_idl_txn *ovnsb_txn; > - struct ovsdb_idl_index *sbrec_chassis_by_name; > - struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name; > - struct ovsdb_idl_index *sbrec_mcast_group_by_name_dp; > - struct ovsdb_idl_index *sbrec_ip_mcast_by_dp; > -}; > - > -struct northd_state { > - bool had_lock; > - bool paused; > -}; > - > -static const char *ovnnb_db; > -static const char *ovnsb_db; > -static const char *unixctl_path; > +VLOG_DEFINE_THIS_MODULE(northd); > > static bool controller_event_en; > > @@ -110,12 +76,6 @@ static bool use_ct_inv_match = true; > #define DEFAULT_PROBE_INTERVAL_MSEC 5000 > static int northd_probe_interval_nb = 0; > static int northd_probe_interval_sb = 0; > - > -/* SSL options */ > -static const char *ssl_private_key_file; > -static const char *ssl_certificate_file; > -static const char *ssl_ca_cert_file; > - > #define MAX_OVN_TAGS 4096 > > /* Pipeline stages. */ > @@ -403,29 +363,6 @@ ovn_stage_to_datapath_type(enum ovn_stage stage) > } > } > > -static void > -usage(void) > -{ > - printf("\ > -%s: OVN northbound management daemon\n\ > -usage: %s [OPTIONS]\n\ > -\n\ > -Options:\n\ > - --ovnnb-db=DATABASE connect to ovn-nb database at DATABASE\n\ > - (default: %s)\n\ > - --ovnsb-db=DATABASE connect to ovn-sb database at DATABASE\n\ > - (default: %s)\n\ > - --dry-run start in paused state (do not commit db > changes)\n\ > - --unixctl=SOCKET override default control socket name\n\ > - -h, --help display this help message\n\ > - -o, --options list available options\n\ > - -V, --version display version information\n\ > -", program_name, program_name, default_nb_db(), default_sb_db()); > - daemon_usage(); > - vlog_usage(); > - stream_usage("database", true, true, false); > -} > - > struct ovn_chassis_qdisc_queues { > struct hmap_node key_node; > uint32_t queue_id; > @@ -4360,7 +4297,7 @@ ovn_lflow_init(struct ovn_lflow *lflow, struct > ovn_datapath *od, > static bool use_logical_dp_groups = false; > static bool use_parallel_build = true; > > -static struct hashrow_locks lflow_locks; > +static struct hashrow_locks *lflow_locks; > > /* Adds a row with the specified contents to the Logical_Flow table. > * Version to use when locking is required. > @@ -4415,11 +4352,11 @@ ovn_lflow_add_at_with_hash(struct hmap *lflow_map, > struct ovn_datapath *od, > > ovs_assert(ovn_stage_to_datapath_type(stage) == > ovn_datapath_get_type(od)); > if (use_logical_dp_groups && use_parallel_build) { > - lock_hash_row(&lflow_locks, hash); > + lock_hash_row(lflow_locks, hash); > lflow = do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match, > actions, io_port, stage_hint, where, > ctrl_meter); > - unlock_hash_row(&lflow_locks, hash); > + unlock_hash_row(lflow_locks, hash); > } else { > lflow = do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match, > actions, io_port, stage_hint, where, ctrl_meter); > @@ -4455,9 +4392,9 @@ ovn_dp_group_add_with_reference(struct ovn_lflow > *lflow_ref, > } > > if (use_parallel_build) { > - lock_hash_row(&lflow_locks, hash); > + lock_hash_row(lflow_locks, hash); > hmapx_add(&lflow_ref->od_group, od); > - unlock_hash_row(&lflow_locks, hash); > + unlock_hash_row(lflow_locks, hash); > } else { > hmapx_add(&lflow_ref->od_group, od); > } > @@ -13171,7 +13108,7 @@ build_lflows(struct northd_context *ctx, struct hmap > *datapaths, > > fast_hmap_size_for(&lflows, max_seen_lflow_size); > if (use_parallel_build) { > - update_hashrow_locks(&lflows, &lflow_locks); > + update_hashrow_locks(&lflows, lflow_locks); > } > build_lswitch_and_lrouter_flows(datapaths, ports, > port_groups, &lflows, mcgroups, > @@ -14239,8 +14176,11 @@ ovnnb_db_run(struct northd_context *ctx, > smap_destroy(&options); > > /* Update the probe interval. */ > - northd_probe_interval_nb = get_probe_interval(ovnnb_db, nb); > - northd_probe_interval_sb = get_probe_interval(ovnsb_db, nb); > + northd_probe_interval_nb = get_probe_interval(ctx->ovnnb_db, nb); > + northd_probe_interval_sb = get_probe_interval(ctx->ovnsb_db, nb); > + > + ovsdb_idl_set_probe_interval(ctx->ovnnb_idl, northd_probe_interval_nb); > + ovsdb_idl_set_probe_interval(ctx->ovnsb_idl, northd_probe_interval_sb); > > use_parallel_build = > (smap_get_bool(&nb->options, "use_parallel_build", false) && > @@ -14532,373 +14472,6 @@ handle_port_binding_changes(struct northd_context > *ctx, struct hmap *ports, > } > } > > -static struct gen_opts_map supported_dhcp_opts[] = { > - OFFERIP, > - DHCP_OPT_NETMASK, > - DHCP_OPT_ROUTER, > - DHCP_OPT_DNS_SERVER, > - DHCP_OPT_LOG_SERVER, > - DHCP_OPT_LPR_SERVER, > - DHCP_OPT_SWAP_SERVER, > - DHCP_OPT_POLICY_FILTER, > - DHCP_OPT_ROUTER_SOLICITATION, > - DHCP_OPT_NIS_SERVER, > - DHCP_OPT_NTP_SERVER, > - DHCP_OPT_SERVER_ID, > - DHCP_OPT_TFTP_SERVER, > - DHCP_OPT_CLASSLESS_STATIC_ROUTE, > - DHCP_OPT_MS_CLASSLESS_STATIC_ROUTE, > - DHCP_OPT_IP_FORWARD_ENABLE, > - DHCP_OPT_ROUTER_DISCOVERY, > - DHCP_OPT_ETHERNET_ENCAP, > - DHCP_OPT_DEFAULT_TTL, > - DHCP_OPT_TCP_TTL, > - DHCP_OPT_MTU, > - DHCP_OPT_LEASE_TIME, > - DHCP_OPT_T1, > - DHCP_OPT_T2, > - DHCP_OPT_WPAD, > - DHCP_OPT_BOOTFILE, > - DHCP_OPT_PATH_PREFIX, > - DHCP_OPT_TFTP_SERVER_ADDRESS, > - DHCP_OPT_HOSTNAME, > - DHCP_OPT_DOMAIN_NAME, > - DHCP_OPT_ARP_CACHE_TIMEOUT, > - DHCP_OPT_TCP_KEEPALIVE_INTERVAL, > - DHCP_OPT_DOMAIN_SEARCH_LIST, > - DHCP_OPT_BOOTFILE_ALT, > - DHCP_OPT_BROADCAST_ADDRESS, > - DHCP_OPT_NETBIOS_NAME_SERVER, > - DHCP_OPT_NETBIOS_NODE_TYPE, > -}; > - > -static struct gen_opts_map supported_dhcpv6_opts[] = { > - DHCPV6_OPT_IA_ADDR, > - DHCPV6_OPT_SERVER_ID, > - DHCPV6_OPT_DOMAIN_SEARCH, > - DHCPV6_OPT_DNS_SERVER > -}; > - > -static void > -check_and_add_supported_dhcp_opts_to_sb_db(struct northd_context *ctx) > -{ > - struct hmap dhcp_opts_to_add = HMAP_INITIALIZER(&dhcp_opts_to_add); > - for (size_t i = 0; (i < sizeof(supported_dhcp_opts) / > - sizeof(supported_dhcp_opts[0])); i++) { > - hmap_insert(&dhcp_opts_to_add, &supported_dhcp_opts[i].hmap_node, > - dhcp_opt_hash(supported_dhcp_opts[i].name)); > - } > - > - const struct sbrec_dhcp_options *opt_row, *opt_row_next; > - SBREC_DHCP_OPTIONS_FOR_EACH_SAFE(opt_row, opt_row_next, ctx->ovnsb_idl) { > - struct gen_opts_map *dhcp_opt = > - dhcp_opts_find(&dhcp_opts_to_add, opt_row->name); > - if (dhcp_opt) { > - if (!strcmp(dhcp_opt->type, opt_row->type) && > - dhcp_opt->code == opt_row->code) { > - hmap_remove(&dhcp_opts_to_add, &dhcp_opt->hmap_node); > - } else { > - sbrec_dhcp_options_delete(opt_row); > - } > - } else { > - sbrec_dhcp_options_delete(opt_row); > - } > - } > - > - struct gen_opts_map *opt; > - HMAP_FOR_EACH (opt, hmap_node, &dhcp_opts_to_add) { > - struct sbrec_dhcp_options *sbrec_dhcp_option = > - sbrec_dhcp_options_insert(ctx->ovnsb_txn); > - sbrec_dhcp_options_set_name(sbrec_dhcp_option, opt->name); > - sbrec_dhcp_options_set_code(sbrec_dhcp_option, opt->code); > - sbrec_dhcp_options_set_type(sbrec_dhcp_option, opt->type); > - } > - > - hmap_destroy(&dhcp_opts_to_add); > -} > - > -static void > -check_and_add_supported_dhcpv6_opts_to_sb_db(struct northd_context *ctx) > -{ > - struct hmap dhcpv6_opts_to_add = HMAP_INITIALIZER(&dhcpv6_opts_to_add); > - for (size_t i = 0; (i < sizeof(supported_dhcpv6_opts) / > - sizeof(supported_dhcpv6_opts[0])); i++) { > - hmap_insert(&dhcpv6_opts_to_add, &supported_dhcpv6_opts[i].hmap_node, > - dhcp_opt_hash(supported_dhcpv6_opts[i].name)); > - } > - > - const struct sbrec_dhcpv6_options *opt_row, *opt_row_next; > - SBREC_DHCPV6_OPTIONS_FOR_EACH_SAFE(opt_row, opt_row_next, > ctx->ovnsb_idl) { > - struct gen_opts_map *dhcp_opt = > - dhcp_opts_find(&dhcpv6_opts_to_add, opt_row->name); > - if (dhcp_opt) { > - hmap_remove(&dhcpv6_opts_to_add, &dhcp_opt->hmap_node); > - } else { > - sbrec_dhcpv6_options_delete(opt_row); > - } > - } > - > - struct gen_opts_map *opt; > - HMAP_FOR_EACH(opt, hmap_node, &dhcpv6_opts_to_add) { > - struct sbrec_dhcpv6_options *sbrec_dhcpv6_option = > - sbrec_dhcpv6_options_insert(ctx->ovnsb_txn); > - sbrec_dhcpv6_options_set_name(sbrec_dhcpv6_option, opt->name); > - sbrec_dhcpv6_options_set_code(sbrec_dhcpv6_option, opt->code); > - sbrec_dhcpv6_options_set_type(sbrec_dhcpv6_option, opt->type); > - } > - > - hmap_destroy(&dhcpv6_opts_to_add); > -} > - > -static const char *rbac_chassis_auth[] = > - {"name"}; > -static const char *rbac_chassis_update[] = > - {"nb_cfg", "external_ids", "encaps", "vtep_logical_switches", > - "other_config", "transport_zones"}; > - > -static const char *rbac_chassis_private_auth[] = > - {"name"}; > -static const char *rbac_chassis_private_update[] = > - {"nb_cfg", "nb_cfg_timestamp", "chassis", "external_ids"}; > - > -static const char *rbac_encap_auth[] = > - {"chassis_name"}; > -static const char *rbac_encap_update[] = > - {"type", "options", "ip"}; > - > -static const char *rbac_controller_event_auth[] = > - {""}; > -static const char *rbac_controller_event_update[] = > - {"chassis", "event_info", "event_type", "seq_num"}; > - > - > -static const char *rbac_fdb_auth[] = > - {""}; > -static const char *rbac_fdb_update[] = > - {"dp_key", "mac", "port_key"}; > - > -static const char *rbac_port_binding_auth[] = > - {""}; > -static const char *rbac_port_binding_update[] = > - {"chassis", "encap", "up", "virtual_parent"}; > - > -static const char *rbac_mac_binding_auth[] = > - {""}; > -static const char *rbac_mac_binding_update[] = > - {"logical_port", "ip", "mac", "datapath"}; > - > -static const char *rbac_svc_monitor_auth[] = > - {""}; > -static const char *rbac_svc_monitor_auth_update[] = > - {"status"}; > -static const char *rbac_igmp_group_auth[] = > - {""}; > -static const char *rbac_igmp_group_update[] = > - {"address", "chassis", "datapath", "ports"}; > - > -static struct rbac_perm_cfg { > - const char *table; > - const char **auth; > - int n_auth; > - bool insdel; > - const char **update; > - int n_update; > - const struct sbrec_rbac_permission *row; > -} rbac_perm_cfg[] = { > - { > - .table = "Chassis", > - .auth = rbac_chassis_auth, > - .n_auth = ARRAY_SIZE(rbac_chassis_auth), > - .insdel = true, > - .update = rbac_chassis_update, > - .n_update = ARRAY_SIZE(rbac_chassis_update), > - .row = NULL > - },{ > - .table = "Chassis_Private", > - .auth = rbac_chassis_private_auth, > - .n_auth = ARRAY_SIZE(rbac_chassis_private_auth), > - .insdel = true, > - .update = rbac_chassis_private_update, > - .n_update = ARRAY_SIZE(rbac_chassis_private_update), > - .row = NULL > - },{ > - .table = "Controller_Event", > - .auth = rbac_controller_event_auth, > - .n_auth = ARRAY_SIZE(rbac_controller_event_auth), > - .insdel = true, > - .update = rbac_controller_event_update, > - .n_update = ARRAY_SIZE(rbac_controller_event_update), > - .row = NULL > - },{ > - .table = "Encap", > - .auth = rbac_encap_auth, > - .n_auth = ARRAY_SIZE(rbac_encap_auth), > - .insdel = true, > - .update = rbac_encap_update, > - .n_update = ARRAY_SIZE(rbac_encap_update), > - .row = NULL > - },{ > - .table = "FDB", > - .auth = rbac_fdb_auth, > - .n_auth = ARRAY_SIZE(rbac_fdb_auth), > - .insdel = true, > - .update = rbac_fdb_update, > - .n_update = ARRAY_SIZE(rbac_fdb_update), > - .row = NULL > - },{ > - .table = "Port_Binding", > - .auth = rbac_port_binding_auth, > - .n_auth = ARRAY_SIZE(rbac_port_binding_auth), > - .insdel = false, > - .update = rbac_port_binding_update, > - .n_update = ARRAY_SIZE(rbac_port_binding_update), > - .row = NULL > - },{ > - .table = "MAC_Binding", > - .auth = rbac_mac_binding_auth, > - .n_auth = ARRAY_SIZE(rbac_mac_binding_auth), > - .insdel = true, > - .update = rbac_mac_binding_update, > - .n_update = ARRAY_SIZE(rbac_mac_binding_update), > - .row = NULL > - },{ > - .table = "Service_Monitor", > - .auth = rbac_svc_monitor_auth, > - .n_auth = ARRAY_SIZE(rbac_svc_monitor_auth), > - .insdel = false, > - .update = rbac_svc_monitor_auth_update, > - .n_update = ARRAY_SIZE(rbac_svc_monitor_auth_update), > - .row = NULL > - },{ > - .table = "IGMP_Group", > - .auth = rbac_igmp_group_auth, > - .n_auth = ARRAY_SIZE(rbac_igmp_group_auth), > - .insdel = true, > - .update = rbac_igmp_group_update, > - .n_update = ARRAY_SIZE(rbac_igmp_group_update), > - .row = NULL > - },{ > - .table = NULL, > - .auth = NULL, > - .n_auth = 0, > - .insdel = false, > - .update = NULL, > - .n_update = 0, > - .row = NULL > - } > -}; > - > -static bool > -ovn_rbac_validate_perm(const struct sbrec_rbac_permission *perm) > -{ > - struct rbac_perm_cfg *pcfg; > - int i, j, n_found; > - > - for (pcfg = rbac_perm_cfg; pcfg->table; pcfg++) { > - if (!strcmp(perm->table, pcfg->table)) { > - break; > - } > - } > - if (!pcfg->table) { > - return false; > - } > - if (perm->n_authorization != pcfg->n_auth || > - perm->n_update != pcfg->n_update) { > - return false; > - } > - if (perm->insert_delete != pcfg->insdel) { > - return false; > - } > - /* verify perm->authorization vs. pcfg->auth */ > - n_found = 0; > - for (i = 0; i < pcfg->n_auth; i++) { > - for (j = 0; j < perm->n_authorization; j++) { > - if (!strcmp(pcfg->auth[i], perm->authorization[j])) { > - n_found++; > - break; > - } > - } > - } > - if (n_found != pcfg->n_auth) { > - return false; > - } > - > - /* verify perm->update vs. pcfg->update */ > - n_found = 0; > - for (i = 0; i < pcfg->n_update; i++) { > - for (j = 0; j < perm->n_update; j++) { > - if (!strcmp(pcfg->update[i], perm->update[j])) { > - n_found++; > - break; > - } > - } > - } > - if (n_found != pcfg->n_update) { > - return false; > - } > - > - /* Success, db state matches expected state */ > - pcfg->row = perm; > - return true; > -} > - > -static void > -ovn_rbac_create_perm(struct rbac_perm_cfg *pcfg, > - struct northd_context *ctx, > - const struct sbrec_rbac_role *rbac_role) > -{ > - struct sbrec_rbac_permission *rbac_perm; > - > - rbac_perm = sbrec_rbac_permission_insert(ctx->ovnsb_txn); > - sbrec_rbac_permission_set_table(rbac_perm, pcfg->table); > - sbrec_rbac_permission_set_authorization(rbac_perm, > - pcfg->auth, > - pcfg->n_auth); > - sbrec_rbac_permission_set_insert_delete(rbac_perm, pcfg->insdel); > - sbrec_rbac_permission_set_update(rbac_perm, > - pcfg->update, > - pcfg->n_update); > - sbrec_rbac_role_update_permissions_setkey(rbac_role, pcfg->table, > - rbac_perm); > -} > - > -static void > -check_and_update_rbac(struct northd_context *ctx) > -{ > - const struct sbrec_rbac_role *rbac_role = NULL; > - const struct sbrec_rbac_permission *perm_row, *perm_next; > - const struct sbrec_rbac_role *role_row, *role_row_next; > - struct rbac_perm_cfg *pcfg; > - > - for (pcfg = rbac_perm_cfg; pcfg->table; pcfg++) { > - pcfg->row = NULL; > - } > - > - SBREC_RBAC_PERMISSION_FOR_EACH_SAFE (perm_row, perm_next, > ctx->ovnsb_idl) { > - if (!ovn_rbac_validate_perm(perm_row)) { > - sbrec_rbac_permission_delete(perm_row); > - } > - } > - SBREC_RBAC_ROLE_FOR_EACH_SAFE (role_row, role_row_next, ctx->ovnsb_idl) { > - if (strcmp(role_row->name, "ovn-controller")) { > - sbrec_rbac_role_delete(role_row); > - } else { > - rbac_role = role_row; > - } > - } > - > - if (!rbac_role) { > - rbac_role = sbrec_rbac_role_insert(ctx->ovnsb_txn); > - sbrec_rbac_role_set_name(rbac_role, "ovn-controller"); > - } > - > - for (pcfg = rbac_perm_cfg; pcfg->table; pcfg++) { > - if (!pcfg->row) { > - ovn_rbac_create_perm(pcfg, ctx, rbac_role); > - } > - } > -} > - > /* Updates the sb_cfg and hv_cfg columns in the northbound NB_Global table. > */ > static void > update_northbound_cfg(struct northd_context *ctx, > @@ -14971,7 +14544,7 @@ ovnsb_db_run(struct northd_context *ctx, > shash_destroy(&ha_ref_chassis_map); > } > > -static void > +void > ovn_db_run(struct northd_context *ctx, > struct ovsdb_idl_index *sbrec_chassis_by_name, > struct ovsdb_idl_loop *ovnsb_idl_loop, > @@ -14982,6 +14555,8 @@ ovn_db_run(struct northd_context *ctx, > ovs_list_init(&lr_list); > hmap_init(&datapaths); > hmap_init(&ports); > + use_parallel_build = ctx->use_parallel_build; > + lflow_locks = ctx->lflow_locks; > > int64_t start_time = time_wall_msec(); > stopwatch_start(OVNNB_DB_RUN_STOPWATCH_NAME, time_msec()); > @@ -14994,653 +14569,4 @@ ovn_db_run(struct northd_context *ctx, > stopwatch_stop(OVNSB_DB_RUN_STOPWATCH_NAME, time_msec()); > destroy_datapaths_and_ports(&datapaths, &ports, &lr_list); > } > - > -static void > -parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED, > - bool *paused) > -{ > - enum { > - OVN_DAEMON_OPTION_ENUMS, > - VLOG_OPTION_ENUMS, > - SSL_OPTION_ENUMS, > - OPT_DRY_RUN, > - OPT_DUMMY_NUMA, > - }; > - static const struct option long_options[] = { > - {"ovnsb-db", required_argument, NULL, 'd'}, > - {"ovnnb-db", required_argument, NULL, 'D'}, > - {"unixctl", required_argument, NULL, 'u'}, > - {"help", no_argument, NULL, 'h'}, > - {"options", no_argument, NULL, 'o'}, > - {"version", no_argument, NULL, 'V'}, > - {"dry-run", no_argument, NULL, OPT_DRY_RUN}, > - {"dummy-numa", required_argument, NULL, OPT_DUMMY_NUMA}, > - OVN_DAEMON_LONG_OPTIONS, > - VLOG_LONG_OPTIONS, > - STREAM_SSL_LONG_OPTIONS, > - {NULL, 0, NULL, 0}, > - }; > - char *short_options = > ovs_cmdl_long_options_to_short_options(long_options); > - > - for (;;) { > - int c; > - > - c = getopt_long(argc, argv, short_options, long_options, NULL); > - if (c == -1) { > - break; > - } > > - switch (c) { > - OVN_DAEMON_OPTION_HANDLERS; > - VLOG_OPTION_HANDLERS; > - > - case 'p': > - ssl_private_key_file = optarg; > - break; > - > - case 'c': > - ssl_certificate_file = optarg; > - break; > - > - case 'C': > - ssl_ca_cert_file = optarg; > - break; > - > - case 'd': > - ovnsb_db = optarg; > - break; > - > - case 'D': > - ovnnb_db = optarg; > - break; > - > - case 'u': > - unixctl_path = optarg; > - break; > - > - case 'h': > - usage(); > - exit(EXIT_SUCCESS); > - > - case 'o': > - ovs_cmdl_print_options(long_options); > - exit(EXIT_SUCCESS); > - > - case 'V': > - ovn_print_version(0, 0); > - exit(EXIT_SUCCESS); > - > - case OPT_DUMMY_NUMA: > - ovs_numa_set_dummy(optarg); > - break; > - > - case OPT_DRY_RUN: > - *paused = true; > - break; > - > - default: > - break; > - } > - } > - > - if (!ovnsb_db || !ovnsb_db[0]) { > - ovnsb_db = default_sb_db(); > - } > - > - if (!ovnnb_db || !ovnnb_db[0]) { > - ovnnb_db = default_nb_db(); > - } > - > - free(short_options); > -} > - > -static void > -add_column_noalert(struct ovsdb_idl *idl, > - const struct ovsdb_idl_column *column) > -{ > - ovsdb_idl_add_column(idl, column); > - ovsdb_idl_omit_alert(idl, column); > -} > - > -static void > -update_ssl_config(void) > -{ > - if (ssl_private_key_file && ssl_certificate_file) { > - stream_ssl_set_key_and_cert(ssl_private_key_file, > - ssl_certificate_file); > - } > - if (ssl_ca_cert_file) { > - stream_ssl_set_ca_cert_file(ssl_ca_cert_file, false); > - } > -} > - > -int > -main(int argc, char *argv[]) > -{ > - int res = EXIT_SUCCESS; > - struct unixctl_server *unixctl; > - int retval; > - bool exiting; > - struct northd_state state = { > - .had_lock = false, > - .paused = false > - }; > - > - fatal_ignore_sigpipe(); > - ovs_cmdl_proctitle_init(argc, argv); > - ovn_set_program_name(argv[0]); > - service_start(&argc, &argv); > - parse_options(argc, argv, &state.paused); > - > - daemonize_start(false); > - > - char *abs_unixctl_path = get_abs_unix_ctl_path(unixctl_path); > - retval = unixctl_server_create(abs_unixctl_path, &unixctl); > - free(abs_unixctl_path); > - > - if (retval) { > - exit(EXIT_FAILURE); > - } > - unixctl_command_register("exit", "", 0, 0, ovn_northd_exit, &exiting); > - unixctl_command_register("pause", "", 0, 0, ovn_northd_pause, &state); > - unixctl_command_register("resume", "", 0, 0, ovn_northd_resume, &state); > - unixctl_command_register("is-paused", "", 0, 0, ovn_northd_is_paused, > - &state); > - unixctl_command_register("status", "", 0, 0, ovn_northd_status, &state); > - > - bool reset_ovnsb_idl_min_index = false; > - unixctl_command_register("sb-cluster-state-reset", "", 0, 0, > - cluster_state_reset_cmd, > - &reset_ovnsb_idl_min_index); > - > - bool reset_ovnnb_idl_min_index = false; > - unixctl_command_register("nb-cluster-state-reset", "", 0, 0, > - cluster_state_reset_cmd, > - &reset_ovnnb_idl_min_index); > - > - daemonize_complete(); > - > - init_hash_row_locks(&lflow_locks); > - use_parallel_build = can_parallelize_hashes(false); > - > - /* We want to detect (almost) all changes to the ovn-nb db. */ > - struct ovsdb_idl_loop ovnnb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > - ovsdb_idl_create(ovnnb_db, &nbrec_idl_class, true, true)); > - ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, > - &nbrec_nb_global_col_nb_cfg_timestamp); > - ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, &nbrec_nb_global_col_sb_cfg); > - ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, > - &nbrec_nb_global_col_sb_cfg_timestamp); > - ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, &nbrec_nb_global_col_hv_cfg); > - ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, > - &nbrec_nb_global_col_hv_cfg_timestamp); > - > - unixctl_command_register("nb-connection-status", "", 0, 0, > - ovn_conn_show, ovnnb_idl_loop.idl); > - > - /* We want to detect only selected changes to the ovn-sb db. */ > - struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > - ovsdb_idl_create(ovnsb_db, &sbrec_idl_class, false, true)); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_sb_global); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_nb_cfg); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_options); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_ipsec); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_logical_flow); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_logical_flow_col_logical_datapath); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_logical_flow_col_logical_dp_group); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_pipeline); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_table_id); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_priority); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_match); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_actions); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_logical_flow_col_controller_meter); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_logical_flow_col_external_ids); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, > - &sbrec_table_logical_dp_group); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_logical_dp_group_col_datapaths); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_multicast_group); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_multicast_group_col_datapath); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_multicast_group_col_tunnel_key); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_multicast_group_col_name); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_multicast_group_col_ports); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_datapath_binding); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_datapath_binding_col_tunnel_key); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_datapath_binding_col_load_balancers); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_datapath_binding_col_external_ids); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_port_binding); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_datapath); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_logical_port); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_tunnel_key); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_parent_port); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_tag); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_type); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_options); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_mac); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_nat_addresses); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_port_binding_col_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_gateway_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_ha_chassis_group); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_virtual_parent); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_up); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_gateway_chassis_col_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_gateway_chassis_col_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_gateway_chassis_col_priority); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_gateway_chassis_col_external_ids); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_gateway_chassis_col_options); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_port_binding_col_external_ids); > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_mac_binding); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_datapath); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_ip); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_mac); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_mac_binding_col_logical_port); > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dhcp_options); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_code); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_type); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_name); > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dhcpv6_options); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcpv6_options_col_code); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcpv6_options_col_type); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcpv6_options_col_name); > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_address_set); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_address_set_col_name); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_address_set_col_addresses); > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_port_group); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_group_col_name); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_group_col_ports); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dns); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dns_col_datapaths); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dns_col_records); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dns_col_external_ids); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_rbac_role); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_rbac_role_col_name); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_rbac_role_col_permissions); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_rbac_permission); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_rbac_permission_col_table); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_rbac_permission_col_authorization); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_rbac_permission_col_insert_delete); > - add_column_noalert(ovnsb_idl_loop.idl, > &sbrec_rbac_permission_col_update); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_meter); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_col_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_col_unit); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_col_bands); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_meter_band); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_band_col_action); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_band_col_rate); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_meter_band_col_burst_size); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_chassis_col_other_config); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_encaps); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_encap); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_type); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis_private); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_chassis_private_col_name); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_chassis_private_col_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_chassis_private_col_nb_cfg); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_chassis_private_col_nb_cfg_timestamp); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_ha_chassis); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_col_chassis); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_col_priority); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_col_external_ids); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_ha_chassis_group); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_group_col_name); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_group_col_ha_chassis); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_group_col_external_ids); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ha_chassis_group_col_ref_chassis); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_igmp_group); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_address); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_datapath); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_chassis); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_ports); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_ip_multicast); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_datapath); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_enabled); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_querier); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_eth_src); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_ip4_src); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_ip6_src); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_table_size); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_idle_timeout); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_query_interval); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_ip_multicast_col_query_max_resp); > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_service_monitor); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_ip); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_logical_port); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_port); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_options); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_status); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_protocol); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_src_mac); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_src_ip); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_service_monitor_col_external_ids); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_load_balancer); > - add_column_noalert(ovnsb_idl_loop.idl, > &sbrec_load_balancer_col_datapaths); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_name); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_vips); > - add_column_noalert(ovnsb_idl_loop.idl, > &sbrec_load_balancer_col_protocol); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_options); > - add_column_noalert(ovnsb_idl_loop.idl, > - &sbrec_load_balancer_col_external_ids); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_bfd); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_logical_port); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_dst_ip); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_status); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_min_tx); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_min_rx); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_detect_mult); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_disc); > - ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_src_port); > - > - ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_fdb); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_fdb_col_mac); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_fdb_col_dp_key); > - add_column_noalert(ovnsb_idl_loop.idl, &sbrec_fdb_col_port_key); > - > - struct ovsdb_idl_index *sbrec_chassis_by_name > - = chassis_index_create(ovnsb_idl_loop.idl); > - > - struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name > - = ha_chassis_group_index_create(ovnsb_idl_loop.idl); > - > - struct ovsdb_idl_index *sbrec_mcast_group_by_name_dp > - = mcast_group_index_create(ovnsb_idl_loop.idl); > - > - struct ovsdb_idl_index *sbrec_ip_mcast_by_dp > - = ip_mcast_index_create(ovnsb_idl_loop.idl); > - > - unixctl_command_register("sb-connection-status", "", 0, 0, > - ovn_conn_show, ovnsb_idl_loop.idl); > - > - char *ovn_internal_version = ovn_get_internal_version(); > - VLOG_INFO("OVN internal version is : [%s]", ovn_internal_version); > - > - stopwatch_create(NORTHD_LOOP_STOPWATCH_NAME, SW_MS); > - stopwatch_create(OVNNB_DB_RUN_STOPWATCH_NAME, SW_MS); > - stopwatch_create(OVNSB_DB_RUN_STOPWATCH_NAME, SW_MS); > - stopwatch_create(BUILD_LFLOWS_CTX_STOPWATCH_NAME, SW_MS); > - stopwatch_create(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, SW_MS); > - stopwatch_create(BUILD_LFLOWS_STOPWATCH_NAME, SW_MS); > - stopwatch_create(LFLOWS_DATAPATHS_STOPWATCH_NAME, SW_MS); > - stopwatch_create(LFLOWS_PORTS_STOPWATCH_NAME, SW_MS); > - stopwatch_create(LFLOWS_LBS_STOPWATCH_NAME, SW_MS); > - stopwatch_create(LFLOWS_IGMP_STOPWATCH_NAME, SW_MS); > - stopwatch_create(LFLOWS_DP_GROUPS_STOPWATCH_NAME, SW_MS); > - > - /* Main loop. */ > - exiting = false; > - > - while (!exiting) { > - update_ssl_config(); > - memory_run(); > - if (memory_should_report()) { > - struct simap usage = SIMAP_INITIALIZER(&usage); > - > - /* Nothing special to report yet. */ > - memory_report(&usage); > - simap_destroy(&usage); > - } > - > - if (!state.paused) { > - if (!ovsdb_idl_has_lock(ovnsb_idl_loop.idl) && > - !ovsdb_idl_is_lock_contended(ovnsb_idl_loop.idl)) > - { > - /* Ensure that only a single ovn-northd is active in the > - * deployment by acquiring a lock called "ovn_northd" on the > - * southbound database and then only performing DB > transactions > - * if the lock is held. > - */ > - ovsdb_idl_set_lock(ovnsb_idl_loop.idl, "ovn_northd"); > - } > - > - struct northd_context ctx = { > - .ovnnb_idl = ovnnb_idl_loop.idl, > - .ovnnb_txn = ovsdb_idl_loop_run(&ovnnb_idl_loop), > - .ovnsb_idl = ovnsb_idl_loop.idl, > - .ovnsb_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), > - .sbrec_chassis_by_name = sbrec_chassis_by_name, > - .sbrec_ha_chassis_grp_by_name = sbrec_ha_chassis_grp_by_name, > - .sbrec_mcast_group_by_name_dp = sbrec_mcast_group_by_name_dp, > - .sbrec_ip_mcast_by_dp = sbrec_ip_mcast_by_dp, > - }; > - > - if (!state.had_lock && ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) { > - VLOG_INFO("ovn-northd lock acquired. " > - "This ovn-northd instance is now active."); > - state.had_lock = true; > - } else if (state.had_lock && > - !ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) > - { > - VLOG_INFO("ovn-northd lock lost. " > - "This ovn-northd instance is now on standby."); > - state.had_lock = false; > - } > - > - if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) { > - ovn_db_run(&ctx, sbrec_chassis_by_name, &ovnsb_idl_loop, > - ovn_internal_version); > - if (ctx.ovnsb_txn) { > - check_and_add_supported_dhcp_opts_to_sb_db(&ctx); > - check_and_add_supported_dhcpv6_opts_to_sb_db(&ctx); > - check_and_update_rbac(&ctx); > - } > - } > - > - ovsdb_idl_loop_commit_and_wait(&ovnnb_idl_loop); > - ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop); > - } else { > - /* ovn-northd is paused > - * - we still want to handle any db updates and update the > - * local IDL. Otherwise, when it is resumed, the local IDL > - * copy will be out of sync. > - * - but we don't want to create any txns. > - * */ > - if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl) || > - ovsdb_idl_is_lock_contended(ovnsb_idl_loop.idl)) > - { > - /* make sure we don't hold the lock while paused */ > - VLOG_INFO("This ovn-northd instance is now paused."); > - ovsdb_idl_set_lock(ovnsb_idl_loop.idl, NULL); > - state.had_lock = false; > - } > - > - ovsdb_idl_run(ovnnb_idl_loop.idl); > - ovsdb_idl_run(ovnsb_idl_loop.idl); > - ovsdb_idl_wait(ovnnb_idl_loop.idl); > - ovsdb_idl_wait(ovnsb_idl_loop.idl); > - } > - > - unixctl_server_run(unixctl); > - unixctl_server_wait(unixctl); > - memory_wait(); > - if (exiting) { > - poll_immediate_wake(); > - } > - > - > - ovsdb_idl_set_probe_interval(ovnnb_idl_loop.idl, > - northd_probe_interval_nb); > - ovsdb_idl_set_probe_interval(ovnsb_idl_loop.idl, > - northd_probe_interval_sb); > - > - if (reset_ovnsb_idl_min_index) { > - VLOG_INFO("Resetting southbound database cluster state"); > - ovsdb_idl_reset_min_index(ovnsb_idl_loop.idl); > - reset_ovnsb_idl_min_index = false; > - } > - > - if (reset_ovnnb_idl_min_index) { > - VLOG_INFO("Resetting northbound database cluster state"); > - ovsdb_idl_reset_min_index(ovnnb_idl_loop.idl); > - reset_ovnnb_idl_min_index = false; > - } > - > - stopwatch_stop(NORTHD_LOOP_STOPWATCH_NAME, time_msec()); > - poll_block(); > - if (should_service_stop()) { > - exiting = true; > - } > - stopwatch_start(NORTHD_LOOP_STOPWATCH_NAME, time_msec()); > - } > - > - > - free(ovn_internal_version); > - unixctl_server_destroy(unixctl); > - ovsdb_idl_loop_destroy(&ovnnb_idl_loop); > - ovsdb_idl_loop_destroy(&ovnsb_idl_loop); > - service_stop(); > - > - exit(res); > -} > - > -static void > -ovn_northd_exit(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *exiting_) > -{ > - bool *exiting = exiting_; > - *exiting = true; > - > - unixctl_command_reply(conn, NULL); > -} > - > -static void > -ovn_northd_pause(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *state_) > -{ > - struct northd_state *state = state_; > - state->paused = true; > - > - unixctl_command_reply(conn, NULL); > -} > - > -static void > -ovn_northd_resume(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *state_) > -{ > - struct northd_state *state = state_; > - state->paused = false; > - > - unixctl_command_reply(conn, NULL); > -} > - > -static void > -ovn_northd_is_paused(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *state_) > -{ > - struct northd_state *state = state_; > - if (state->paused) { > - unixctl_command_reply(conn, "true"); > - } else { > - unixctl_command_reply(conn, "false"); > - } > -} > - > -static void > -ovn_northd_status(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *state_) > -{ > - struct northd_state *state = state_; > - char *status; > - > - if (state->paused) { > - status = "paused"; > - } else { > - status = state->had_lock ? "active" : "standby"; > - } > - > - /* > - * Use a labelled formatted output so we can add more to the status > command > - * later without breaking any consuming scripts > - */ > - struct ds s = DS_EMPTY_INITIALIZER; > - ds_put_format(&s, "Status: %s\n", status); > - unixctl_command_reply(conn, ds_cstr(&s)); > - ds_destroy(&s); > -} > - > -static void > -cluster_state_reset_cmd(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *idl_reset_) > -{ > - bool *idl_reset = idl_reset_; > - > - *idl_reset = true; > - poll_immediate_wake(); > - unixctl_command_reply(conn, NULL); > -} > diff --git a/northd/northd.h b/northd/northd.h > new file mode 100644 > index 000000000000..3209d4224803 > --- /dev/null > +++ b/northd/northd.h > @@ -0,0 +1,42 @@ > +/* > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > +#ifndef NORTHD_H > +#define NORTHD_H 1 > + > +#include "ovsdb-idl.h" > +#include "lib/ovn-parallel-hmap.h" > + > +struct northd_context { > + const char *ovnnb_db; > + const char *ovnsb_db; > + struct ovsdb_idl *ovnnb_idl; > + struct ovsdb_idl *ovnsb_idl; > + struct ovsdb_idl_txn *ovnnb_txn; > + struct ovsdb_idl_txn *ovnsb_txn; > + struct ovsdb_idl_index *sbrec_chassis_by_name; > + struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name; > + struct ovsdb_idl_index *sbrec_mcast_group_by_name_dp; > + struct ovsdb_idl_index *sbrec_ip_mcast_by_dp; > + > + bool use_parallel_build; > + struct hashrow_locks *lflow_locks; > +}; > + > +void > +ovn_db_run(struct northd_context *ctx, > + struct ovsdb_idl_index *sbrec_chassis_by_name, > + struct ovsdb_idl_loop *ovnsb_idl_loop, > + const char *ovn_internal_version); > + > +#endif /* NORTHD_H */ > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c > new file mode 100644 > index 000000000000..ecee14e644af > --- /dev/null > +++ b/northd/ovn-northd.c > @@ -0,0 +1,1100 @@ > +/* > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#include <config.h> > + > +#include <getopt.h> > +#include <stdlib.h> > +#include <stdio.h> > + > +#include "lib/chassis-index.h" > +#include "command-line.h" > +#include "daemon.h" > +#include "fatal-signal.h" > +#include "lib/ip-mcast-index.h" > +#include "lib/mcast-group-index.h" > +#include "memory.h" > +#include "northd.h" > +#include "ovs-numa.h" > +#include "ovsdb-idl.h" > +#include "lib/ovn-l7.h" > +#include "lib/ovn-nb-idl.h" > +#include "lib/ovn-parallel-hmap.h" > +#include "lib/ovn-sb-idl.h" > +#include "openvswitch/poll-loop.h" > +#include "simap.h" > +#include "stopwatch.h" > +#include "lib/stopwatch-names.h" > +#include "stream.h" > +#include "stream-ssl.h" > +#include "unixctl.h" > +#include "util.h" > +#include "openvswitch/vlog.h" > + > +VLOG_DEFINE_THIS_MODULE(ovn_northd); > + > +static unixctl_cb_func ovn_northd_exit; > +static unixctl_cb_func ovn_northd_pause; > +static unixctl_cb_func ovn_northd_resume; > +static unixctl_cb_func ovn_northd_is_paused; > +static unixctl_cb_func ovn_northd_status; > +static unixctl_cb_func cluster_state_reset_cmd; > + > +struct northd_state { > + bool had_lock; > + bool paused; > +}; > + > +static const char *ovnnb_db; > +static const char *ovnsb_db; > +static const char *unixctl_path; > + > +/* SSL options */ > +static const char *ssl_private_key_file; > +static const char *ssl_certificate_file; > +static const char *ssl_ca_cert_file; > + > +static bool use_parallel_build = true; > +static struct hashrow_locks lflow_locks; > + > +static const char *rbac_chassis_auth[] = > + {"name"}; > +static const char *rbac_chassis_update[] = > + {"nb_cfg", "external_ids", "encaps", "vtep_logical_switches", > + "other_config", "transport_zones"}; > + > +static const char *rbac_chassis_private_auth[] = > + {"name"}; > +static const char *rbac_chassis_private_update[] = > + {"nb_cfg", "nb_cfg_timestamp", "chassis", "external_ids"}; > + > +static const char *rbac_encap_auth[] = > + {"chassis_name"}; > +static const char *rbac_encap_update[] = > + {"type", "options", "ip"}; > + > +static const char *rbac_controller_event_auth[] = > + {""}; > +static const char *rbac_controller_event_update[] = > + {"chassis", "event_info", "event_type", "seq_num"}; > + > + > +static const char *rbac_fdb_auth[] = > + {""}; > +static const char *rbac_fdb_update[] = > + {"dp_key", "mac", "port_key"}; > + > +static const char *rbac_port_binding_auth[] = > + {""}; > +static const char *rbac_port_binding_update[] = > + {"chassis", "encap", "up", "virtual_parent"}; > + > +static const char *rbac_mac_binding_auth[] = > + {""}; > +static const char *rbac_mac_binding_update[] = > + {"logical_port", "ip", "mac", "datapath"}; > + > +static const char *rbac_svc_monitor_auth[] = > + {""}; > +static const char *rbac_svc_monitor_auth_update[] = > + {"status"}; > +static const char *rbac_igmp_group_auth[] = > + {""}; > +static const char *rbac_igmp_group_update[] = > + {"address", "chassis", "datapath", "ports"}; > + > +static struct rbac_perm_cfg { > + const char *table; > + const char **auth; > + int n_auth; > + bool insdel; > + const char **update; > + int n_update; > + const struct sbrec_rbac_permission *row; > +} rbac_perm_cfg[] = { > + { > + .table = "Chassis", > + .auth = rbac_chassis_auth, > + .n_auth = ARRAY_SIZE(rbac_chassis_auth), > + .insdel = true, > + .update = rbac_chassis_update, > + .n_update = ARRAY_SIZE(rbac_chassis_update), > + .row = NULL > + },{ > + .table = "Chassis_Private", > + .auth = rbac_chassis_private_auth, > + .n_auth = ARRAY_SIZE(rbac_chassis_private_auth), > + .insdel = true, > + .update = rbac_chassis_private_update, > + .n_update = ARRAY_SIZE(rbac_chassis_private_update), > + .row = NULL > + },{ > + .table = "Controller_Event", > + .auth = rbac_controller_event_auth, > + .n_auth = ARRAY_SIZE(rbac_controller_event_auth), > + .insdel = true, > + .update = rbac_controller_event_update, > + .n_update = ARRAY_SIZE(rbac_controller_event_update), > + .row = NULL > + },{ > + .table = "Encap", > + .auth = rbac_encap_auth, > + .n_auth = ARRAY_SIZE(rbac_encap_auth), > + .insdel = true, > + .update = rbac_encap_update, > + .n_update = ARRAY_SIZE(rbac_encap_update), > + .row = NULL > + },{ > + .table = "FDB", > + .auth = rbac_fdb_auth, > + .n_auth = ARRAY_SIZE(rbac_fdb_auth), > + .insdel = true, > + .update = rbac_fdb_update, > + .n_update = ARRAY_SIZE(rbac_fdb_update), > + .row = NULL > + },{ > + .table = "Port_Binding", > + .auth = rbac_port_binding_auth, > + .n_auth = ARRAY_SIZE(rbac_port_binding_auth), > + .insdel = false, > + .update = rbac_port_binding_update, > + .n_update = ARRAY_SIZE(rbac_port_binding_update), > + .row = NULL > + },{ > + .table = "MAC_Binding", > + .auth = rbac_mac_binding_auth, > + .n_auth = ARRAY_SIZE(rbac_mac_binding_auth), > + .insdel = true, > + .update = rbac_mac_binding_update, > + .n_update = ARRAY_SIZE(rbac_mac_binding_update), > + .row = NULL > + },{ > + .table = "Service_Monitor", > + .auth = rbac_svc_monitor_auth, > + .n_auth = ARRAY_SIZE(rbac_svc_monitor_auth), > + .insdel = false, > + .update = rbac_svc_monitor_auth_update, > + .n_update = ARRAY_SIZE(rbac_svc_monitor_auth_update), > + .row = NULL > + },{ > + .table = "IGMP_Group", > + .auth = rbac_igmp_group_auth, > + .n_auth = ARRAY_SIZE(rbac_igmp_group_auth), > + .insdel = true, > + .update = rbac_igmp_group_update, > + .n_update = ARRAY_SIZE(rbac_igmp_group_update), > + .row = NULL > + },{ > + .table = NULL, > + .auth = NULL, > + .n_auth = 0, > + .insdel = false, > + .update = NULL, > + .n_update = 0, > + .row = NULL > + } > +}; > + > +static struct gen_opts_map supported_dhcp_opts[] = { > + OFFERIP, > + DHCP_OPT_NETMASK, > + DHCP_OPT_ROUTER, > + DHCP_OPT_DNS_SERVER, > + DHCP_OPT_LOG_SERVER, > + DHCP_OPT_LPR_SERVER, > + DHCP_OPT_SWAP_SERVER, > + DHCP_OPT_POLICY_FILTER, > + DHCP_OPT_ROUTER_SOLICITATION, > + DHCP_OPT_NIS_SERVER, > + DHCP_OPT_NTP_SERVER, > + DHCP_OPT_SERVER_ID, > + DHCP_OPT_TFTP_SERVER, > + DHCP_OPT_CLASSLESS_STATIC_ROUTE, > + DHCP_OPT_MS_CLASSLESS_STATIC_ROUTE, > + DHCP_OPT_IP_FORWARD_ENABLE, > + DHCP_OPT_ROUTER_DISCOVERY, > + DHCP_OPT_ETHERNET_ENCAP, > + DHCP_OPT_DEFAULT_TTL, > + DHCP_OPT_TCP_TTL, > + DHCP_OPT_MTU, > + DHCP_OPT_LEASE_TIME, > + DHCP_OPT_T1, > + DHCP_OPT_T2, > + DHCP_OPT_WPAD, > + DHCP_OPT_BOOTFILE, > + DHCP_OPT_PATH_PREFIX, > + DHCP_OPT_TFTP_SERVER_ADDRESS, > + DHCP_OPT_HOSTNAME, > + DHCP_OPT_DOMAIN_NAME, > + DHCP_OPT_ARP_CACHE_TIMEOUT, > + DHCP_OPT_TCP_KEEPALIVE_INTERVAL, > + DHCP_OPT_DOMAIN_SEARCH_LIST, > + DHCP_OPT_BOOTFILE_ALT, > + DHCP_OPT_BROADCAST_ADDRESS, > + DHCP_OPT_NETBIOS_NAME_SERVER, > + DHCP_OPT_NETBIOS_NODE_TYPE, > +}; > + > +static struct gen_opts_map supported_dhcpv6_opts[] = { > + DHCPV6_OPT_IA_ADDR, > + DHCPV6_OPT_SERVER_ID, > + DHCPV6_OPT_DOMAIN_SEARCH, > + DHCPV6_OPT_DNS_SERVER > +}; > + > +static bool > +ovn_rbac_validate_perm(const struct sbrec_rbac_permission *perm) > +{ > + struct rbac_perm_cfg *pcfg; > + int i, j, n_found; > + > + for (pcfg = rbac_perm_cfg; pcfg->table; pcfg++) { > + if (!strcmp(perm->table, pcfg->table)) { > + break; > + } > + } > + if (!pcfg->table) { > + return false; > + } > + if (perm->n_authorization != pcfg->n_auth || > + perm->n_update != pcfg->n_update) { > + return false; > + } > + if (perm->insert_delete != pcfg->insdel) { > + return false; > + } > + /* verify perm->authorization vs. pcfg->auth */ > + n_found = 0; > + for (i = 0; i < pcfg->n_auth; i++) { > + for (j = 0; j < perm->n_authorization; j++) { > + if (!strcmp(pcfg->auth[i], perm->authorization[j])) { > + n_found++; > + break; > + } > + } > + } > + if (n_found != pcfg->n_auth) { > + return false; > + } > + > + /* verify perm->update vs. pcfg->update */ > + n_found = 0; > + for (i = 0; i < pcfg->n_update; i++) { > + for (j = 0; j < perm->n_update; j++) { > + if (!strcmp(pcfg->update[i], perm->update[j])) { > + n_found++; > + break; > + } > + } > + } > + if (n_found != pcfg->n_update) { > + return false; > + } > + > + /* Success, db state matches expected state */ > + pcfg->row = perm; > + return true; > +} > + > +static void > +ovn_rbac_create_perm(struct rbac_perm_cfg *pcfg, > + struct northd_context *ctx, > + const struct sbrec_rbac_role *rbac_role) > +{ > + struct sbrec_rbac_permission *rbac_perm; > + > + rbac_perm = sbrec_rbac_permission_insert(ctx->ovnsb_txn); > + sbrec_rbac_permission_set_table(rbac_perm, pcfg->table); > + sbrec_rbac_permission_set_authorization(rbac_perm, > + pcfg->auth, > + pcfg->n_auth); > + sbrec_rbac_permission_set_insert_delete(rbac_perm, pcfg->insdel); > + sbrec_rbac_permission_set_update(rbac_perm, > + pcfg->update, > + pcfg->n_update); > + sbrec_rbac_role_update_permissions_setkey(rbac_role, pcfg->table, > + rbac_perm); > +} > + > +static void > +check_and_update_rbac(struct northd_context *ctx) > +{ > + const struct sbrec_rbac_role *rbac_role = NULL; > + const struct sbrec_rbac_permission *perm_row, *perm_next; > + const struct sbrec_rbac_role *role_row, *role_row_next; > + struct rbac_perm_cfg *pcfg; > + > + for (pcfg = rbac_perm_cfg; pcfg->table; pcfg++) { > + pcfg->row = NULL; > + } > + > + SBREC_RBAC_PERMISSION_FOR_EACH_SAFE (perm_row, perm_next, > ctx->ovnsb_idl) { > + if (!ovn_rbac_validate_perm(perm_row)) { > + sbrec_rbac_permission_delete(perm_row); > + } > + } > + SBREC_RBAC_ROLE_FOR_EACH_SAFE (role_row, role_row_next, ctx->ovnsb_idl) { > + if (strcmp(role_row->name, "ovn-controller")) { > + sbrec_rbac_role_delete(role_row); > + } else { > + rbac_role = role_row; > + } > + } > + > + if (!rbac_role) { > + rbac_role = sbrec_rbac_role_insert(ctx->ovnsb_txn); > + sbrec_rbac_role_set_name(rbac_role, "ovn-controller"); > + } > + > + for (pcfg = rbac_perm_cfg; pcfg->table; pcfg++) { > + if (!pcfg->row) { > + ovn_rbac_create_perm(pcfg, ctx, rbac_role); > + } > + } > +} > + > +static void > +check_and_add_supported_dhcp_opts_to_sb_db(struct northd_context *ctx) > +{ > + struct hmap dhcp_opts_to_add = HMAP_INITIALIZER(&dhcp_opts_to_add); > + for (size_t i = 0; (i < sizeof(supported_dhcp_opts) / > + sizeof(supported_dhcp_opts[0])); i++) { > + hmap_insert(&dhcp_opts_to_add, &supported_dhcp_opts[i].hmap_node, > + dhcp_opt_hash(supported_dhcp_opts[i].name)); > + } > + > + const struct sbrec_dhcp_options *opt_row, *opt_row_next; > + SBREC_DHCP_OPTIONS_FOR_EACH_SAFE(opt_row, opt_row_next, ctx->ovnsb_idl) { > + struct gen_opts_map *dhcp_opt = > + dhcp_opts_find(&dhcp_opts_to_add, opt_row->name); > + if (dhcp_opt) { > + if (!strcmp(dhcp_opt->type, opt_row->type) && > + dhcp_opt->code == opt_row->code) { > + hmap_remove(&dhcp_opts_to_add, &dhcp_opt->hmap_node); > + } else { > + sbrec_dhcp_options_delete(opt_row); > + } > + } else { > + sbrec_dhcp_options_delete(opt_row); > + } > + } > + > + struct gen_opts_map *opt; > + HMAP_FOR_EACH (opt, hmap_node, &dhcp_opts_to_add) { > + struct sbrec_dhcp_options *sbrec_dhcp_option = > + sbrec_dhcp_options_insert(ctx->ovnsb_txn); > + sbrec_dhcp_options_set_name(sbrec_dhcp_option, opt->name); > + sbrec_dhcp_options_set_code(sbrec_dhcp_option, opt->code); > + sbrec_dhcp_options_set_type(sbrec_dhcp_option, opt->type); > + } > + > + hmap_destroy(&dhcp_opts_to_add); > +} > + > +static void > +check_and_add_supported_dhcpv6_opts_to_sb_db(struct northd_context *ctx) > +{ > + struct hmap dhcpv6_opts_to_add = HMAP_INITIALIZER(&dhcpv6_opts_to_add); > + for (size_t i = 0; (i < sizeof(supported_dhcpv6_opts) / > + sizeof(supported_dhcpv6_opts[0])); i++) { > + hmap_insert(&dhcpv6_opts_to_add, &supported_dhcpv6_opts[i].hmap_node, > + dhcp_opt_hash(supported_dhcpv6_opts[i].name)); > + } > + > + const struct sbrec_dhcpv6_options *opt_row, *opt_row_next; > + SBREC_DHCPV6_OPTIONS_FOR_EACH_SAFE(opt_row, opt_row_next, > ctx->ovnsb_idl) { > + struct gen_opts_map *dhcp_opt = > + dhcp_opts_find(&dhcpv6_opts_to_add, opt_row->name); > + if (dhcp_opt) { > + hmap_remove(&dhcpv6_opts_to_add, &dhcp_opt->hmap_node); > + } else { > + sbrec_dhcpv6_options_delete(opt_row); > + } > + } > + > + struct gen_opts_map *opt; > + HMAP_FOR_EACH(opt, hmap_node, &dhcpv6_opts_to_add) { > + struct sbrec_dhcpv6_options *sbrec_dhcpv6_option = > + sbrec_dhcpv6_options_insert(ctx->ovnsb_txn); > + sbrec_dhcpv6_options_set_name(sbrec_dhcpv6_option, opt->name); > + sbrec_dhcpv6_options_set_code(sbrec_dhcpv6_option, opt->code); > + sbrec_dhcpv6_options_set_type(sbrec_dhcpv6_option, opt->type); > + } > + > + hmap_destroy(&dhcpv6_opts_to_add); > +} > + > +static void > +usage(void) > +{ > + printf("\ > +%s: OVN northbound management daemon\n\ > +usage: %s [OPTIONS]\n\ > +\n\ > +Options:\n\ > + --ovnnb-db=DATABASE connect to ovn-nb database at DATABASE\n\ > + (default: %s)\n\ > + --ovnsb-db=DATABASE connect to ovn-sb database at DATABASE\n\ > + (default: %s)\n\ > + --dry-run start in paused state (do not commit db > changes)\n\ > + --unixctl=SOCKET override default control socket name\n\ > + -h, --help display this help message\n\ > + -o, --options list available options\n\ > + -V, --version display version information\n\ > +", program_name, program_name, default_nb_db(), default_sb_db()); > + daemon_usage(); > + vlog_usage(); > + stream_usage("database", true, true, false); > +} > + > +static void > +parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED, > + bool *paused) > +{ > + enum { > + OVN_DAEMON_OPTION_ENUMS, > + VLOG_OPTION_ENUMS, > + SSL_OPTION_ENUMS, > + OPT_DRY_RUN, > + OPT_DUMMY_NUMA, > + }; > + static const struct option long_options[] = { > + {"ovnsb-db", required_argument, NULL, 'd'}, > + {"ovnnb-db", required_argument, NULL, 'D'}, > + {"unixctl", required_argument, NULL, 'u'}, > + {"help", no_argument, NULL, 'h'}, > + {"options", no_argument, NULL, 'o'}, > + {"version", no_argument, NULL, 'V'}, > + {"dry-run", no_argument, NULL, OPT_DRY_RUN}, > + {"dummy-numa", required_argument, NULL, OPT_DUMMY_NUMA}, > + OVN_DAEMON_LONG_OPTIONS, > + VLOG_LONG_OPTIONS, > + STREAM_SSL_LONG_OPTIONS, > + {NULL, 0, NULL, 0}, > + }; > + char *short_options = > ovs_cmdl_long_options_to_short_options(long_options); > + > + for (;;) { > + int c; > + > + c = getopt_long(argc, argv, short_options, long_options, NULL); > + if (c == -1) { > + break; > + } > + > + switch (c) { > + OVN_DAEMON_OPTION_HANDLERS; > + VLOG_OPTION_HANDLERS; > + > + case 'p': > + ssl_private_key_file = optarg; > + break; > + > + case 'c': > + ssl_certificate_file = optarg; > + break; > + > + case 'C': > + ssl_ca_cert_file = optarg; > + break; > + > + case 'd': > + ovnsb_db = optarg; > + break; > + > + case 'D': > + ovnnb_db = optarg; > + break; > + > + case 'u': > + unixctl_path = optarg; > + break; > + > + case 'h': > + usage(); > + exit(EXIT_SUCCESS); > + > + case 'o': > + ovs_cmdl_print_options(long_options); > + exit(EXIT_SUCCESS); > + > + case 'V': > + ovn_print_version(0, 0); > + exit(EXIT_SUCCESS); > + > + case OPT_DUMMY_NUMA: > + ovs_numa_set_dummy(optarg); > + break; > + > + case OPT_DRY_RUN: > + *paused = true; > + break; > + > + default: > + break; > + } > + } > + > + if (!ovnsb_db || !ovnsb_db[0]) { > + ovnsb_db = default_sb_db(); > + } > + > + if (!ovnnb_db || !ovnnb_db[0]) { > + ovnnb_db = default_nb_db(); > + } > + > + free(short_options); > +} > + > +static void > +add_column_noalert(struct ovsdb_idl *idl, > + const struct ovsdb_idl_column *column) > +{ > + ovsdb_idl_add_column(idl, column); > + ovsdb_idl_omit_alert(idl, column); > +} > + > +static void > +update_ssl_config(void) > +{ > + if (ssl_private_key_file && ssl_certificate_file) { > + stream_ssl_set_key_and_cert(ssl_private_key_file, > + ssl_certificate_file); > + } > + if (ssl_ca_cert_file) { > + stream_ssl_set_ca_cert_file(ssl_ca_cert_file, false); > + } > +} > + > +int > +main(int argc, char *argv[]) > +{ > + int res = EXIT_SUCCESS; > + struct unixctl_server *unixctl; > + int retval; > + bool exiting; > + struct northd_state state = { > + .had_lock = false, > + .paused = false > + }; > + > + fatal_ignore_sigpipe(); > + ovs_cmdl_proctitle_init(argc, argv); > + ovn_set_program_name(argv[0]); > + service_start(&argc, &argv); > + parse_options(argc, argv, &state.paused); > + > + daemonize_start(false); > + > + char *abs_unixctl_path = get_abs_unix_ctl_path(unixctl_path); > + retval = unixctl_server_create(abs_unixctl_path, &unixctl); > + free(abs_unixctl_path); > + > + if (retval) { > + exit(EXIT_FAILURE); > + } > + unixctl_command_register("exit", "", 0, 0, ovn_northd_exit, &exiting); > + unixctl_command_register("pause", "", 0, 0, ovn_northd_pause, &state); > + unixctl_command_register("resume", "", 0, 0, ovn_northd_resume, &state); > + unixctl_command_register("is-paused", "", 0, 0, ovn_northd_is_paused, > + &state); > + unixctl_command_register("status", "", 0, 0, ovn_northd_status, &state); > + > + bool reset_ovnsb_idl_min_index = false; > + unixctl_command_register("sb-cluster-state-reset", "", 0, 0, > + cluster_state_reset_cmd, > + &reset_ovnsb_idl_min_index); > + > + bool reset_ovnnb_idl_min_index = false; > + unixctl_command_register("nb-cluster-state-reset", "", 0, 0, > + cluster_state_reset_cmd, > + &reset_ovnnb_idl_min_index); > + > + daemonize_complete(); > + > + init_hash_row_locks(&lflow_locks); > + use_parallel_build = can_parallelize_hashes(false); > + > + /* We want to detect (almost) all changes to the ovn-nb db. */ > + struct ovsdb_idl_loop ovnnb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > + ovsdb_idl_create(ovnnb_db, &nbrec_idl_class, true, true)); > + ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, > + &nbrec_nb_global_col_nb_cfg_timestamp); > + ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, &nbrec_nb_global_col_sb_cfg); > + ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, > + &nbrec_nb_global_col_sb_cfg_timestamp); > + ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, &nbrec_nb_global_col_hv_cfg); > + ovsdb_idl_omit_alert(ovnnb_idl_loop.idl, > + &nbrec_nb_global_col_hv_cfg_timestamp); > + > + unixctl_command_register("nb-connection-status", "", 0, 0, > + ovn_conn_show, ovnnb_idl_loop.idl); > + > + /* We want to detect only selected changes to the ovn-sb db. */ > + struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > + ovsdb_idl_create(ovnsb_db, &sbrec_idl_class, false, true)); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_sb_global); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_nb_cfg); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_options); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_ipsec); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_logical_flow); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_logical_flow_col_logical_datapath); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_logical_flow_col_logical_dp_group); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_pipeline); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_table_id); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_priority); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_match); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_actions); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_logical_flow_col_controller_meter); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_logical_flow_col_external_ids); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, > + &sbrec_table_logical_dp_group); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_logical_dp_group_col_datapaths); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_multicast_group); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_multicast_group_col_datapath); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_multicast_group_col_tunnel_key); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_multicast_group_col_name); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_multicast_group_col_ports); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_datapath_binding); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_datapath_binding_col_tunnel_key); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_datapath_binding_col_load_balancers); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_datapath_binding_col_external_ids); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_port_binding); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_datapath); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_logical_port); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_tunnel_key); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_parent_port); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_tag); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_type); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_options); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_mac); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_nat_addresses); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_port_binding_col_chassis); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_gateway_chassis); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_ha_chassis_group); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_virtual_parent); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_up); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_gateway_chassis_col_chassis); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_gateway_chassis_col_name); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_gateway_chassis_col_priority); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_gateway_chassis_col_external_ids); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_gateway_chassis_col_options); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_port_binding_col_external_ids); > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_mac_binding); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_datapath); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_ip); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_mac); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_mac_binding_col_logical_port); > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dhcp_options); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_code); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_type); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcp_options_col_name); > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dhcpv6_options); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcpv6_options_col_code); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcpv6_options_col_type); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dhcpv6_options_col_name); > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_address_set); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_address_set_col_name); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_address_set_col_addresses); > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_port_group); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_group_col_name); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_group_col_ports); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_dns); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dns_col_datapaths); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dns_col_records); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_dns_col_external_ids); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_rbac_role); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_rbac_role_col_name); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_rbac_role_col_permissions); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_rbac_permission); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_rbac_permission_col_table); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_rbac_permission_col_authorization); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_rbac_permission_col_insert_delete); > + add_column_noalert(ovnsb_idl_loop.idl, > &sbrec_rbac_permission_col_update); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_meter); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_col_name); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_col_unit); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_col_bands); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_meter_band); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_band_col_action); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_meter_band_col_rate); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_meter_band_col_burst_size); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_name); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > &sbrec_chassis_col_other_config); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_chassis_col_encaps); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_encap); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_encap_col_type); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_chassis_private); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_private_col_name); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_private_col_chassis); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_private_col_nb_cfg); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_chassis_private_col_nb_cfg_timestamp); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_ha_chassis); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_col_chassis); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_col_priority); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_col_external_ids); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_ha_chassis_group); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_group_col_name); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_group_col_ha_chassis); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_group_col_external_ids); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ha_chassis_group_col_ref_chassis); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_igmp_group); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_address); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_datapath); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_chassis); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_igmp_group_col_ports); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_ip_multicast); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_datapath); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_enabled); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_querier); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_eth_src); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_ip4_src); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_ip6_src); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_table_size); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_idle_timeout); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_query_interval); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_ip_multicast_col_query_max_resp); > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_service_monitor); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_ip); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_logical_port); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_port); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_options); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_status); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_protocol); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_src_mac); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_src_ip); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_service_monitor_col_external_ids); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_load_balancer); > + add_column_noalert(ovnsb_idl_loop.idl, > &sbrec_load_balancer_col_datapaths); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_name); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_vips); > + add_column_noalert(ovnsb_idl_loop.idl, > &sbrec_load_balancer_col_protocol); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_options); > + add_column_noalert(ovnsb_idl_loop.idl, > + &sbrec_load_balancer_col_external_ids); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_bfd); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_logical_port); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_dst_ip); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_status); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_min_tx); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_min_rx); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_detect_mult); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_disc); > + ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_bfd_col_src_port); > + > + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_fdb); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_fdb_col_mac); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_fdb_col_dp_key); > + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_fdb_col_port_key); > + > + struct ovsdb_idl_index *sbrec_chassis_by_name > + = chassis_index_create(ovnsb_idl_loop.idl); > + > + struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name > + = ha_chassis_group_index_create(ovnsb_idl_loop.idl); > + > + struct ovsdb_idl_index *sbrec_mcast_group_by_name_dp > + = mcast_group_index_create(ovnsb_idl_loop.idl); > + > + struct ovsdb_idl_index *sbrec_ip_mcast_by_dp > + = ip_mcast_index_create(ovnsb_idl_loop.idl); > + > + unixctl_command_register("sb-connection-status", "", 0, 0, > + ovn_conn_show, ovnsb_idl_loop.idl); > + > + char *ovn_internal_version = ovn_get_internal_version(); > + VLOG_INFO("OVN internal version is : [%s]", ovn_internal_version); > + > + stopwatch_create(NORTHD_LOOP_STOPWATCH_NAME, SW_MS); > + stopwatch_create(OVNNB_DB_RUN_STOPWATCH_NAME, SW_MS); > + stopwatch_create(OVNSB_DB_RUN_STOPWATCH_NAME, SW_MS); > + > + /* Main loop. */ > + exiting = false; > + > + while (!exiting) { > + update_ssl_config(); > + memory_run(); > + if (memory_should_report()) { > + struct simap usage = SIMAP_INITIALIZER(&usage); > + > + /* Nothing special to report yet. */ > + memory_report(&usage); > + simap_destroy(&usage); > + } > + > + if (!state.paused) { > + if (!ovsdb_idl_has_lock(ovnsb_idl_loop.idl) && > + !ovsdb_idl_is_lock_contended(ovnsb_idl_loop.idl)) > + { > + /* Ensure that only a single ovn-northd is active in the > + * deployment by acquiring a lock called "ovn_northd" on the > + * southbound database and then only performing DB > transactions > + * if the lock is held. > + */ > + ovsdb_idl_set_lock(ovnsb_idl_loop.idl, "ovn_northd"); > + } > + > + struct northd_context ctx = { > + .ovnnb_db = ovnnb_db, > + .ovnsb_db = ovnsb_db, > + .ovnnb_idl = ovnnb_idl_loop.idl, > + .ovnnb_txn = ovsdb_idl_loop_run(&ovnnb_idl_loop), > + .ovnsb_idl = ovnsb_idl_loop.idl, > + .ovnsb_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), > + .sbrec_chassis_by_name = sbrec_chassis_by_name, > + .sbrec_ha_chassis_grp_by_name = sbrec_ha_chassis_grp_by_name, > + .sbrec_mcast_group_by_name_dp = sbrec_mcast_group_by_name_dp, > + .sbrec_ip_mcast_by_dp = sbrec_ip_mcast_by_dp, > + .lflow_locks = &lflow_locks, > + .use_parallel_build = use_parallel_build, > + }; > + > + if (!state.had_lock && ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) { > + VLOG_INFO("ovn-northd lock acquired. " > + "This ovn-northd instance is now active."); > + state.had_lock = true; > + } else if (state.had_lock && > + !ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) > + { > + VLOG_INFO("ovn-northd lock lost. " > + "This ovn-northd instance is now on standby."); > + state.had_lock = false; > + } > + > + if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) { > + > + ovn_db_run(&ctx, sbrec_chassis_by_name, &ovnsb_idl_loop, > + ovn_internal_version); > + if (ctx.ovnsb_txn) { > + check_and_add_supported_dhcp_opts_to_sb_db(&ctx); > + check_and_add_supported_dhcpv6_opts_to_sb_db(&ctx); > + check_and_update_rbac(&ctx); > + } > + } > + > + ovsdb_idl_loop_commit_and_wait(&ovnnb_idl_loop); > + ovsdb_idl_loop_commit_and_wait(&ovnsb_idl_loop); > + } else { > + /* ovn-northd is paused > + * - we still want to handle any db updates and update the > + * local IDL. Otherwise, when it is resumed, the local IDL > + * copy will be out of sync. > + * - but we don't want to create any txns. > + * */ > + if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl) || > + ovsdb_idl_is_lock_contended(ovnsb_idl_loop.idl)) > + { > + /* make sure we don't hold the lock while paused */ > + VLOG_INFO("This ovn-northd instance is now paused."); > + ovsdb_idl_set_lock(ovnsb_idl_loop.idl, NULL); > + state.had_lock = false; > + } > + > + ovsdb_idl_run(ovnnb_idl_loop.idl); > + ovsdb_idl_run(ovnsb_idl_loop.idl); > + ovsdb_idl_wait(ovnnb_idl_loop.idl); > + ovsdb_idl_wait(ovnsb_idl_loop.idl); > + } > + > + stopwatch_stop(NORTHD_LOOP_STOPWATCH_NAME, time_msec()); > + stopwatch_start(NORTHD_LOOP_STOPWATCH_NAME, time_msec()); > + unixctl_server_run(unixctl); > + unixctl_server_wait(unixctl); > + memory_wait(); > + if (exiting) { > + poll_immediate_wake(); > + } > + > + if (reset_ovnsb_idl_min_index) { > + VLOG_INFO("Resetting southbound database cluster state"); > + ovsdb_idl_reset_min_index(ovnsb_idl_loop.idl); > + reset_ovnsb_idl_min_index = false; > + } > + > + if (reset_ovnnb_idl_min_index) { > + VLOG_INFO("Resetting northbound database cluster state"); > + ovsdb_idl_reset_min_index(ovnnb_idl_loop.idl); > + reset_ovnnb_idl_min_index = false; > + } > + > + poll_block(); > + if (should_service_stop()) { > + exiting = true; > + } > + } > + > + > + free(ovn_internal_version); > + unixctl_server_destroy(unixctl); > + ovsdb_idl_loop_destroy(&ovnnb_idl_loop); > + ovsdb_idl_loop_destroy(&ovnsb_idl_loop); > + service_stop(); > + > + exit(res); > +} > + > +static void > +ovn_northd_exit(struct unixctl_conn *conn, int argc OVS_UNUSED, > + const char *argv[] OVS_UNUSED, void *exiting_) > +{ > + bool *exiting = exiting_; > + *exiting = true; > + > + unixctl_command_reply(conn, NULL); > +} > + > +static void > +ovn_northd_pause(struct unixctl_conn *conn, int argc OVS_UNUSED, > + const char *argv[] OVS_UNUSED, void *state_) > +{ > + struct northd_state *state = state_; > + state->paused = true; > + > + unixctl_command_reply(conn, NULL); > +} > + > +static void > +ovn_northd_resume(struct unixctl_conn *conn, int argc OVS_UNUSED, > + const char *argv[] OVS_UNUSED, void *state_) > +{ > + struct northd_state *state = state_; > + state->paused = false; > + > + unixctl_command_reply(conn, NULL); > +} > + > +static void > +ovn_northd_is_paused(struct unixctl_conn *conn, int argc OVS_UNUSED, > + const char *argv[] OVS_UNUSED, void *state_) > +{ > + struct northd_state *state = state_; > + if (state->paused) { > + unixctl_command_reply(conn, "true"); > + } else { > + unixctl_command_reply(conn, "false"); > + } > +} > + > +static void > +ovn_northd_status(struct unixctl_conn *conn, int argc OVS_UNUSED, > + const char *argv[] OVS_UNUSED, void *state_) > +{ > + struct northd_state *state = state_; > + char *status; > + > + if (state->paused) { > + status = "paused"; > + } else { > + status = state->had_lock ? "active" : "standby"; > + } > + > + /* > + * Use a labelled formatted output so we can add more to the status > command > + * later without breaking any consuming scripts > + */ > + struct ds s = DS_EMPTY_INITIALIZER; > + ds_put_format(&s, "Status: %s\n", status); > + unixctl_command_reply(conn, ds_cstr(&s)); > + ds_destroy(&s); > +} > + > +static void > +cluster_state_reset_cmd(struct unixctl_conn *conn, int argc OVS_UNUSED, > + const char *argv[] OVS_UNUSED, void *idl_reset_) > +{ > + bool *idl_reset = idl_reset_; > + > + *idl_reset = true; > + poll_immediate_wake(); > + unixctl_command_reply(conn, NULL); > +} > -- > 2.27.0 > > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
