Adding ovs dev
On 3/15/16, 4:28 PM, "Darrell Ball" <[email protected]> wrote: >Signed-off-by: Darrell Ball <[email protected]> >--- > ovn/utilities/ovn-sbctl.c | 295 +++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 291 insertions(+), 4 deletions(-) > >diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c >index 0f402cd..382128b 100644 >--- a/ovn/utilities/ovn-sbctl.c >+++ b/ovn/utilities/ovn-sbctl.c >@@ -311,11 +311,25 @@ Chassis commands:\n\ > and ENCAP-IP\n\ > chassis-del CHASSIS delete CHASSIS and all of its encaps\n\ > and gateway_ports\n\ >+Physical Endpoint commands:\n\ >+ phys-endpt-add PHYS-ENDPT CHASSIS PORT TYPE ING-ENC EGR-ENC\n\ >+ create a new phys endpt named\n\ >+ PHYS-ENDPT on CHASSIS/PORT\n\ >+ with TYPE encap\n\ >+ and encap values ING-ENC EGR-ENC\n\ >+ chassis and port may be omitted \n\ >+ phys-endpt-del PHYS-ENDPT delete PHYS-ENDPT \n\ > \n\ > Port binding commands:\n\ > lport-bind LPORT CHASSIS bind logical port LPORT to CHASSIS\n\ > lport-unbind LPORT reset the port binding of logical port LPORT\n\ > \n\ >+Port binding Phys Endpt commands:\n\ >+ lport-bind-phys-endpt LPORT PHYS-ENDPT\n\ >+ bind logical port LPORT to PHYS-ENDPT\n\ >+ lport-unbind-phys-endpt LPORT\n\ >+ reset the binding of LPORT to PHYS-ENDPT\n\ >+\n\ > Logical flow commands:\n\ > lflow-list [DATAPATH] List logical flows for all or a single > datapath\n\ > dump-flows [DATAPATH] Alias for lflow-list\n\ >@@ -357,6 +371,9 @@ struct sbctl_context { > struct shash chassis; > /* Maps from lport name to struct sbctl_port_binding. */ > struct shash port_bindings; >+ >+ /* Maps from phys_endpt name to struct sbctl_physical_endpoint. */ >+ struct shash phys_endpts_name_to_rec; > }; > > /* Casts 'base' into 'struct sbctl_context'. */ >@@ -374,6 +391,10 @@ struct sbctl_port_binding { > const struct sbrec_port_binding *bd_cfg; > }; > >+struct sbctl_physical_endpoint { >+ const struct sbrec_physical_endpoint *phys_endpt_db_rec; >+}; >+ > static void > sbctl_context_invalidate_cache(struct ctl_context *ctx) > { >@@ -382,9 +403,10 @@ sbctl_context_invalidate_cache(struct ctl_context *ctx) > if (!sbctl_ctx->cache_valid) { > return; > } >- sbctl_ctx->cache_valid = false; > shash_destroy_free_data(&sbctl_ctx->chassis); > shash_destroy_free_data(&sbctl_ctx->port_bindings); >+ shash_destroy_free_data(&sbctl_ctx->phys_endpts_name_to_rec); >+ sbctl_ctx->cache_valid = false; > } > > static void >@@ -393,7 +415,8 @@ sbctl_context_populate_cache(struct ctl_context *ctx) > struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); > const struct sbrec_chassis *chassis_rec; > const struct sbrec_port_binding *port_binding_rec; >- struct sset chassis, port_bindings; >+ const struct sbrec_physical_endpoint *phys_endpt_db_rec; >+ struct sset chassis, port_bindings, physical_endpoints_set; > > if (sbctl_ctx->cache_valid) { > /* Cache is already populated. */ >@@ -402,6 +425,8 @@ sbctl_context_populate_cache(struct ctl_context *ctx) > sbctl_ctx->cache_valid = true; > shash_init(&sbctl_ctx->chassis); > shash_init(&sbctl_ctx->port_bindings); >+ shash_init(&sbctl_ctx->phys_endpts_name_to_rec); >+ > sset_init(&chassis); > SBREC_CHASSIS_FOR_EACH(chassis_rec, ctx->idl) { > struct sbctl_chassis *ch; >@@ -435,10 +460,30 @@ sbctl_context_populate_cache(struct ctl_context *ctx) > bd); > } > sset_destroy(&port_bindings); >+ >+ sset_init(&physical_endpoints_set); >+ SBREC_PHYSICAL_ENDPOINT_FOR_EACH(phys_endpt_db_rec, ctx->idl) { >+ struct sbctl_physical_endpoint *phys_endpt_lrec; >+ >+ if (!sset_add(&physical_endpoints_set, phys_endpt_db_rec->name)) { >+ VLOG_WARN("database contains duplicate physical endpoint record " >+ "for name (%s)", >+ phys_endpt_db_rec->name); >+ continue; >+ } >+ >+ phys_endpt_lrec >+ = xmalloc(sizeof *phys_endpt_lrec); >+ phys_endpt_lrec->phys_endpt_db_rec = phys_endpt_db_rec; >+ shash_add(&sbctl_ctx->phys_endpts_name_to_rec, >+ phys_endpt_db_rec->name, phys_endpt_lrec); >+ } >+ sset_destroy(&physical_endpoints_set); >+ > } > > static void >-check_conflicts(struct sbctl_context *sbctl_ctx, const char *name, >+chassis_check_conflict(struct sbctl_context *sbctl_ctx, const char *name, > char *msg) > { > if (shash_find(&sbctl_ctx->chassis, name)) { >@@ -448,6 +493,18 @@ check_conflicts(struct sbctl_context *sbctl_ctx, const >char *name, > free(msg); > } > >+static void >+physical_endpoint_check_conflict( >+ struct sbctl_context *sbctl_ctx, const char *name, >+ char *msg) >+{ >+ if (shash_find(&sbctl_ctx->phys_endpts_name_to_rec, name)) { >+ ctl_fatal("%s because a physical endpoint named %s already exists", >+ msg, name); >+ } >+ free(msg); >+} >+ > static struct sbctl_chassis * > find_chassis(struct sbctl_context *sbctl_ctx, const char *name, > bool must_exist) >@@ -480,6 +537,23 @@ find_port_binding(struct sbctl_context *sbctl_ctx, const >char *name, > return bd; > } > >+static struct sbctl_physical_endpoint * >+find_phys_endpt(struct sbctl_context *sbctl_ctx, const char *name, >+ bool must_exist) >+{ >+ struct sbctl_physical_endpoint *phys_endpt_lrec; >+ >+ ovs_assert(sbctl_ctx->cache_valid); >+ >+ phys_endpt_lrec = >+ shash_find_data(&sbctl_ctx->phys_endpts_name_to_rec, name); >+ if (must_exist && !phys_endpt_lrec) { >+ ctl_fatal("no physical endpoint named %s", name); >+ } >+ >+ return phys_endpt_lrec; >+} >+ > static void > pre_get_info(struct ctl_context *ctx) > { >@@ -489,8 +563,16 @@ pre_get_info(struct ctl_context *ctx) > ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_type); > ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_ip); > >+ ovsdb_idl_add_column(ctx->idl, &sbrec_physical_endpoint_col_name); >+ ovsdb_idl_add_column(ctx->idl, &sbrec_physical_endpoint_col_chassis); >+ ovsdb_idl_add_column(ctx->idl, &sbrec_physical_endpoint_col_chassis_port); >+ ovsdb_idl_add_column(ctx->idl, &sbrec_physical_endpoint_col_type); >+ ovsdb_idl_add_column(ctx->idl, >&sbrec_physical_endpoint_col_ingress_encap); >+ ovsdb_idl_add_column(ctx->idl, &sbrec_physical_endpoint_col_egress_encap); >+ > ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_logical_port); > ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_chassis); >+ ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_phys_endpts); > > ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_logical_datapath); > ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_pipeline); >@@ -518,6 +600,13 @@ static struct cmd_show_table cmd_show_tables[] = { > NULL}, > {NULL, NULL, NULL}}, > >+ {&sbrec_table_physical_endpoint, >+ &sbrec_physical_endpoint_col_name, >+ {&sbrec_physical_endpoint_col_chassis, >+ &sbrec_physical_endpoint_col_chassis_port, >+ &sbrec_physical_endpoint_col_ingress_encap}, >+ {NULL, NULL, NULL}}, >+ > {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}}, > }; > >@@ -541,7 +630,7 @@ cmd_chassis_add(struct ctl_context *ctx) > return; > } > } >- check_conflicts(sbctl_ctx, ch_name, >+ chassis_check_conflict(sbctl_ctx, ch_name, > xasprintf("cannot create a chassis named %s", ch_name)); > > char *tokstr = xstrdup(encap_types); >@@ -598,6 +687,113 @@ cmd_chassis_del(struct ctl_context *ctx) > } > > static void >+cmd_phys_endpt_add(struct ctl_context *ctx) >+{ >+ struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); >+ bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; >+ const char *phys_endpt_names, *chassis_name, *chassis_port_name; >+ const char *type_name, *ing_encap, *egr_encap; >+ struct sbctl_chassis *sbctl_ch; >+ int v; >+ >+ if (ctx->argc == 7) { >+ phys_endpt_names = ctx->argv[1]; >+ chassis_name = ctx->argv[2]; >+ chassis_port_name = ctx->argv[3]; >+ type_name = ctx->argv[4]; >+ ing_encap = ctx->argv[5]; >+ egr_encap = ctx->argv[6]; >+ } else if (ctx->argc == 5) { >+ phys_endpt_names = ctx->argv[1]; >+ chassis_name = NULL; >+ chassis_port_name = NULL; >+ type_name = ctx->argv[2]; >+ ing_encap = ctx->argv[3]; >+ egr_encap = ctx->argv[4]; >+ } else { >+ ctl_fatal("phys endpt config must have 6 args " >+ "or 4 args if no chassis and chassis port " >+ "is supplied "); >+ } >+ >+ sbctl_context_populate_cache(ctx); >+ if (may_exist) { >+ struct sbctl_physical_endpoint >+ *phys_endpt_lrec = >+ find_phys_endpt( >+ sbctl_ctx, phys_endpt_names, false); >+ if (phys_endpt_lrec) { >+ return; >+ } >+ } >+ physical_endpoint_check_conflict( >+ sbctl_ctx, phys_endpt_names, >+ xasprintf("cannot create physical endpoint %s", >+ phys_endpt_names)); >+ >+ /* Reminder: Splice out a encap verify function. >+ Presently only supporting single vlan with same >+ value for ingress and egress */ >+ if ( (strcmp(type_name, "vlan")) || >+ (!str_to_int(ing_encap, 10, &v) || v < 0 || v > 4095) || >+ (!str_to_int(egr_encap, 10, &v) || v < 0 || v > 4095) || >+ (strcmp(ing_encap, egr_encap))) { >+ ctl_fatal("phys endpt (%s) unsupported encap ", >+ phys_endpt_names); >+ } >+ >+ struct sbrec_physical_endpoint *phys_endpt_db_rec = >+ sbrec_physical_endpoint_insert(ctx->txn); >+ >+ sbrec_physical_endpoint_set_name( >+ phys_endpt_db_rec, >+ phys_endpt_names); >+ >+ sbctl_ch = find_chassis(sbctl_ctx, chassis_name, true); >+ sbrec_physical_endpoint_set_chassis( >+ phys_endpt_db_rec, >+ sbctl_ch->ch_cfg); >+ >+ sbrec_physical_endpoint_set_chassis_port( >+ phys_endpt_db_rec, >+ chassis_port_name); >+ sbrec_physical_endpoint_set_type( >+ phys_endpt_db_rec, >+ type_name); >+ sbrec_physical_endpoint_set_ingress_encap( >+ phys_endpt_db_rec, >+ ing_encap); >+ sbrec_physical_endpoint_set_egress_encap( >+ phys_endpt_db_rec, >+ egr_encap); >+ >+ sbctl_context_invalidate_cache(ctx); >+} >+ >+static void >+cmd_phys_endpt_del(struct ctl_context *ctx) >+{ >+ struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); >+ bool must_exist = !shash_find(&ctx->options, "--if-exists"); >+ struct sbctl_physical_endpoint *phys_endpt_lrec; >+ >+ sbctl_context_populate_cache(ctx); >+ phys_endpt_lrec = find_phys_endpt( >+ sbctl_ctx, ctx->argv[1], must_exist); >+ if (phys_endpt_lrec) { >+ if (phys_endpt_lrec->phys_endpt_db_rec) { >+ >+ sbrec_physical_endpoint_delete( >+ phys_endpt_lrec->phys_endpt_db_rec); >+ } >+ shash_find_and_delete( >+ &sbctl_ctx->phys_endpts_name_to_rec, >+ ctx->argv[1]); >+ free(phys_endpt_lrec); >+ } >+} >+ >+static void > cmd_lport_bind(struct ctl_context *ctx) > { > struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); >@@ -642,6 +838,79 @@ cmd_lport_unbind(struct ctl_context *ctx) > } > } > >+static void >+cmd_lport_bind_phys_endpts(struct ctl_context *ctx) >+{ >+ struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); >+ bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; >+ struct sbctl_port_binding *sbctl_bd; >+ struct sbctl_physical_endpoint *phys_endpt_lrec; >+ char *lport_name, *phys_endpt_names; >+ >+ >+ /* port_binding must exist, chassis must exist! */ >+ lport_name = ctx->argv[1]; >+ phys_endpt_names = ctx->argv[2]; >+ >+ sbctl_context_populate_cache(ctx); >+ sbctl_bd = find_port_binding(sbctl_ctx, lport_name, true); >+ >+ if (sbctl_bd->bd_cfg->phys_endpts) { >+ if (may_exist) { >+ return; >+ } else { >+ ctl_fatal("lport (%s) already bound to phys_endpts ", >+ lport_name); >+ } >+ } >+ >+ /* Parse the individual endpoints from the endpoints string >+ * and dump them into a set >+ */ >+ char *tokstr = xstrdup(phys_endpt_names); >+ char *token, *save_ptr = NULL; >+ struct sset phys_endpt_names_set = >SSET_INITIALIZER(&phys_endpt_names_set); >+ for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL; >+ token = strtok_r(NULL, ",", &save_ptr)) { >+ sset_add(&phys_endpt_names_set, token); >+ } >+ free(tokstr); >+ >+ size_t num_phys_endpts = sset_count(&phys_endpt_names_set); >+ struct sbrec_physical_endpoint **phys_endpts = >+ xmalloc(num_phys_endpts * sizeof *phys_endpts); >+ const char *phys_endpt_name; >+ int i = 0; >+ SSET_FOR_EACH (phys_endpt_name, &phys_endpt_names_set){ >+ phys_endpt_lrec = find_phys_endpt(sbctl_ctx, phys_endpt_name, true); >+ if (phys_endpt_lrec) { >+ phys_endpts[i] = CONST_CAST(struct sbrec_physical_endpoint *, >+ phys_endpt_lrec->phys_endpt_db_rec); >+ i++; >+ } >+ } >+ sset_destroy(&phys_endpt_names_set); >+ >+ sbrec_port_binding_set_phys_endpts(sbctl_bd->bd_cfg, phys_endpts, i); >+ sbctl_context_invalidate_cache(ctx); >+} >+ >+static void >+cmd_lport_unbind_phys_endpts(struct ctl_context *ctx) >+{ >+ struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); >+ bool must_exist = !shash_find(&ctx->options, "--if-exists"); >+ struct sbctl_port_binding *sbctl_bd; >+ char *lport_name; >+ >+ lport_name = ctx->argv[1]; >+ sbctl_context_populate_cache(ctx); >+ sbctl_bd = find_port_binding(sbctl_ctx, lport_name, must_exist); >+ if (sbctl_bd) { >+ sbrec_port_binding_set_phys_endpts(sbctl_bd->bd_cfg, NULL, 0); >+ } >+} >+ > enum { > PL_INGRESS, > PL_EGRESS, >@@ -775,6 +1044,11 @@ static const struct ctl_table_class tables[] = { > {{&sbrec_table_mac_binding, &sbrec_mac_binding_col_logical_port, NULL}, > {NULL, NULL, NULL}}}, > >+ {&sbrec_table_physical_endpoint, >+ {{&sbrec_table_physical_endpoint, >+ &sbrec_physical_endpoint_col_name, NULL}, >+ {NULL, NULL, NULL}}}, >+ > {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}} > }; > >@@ -1011,17 +1285,30 @@ sbctl_exit(int status) > > static const struct ctl_command_syntax sbctl_commands[] = { > /* Chassis commands. */ >+ > {"chassis-add", 3, 3, "CHASSIS ENCAP-TYPE ENCAP-IP", pre_get_info, > cmd_chassis_add, NULL, "--may-exist", RW}, > {"chassis-del", 1, 1, "CHASSIS", pre_get_info, cmd_chassis_del, NULL, > "--if-exists", RW}, > >+ /* Physical Endpoint commands */ >+ {"phys-endpt-add", 4, 6, "PHYS-ENDPT CHASSIS PORT TYPE ING-ENC EGR-ENC", >+ pre_get_info, cmd_phys_endpt_add, NULL, "--may-exist", RW}, >+ {"phys-endpt-del", 1, 1, "PHYS-ENDPT", >+ pre_get_info, cmd_phys_endpt_del, NULL, "--if-exists", RW}, >+ > /* Port binding commands. */ > {"lport-bind", 2, 2, "LPORT CHASSIS", pre_get_info, cmd_lport_bind, NULL, > "--may-exist", RW}, > {"lport-unbind", 1, 1, "LPORT", pre_get_info, cmd_lport_unbind, NULL, > "--if-exists", RW}, > >+ /* Port to physical endpoint binding */ >+ {"lport-bind-phys-endpt", 2, 2, "LPORT PHYS-ENDPT", pre_get_info, >+ cmd_lport_bind_phys_endpts, NULL, "--may-exist", RW}, >+ {"lport-unbind-phys-endpt", 1, 1, "LPORT", pre_get_info, >+ cmd_lport_unbind_phys_endpts, NULL, "--if-exists", RW}, >+ > /* Logical flow commands */ > {"lflow-list", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL, > "", RO}, >-- >1.9.1 > _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
