On Thu, Oct 31, 2019 at 2:48 AM Han Zhou <hz...@ovn.org> wrote: > > Sync local and remote gateways between SB and ISB. > > Signed-off-by: Han Zhou <hz...@ovn.org> > --- > ic/ovn-ic.c | 147 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > tests/ovn-ic.at | 56 +++++++++++++++++++++ > 2 files changed, 203 insertions(+) > > diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c > index cf9bf96..025aad5 100644 > --- a/ic/ovn-ic.c > +++ b/ic/ovn-ic.c > @@ -246,6 +246,152 @@ ts_run(struct ic_context *ctx) > shash_destroy(&isb_dps); > } > > +/* Returns true if any information in gw and chassis is different. */ > +static bool > +is_gateway_data_changed(const struct isbrec_gateway *gw, > + const struct sbrec_chassis *chassis) > +{ > + if (strcmp(gw->hostname, chassis->hostname)) { > + return true; > + } > + > + if (gw->n_encaps != chassis->n_encaps) { > + return true; > + } > + > + for (int g = 0; g < gw->n_encaps; g++) { > + > + bool found = false; > + const struct isbrec_encap *gw_encap = gw->encaps[g]; > + for (int s = 0; s < chassis->n_encaps; s++) { > + const struct sbrec_encap *chassis_encap = chassis->encaps[s]; > + if (!strcmp(gw_encap->type, chassis_encap->type) && > + !strcmp(gw_encap->ip, chassis_encap->ip)) { > + found = true; > + if (!smap_equal(&gw_encap->options, > &chassis_encap->options)) { > + return true; > + } > + break; > + } > + } > + if (!found) { > + return true; > + } > + } > + > + return false; > +} > + > +static void > +sync_isb_gw_to_sb(struct ic_context *ctx, > + const struct isbrec_gateway *gw, > + const struct sbrec_chassis *chassis) > +{ > + sbrec_chassis_set_hostname(chassis, gw->hostname); > + sbrec_chassis_set_is_remote(chassis, true); > + > + /* Sync encaps used by this gateway. */ > + ovs_assert(gw->n_encaps); > + struct sbrec_encap *sb_encap; > + struct sbrec_encap **sb_encaps = > + xmalloc(gw->n_encaps * sizeof *sb_encaps); > + for (int i = 0; i < gw->n_encaps; i++) { > + sb_encap = sbrec_encap_insert(ctx->ovnsb_txn); > + sbrec_encap_set_chassis_name(sb_encap, gw->name); > + sbrec_encap_set_ip(sb_encap, gw->encaps[i]->ip); > + sbrec_encap_set_type(sb_encap, gw->encaps[i]->type); > + sbrec_encap_set_options(sb_encap, &gw->encaps[i]->options); > + sb_encaps[i] = sb_encap; > + } > + sbrec_chassis_set_encaps(chassis, sb_encaps, gw->n_encaps); > + free(sb_encaps); > +} > + > +static void > +sync_sb_gw_to_isb(struct ic_context *ctx, > + const struct sbrec_chassis *chassis, > + const struct isbrec_gateway *gw) > +{ > + isbrec_gateway_set_hostname(gw, chassis->hostname); > + > + /* Sync encaps used by this chassis. */ > + ovs_assert(chassis->n_encaps); > + struct isbrec_encap *isb_encap; > + struct isbrec_encap **isb_encaps = > + xmalloc(chassis->n_encaps * sizeof *isb_encaps); > + for (int i = 0; i < chassis->n_encaps; i++) { > + isb_encap = isbrec_encap_insert(ctx->ovnisb_txn); > + isbrec_encap_set_gateway_name(isb_encap, > + chassis->name); > + isbrec_encap_set_ip(isb_encap, chassis->encaps[i]->ip); > + isbrec_encap_set_type(isb_encap, > + chassis->encaps[i]->type); > + isbrec_encap_set_options(isb_encap, > + &chassis->encaps[i]->options); > + isb_encaps[i] = isb_encap; > + } > + isbrec_gateway_set_encaps(gw, isb_encaps, > + chassis->n_encaps); > + free(isb_encaps); > +} > + > +static void > +gateway_run(struct ic_context *ctx, const struct isbrec_availability_zone > *az) > +{ > + if (!ctx->ovnisb_txn || !ctx->ovnsb_txn) { > + return; > + } > + > + struct shash local_gws = SHASH_INITIALIZER(&local_gws); > + struct shash remote_gws = SHASH_INITIALIZER(&remote_gws); > + const struct isbrec_gateway *gw; > + ISBREC_GATEWAY_FOR_EACH (gw, ctx->ovnisb_idl) { > + if (gw->availability_zone == az) { > + shash_add(&local_gws, gw->name, gw); > + } else { > + shash_add(&remote_gws, gw->name, gw); > + } > + } > + > + const struct sbrec_chassis *chassis; > + SBREC_CHASSIS_FOR_EACH (chassis, ctx->ovnsb_idl) { > + if (chassis->is_interconn) { > + gw = shash_find_and_delete(&local_gws, chassis->name); > + if (!gw) { > + gw = isbrec_gateway_insert(ctx->ovnisb_txn); > + isbrec_gateway_set_availability_zone(gw, az); > + isbrec_gateway_set_name(gw, chassis->name); > + sync_sb_gw_to_isb(ctx, chassis, gw); > + } else if (is_gateway_data_changed(gw, chassis)) { > + sync_sb_gw_to_isb(ctx, chassis, gw); > + } > + } else if (chassis->is_remote) { > + gw = shash_find_and_delete(&remote_gws, chassis->name); > + if (!gw) { > + sbrec_chassis_delete(chassis); > + } else if (is_gateway_data_changed(gw, chassis)) { > + sync_isb_gw_to_sb(ctx, gw, chassis); > + } > + } > + } > + > + /* Delete extra gateways from ISB for the local AZ */ > + struct shash_node *node; > + SHASH_FOR_EACH (node, &local_gws) { > + isbrec_gateway_delete(node->data); > + } > + shash_destroy(&local_gws); > + > + /* Create SB chassis for remote gateways in ISB */ > + SHASH_FOR_EACH (node, &remote_gws) { > + gw = node->data; > + chassis = sbrec_chassis_insert(ctx->ovnsb_txn); > + sbrec_chassis_set_name(chassis, gw->name); > + sync_isb_gw_to_sb(ctx, gw, chassis); > + } > + shash_destroy(&remote_gws); > +} > + > static void > ovn_db_run(struct ic_context *ctx) > { > @@ -257,6 +403,7 @@ ovn_db_run(struct ic_context *ctx) > } > > ts_run(ctx); > + gateway_run(ctx, az); > } > > static void > diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at > index 7e6644d..e5640e4 100644 > --- a/tests/ovn-ic.at > +++ b/tests/ovn-ic.at > @@ -68,3 +68,59 @@ ts2 > OVN_CLEANUP_IC([az1]) > > AT_CLEANUP > + > +AT_SETUP([ovn-ic -- gateway sync]) > +AT_SKIP_IF([test $HAVE_PYTHON = no]) > + > +ovn_init_ic_db > +net_add n1 > +ovn_start az1 > +ovn_start az2 > +sim_add gw1 > +as gw1 > +ovs-vsctl add-br br-phys > +ovn_az_attach az1 n1 br-phys 192.168.0.1 > +ovs-vsctl set open . external-ids:is-interconn=true > + > +AT_CHECK([ovn_as az2 ovn-sbctl show | sort -r], [0], [dnl > +Chassis gw1 > + hostname: localhost.localdomain
This test case is failing for me. Looks like the test suite is not setting the hostname properly. I am seeing the below error in testsuite.log ************ --- - 2019-11-12 23:16:17.023926966 +0530 +++ /home/nusiddiq/workspace_cpp/ovn-org/ovn-for-reviews/ovn/_gcc/tests/testsuite.dir/at-groups/204/stdout 2019-11-12 23:16:17.020998532 +0530 @@ -1,5 +1,5 @@ Chassis gw1 - hostname: localhost.localdomain + hostname: nummac.local Encap vxlan Encap geneve options: {csum="true"} 204. ovn-ic.at:72: 204. ovn-ic -- gateway sync (ovn-ic.at:72): FAILED (ovn-ic.at:85) ************* > + Encap vxlan > + Encap geneve > + options: {csum="true"} > + options: {csum="true"} > + ip: "192.168.0.1" > + ip: "192.168.0.1" > +]) > + > +AT_CHECK([ovn_as az2 ovn-sbctl -f csv -d bare --no-headings --columns > is_remote,is_interconn list chassis], [0], [dnl > +true,false > +]) > + > +ovs-vsctl set open . external-ids:is-interconn=false > +AT_CHECK([ovn_as az2 ovn-sbctl show], [0], [dnl > +]) > + > +ovs-vsctl set open . external-ids:is-interconn=true > +AT_CHECK([ovn_as az2 ovn-sbctl show | grep gw1], [0], [ignore]) > + > +OVN_CLEANUP_SBOX(gw1) > +AT_CHECK([ovn_as az2 ovn-sbctl show], [0], [dnl > +]) > + > +# Test encap change > +sim_add gw2 > +as gw2 > +ovs-vsctl add-br br-phys > +ovn_az_attach az1 n1 br-phys 192.168.0.1 > +ovs-vsctl set open . external-ids:is-interconn=true > +OVS_WAIT_UNTIL([ovn_as az2 ovn-sbctl show | grep "192.168.0.1"]) > +ovs-vsctl set open . external_ids:ovn-encap-ip=192.168.0.2 > +OVS_WAIT_UNTIL([ovn_as az2 ovn-sbctl show | grep "192.168.0.2"]) > +ovs-vsctl set open . external_ids:ovn-encap-type="geneve,stt" > +OVS_WAIT_UNTIL([ovn_as az2 ovn-sbctl show | grep stt]) > + > +OVN_CLEANUP_SBOX(gw2) > +OVN_CLEANUP_IC([az1], [az2]) > + > +AT_CLEANUP > -- > 2.1.0 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev