@@ -254,29 +254,54 @@ get_ovnsb_remote_probe_interval(struct ovsdb_idl *ovs_idl, int *value)
}
static void
-update_ct_zones(struct sset *lports, struct simap *ct_zones,
- unsigned long *ct_zone_bitmap)
+update_ct_zones(struct sset *lports, struct hmap *patched_datapaths,
+ struct simap *ct_zones, unsigned long *ct_zone_bitmap)
{
struct simap_node *ct_zone, *ct_zone_next;
- const char *iface_id;
int scan_start = 1;
+ struct patched_datapath *pd;
+ const char *user;
+ struct sset all_users = SSET_INITIALIZER(&all_users);
- /* xxx This is wasteful to assign a zone to each port--even if no
- * xxx security policy is applied. */
+ SSET_FOR_EACH(user, lports) {
+ sset_add(&all_users, user);
+ }
+
+ /* Local patched datapath (gateway routers) need zones assigned. */
+ HMAP_FOR_EACH(pd, hmap_node, patched_datapaths) {
+ if (!pd->local) {
+ continue;
+ }
- /* Delete any zones that are associated with removed ports. */
+ char *dnat = xasprintf(UUID_FMT"_%s",
+ UUID_ARGS(&pd->port_binding->datapath->header_.uuid),
+ "dnat");
+ char *snat = xasprintf(UUID_FMT"_%s",
+ UUID_ARGS(&pd->port_binding->datapath->header_.uuid),
+ "snat");
+ sset_add(&all_users, dnat);
+ sset_add(&all_users, snat);
+ free(dnat);
+ free(snat);
+ }
+
+ /* Delete zones that do not exist in above sset. */
SIMAP_FOR_EACH_SAFE(ct_zone, ct_zone_next, ct_zones) {
- if (!sset_contains(lports, ct_zone->name)) {
+ if (!sset_contains(&all_users, ct_zone->name)) {
bitmap_set0(ct_zone_bitmap, ct_zone->data);
simap_delete(ct_zones, ct_zone);
}
}
- /* Assign a unique zone id for each logical port. */
- SSET_FOR_EACH(iface_id, lports) {
+ /* xxx This is wasteful to assign a zone to each port--even if no
+ * xxx security policy is applied. */
+
+ /* Assign a unique zone id for each logical port and two zones
+ * to a gateway router. */
+ SSET_FOR_EACH(user, &all_users) {
size_t zone;
- if (simap_contains(ct_zones, iface_id)) {
+ if (simap_contains(ct_zones, user)) {
continue;
}
@@ -290,7 +315,7 @@ update_ct_zones(struct sset *lports, struct simap *ct_zones,
scan_start = zone + 1;
bitmap_set1(ct_zone_bitmap, zone);
- simap_put(ct_zones, iface_id, zone);
+ simap_put(ct_zones, user, zone);
/* xxx We should erase any old entries for this
* xxx zone, but we need a generic interface to the conntrack
@@ -422,7 +447,8 @@ main(int argc, char *argv[])
enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
pinctrl_run(&ctx, &lports, br_int);
- update_ct_zones(&all_lports, &ct_zones, ct_zone_bitmap);
+ update_ct_zones(&all_lports, &patched_datapaths, &ct_zones,
+ ct_zone_bitmap);
struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
lflow_run(&ctx, &lports, &mcgroups, &local_datapaths,
@@ -48,6 +48,8 @@ struct local_datapath *get_local_datapath(const struct hmap *,
* with at least one logical patch port binding. */
struct patched_datapath {
struct hmap_node hmap_node;
+ bool local; /* 'True' if the datapath is for gateway router. */
+ const struct sbrec_port_binding *port_binding;
};
struct patched_datapath *get_patched_datapath(const struct hmap *,
@@ -230,7 +230,7 @@ add_bridge_mappings(struct controller_ctx *ctx,
static void
add_patched_datapath(struct hmap *patched_datapaths,
- const struct sbrec_port_binding *binding_rec)
+ const struct sbrec_port_binding *binding_rec, bool local)
{
if (get_patched_datapath(patched_datapaths,
binding_rec->datapath->tunnel_key)) {
@@ -238,6 +238,8 @@ add_patched_datapath(struct hmap *patched_datapaths,
}
struct patched_datapath *pd = xzalloc(sizeof *pd);
+ pd->local = local;
+ pd->port_binding = binding_rec;
hmap_insert(patched_datapaths, &pd->hmap_node,
binding_rec->datapath->tunnel_key);
}
@@ -302,7 +304,7 @@ add_logical_patch_ports(struct controller_ctx *ctx,
existing_ports);
free(dst_name);
free(src_name);
- add_patched_datapath(patched_datapaths, binding);
+ add_patched_datapath(patched_datapaths, binding, local_port);
if (local_port) {
if (binding->chassis != chassis_rec) {
sbrec_port_binding_set_chassis(binding, chassis_rec);
@@ -367,6 +367,25 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
}
+ int zone_id_dnat, zone_id_snat;
+ char *dnat = xasprintf(UUID_FMT"_%s",
+ UUID_ARGS(&binding->datapath->header_.uuid),
+ "dnat");
+ char *snat = xasprintf(UUID_FMT"_%s",
+ UUID_ARGS(&binding->datapath->header_.uuid),
+ "snat");
+ zone_id_dnat = simap_get(ct_zones, dnat);
+ if (zone_id_dnat) {
+ put_load(zone_id_dnat, MFF_LOG_DNAT_ZONE, 0, 32, &ofpacts);
+ }
+ free(dnat);
+
+ zone_id_snat = simap_get(ct_zones, snat);
+ if (zone_id_snat) {
+ put_load(zone_id_snat, MFF_LOG_SNAT_ZONE, 0, 32, &ofpacts);
+ }
+ free(snat);
+
/* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
@@ -403,6 +422,12 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
if (zone_id) {
put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
}
+ if (zone_id_dnat) {
+ put_load(zone_id_dnat, MFF_LOG_DNAT_ZONE, 0, 32, &ofpacts);
+ }
+ if (zone_id_snat) {
+ put_load(zone_id_snat, MFF_LOG_SNAT_ZONE, 0, 32, &ofpacts);
+ }
/* Resubmit to table 34. */
put_resubmit(OFTABLE_DROP_LOOPBACK, &ofpacts);
@@ -23,7 +23,12 @@
* These values are documented in ovn-architecture(7), please update the
* documentation if you change any of them. */
#define MFF_LOG_DATAPATH MFF_METADATA /* Logical datapath (64 bits). */
-#define MFF_LOG_CT_ZONE MFF_REG5 /* Logical conntrack zone (32 bits). */
+#define MFF_LOG_DNAT_ZONE MFF_REG3 /* conntrack dnat zone for gateway router
+ * (32 bits). */
+#define MFF_LOG_SNAT_ZONE MFF_REG4 /* conntrack snat zone for gateway router
+ * (32 bits). */
+#define MFF_LOG_CT_ZONE MFF_REG5 /* Logical conntrack zone for lports
+ * (32 bits). */
#define MFF_LOG_INPORT MFF_REG6 /* Logical input port (32 bits). */
#define MFF_LOG_OUTPORT MFF_REG7 /* Logical output port (32 bits). */
@@ -33,8 +38,6 @@
#define MFF_LOG_REGS \
MFF_LOG_REG(MFF_REG0) \
MFF_LOG_REG(MFF_REG1) \
- MFF_LOG_REG(MFF_REG2) \
- MFF_LOG_REG(MFF_REG3) \
- MFF_LOG_REG(MFF_REG4)
+ MFF_LOG_REG(MFF_REG2)
#endif /* ovn/lib/logical-fields.h */
OVS NAT currently cannot do snat and dnat in the same zone. So we need two zones per gateway router. Signed-off-by: Gurucharan Shetty <guru@ovn.org> --- No v1. Newly added as part of v2. --- ovn/controller/ovn-controller.c | 50 +++++++++++++++++++++++++++++---------- ovn/controller/ovn-controller.h | 2 ++ ovn/controller/patch.c | 6 +++-- ovn/controller/physical.c | 25 ++++++++++++++++++++ ovn/lib/logical-fields.h | 11 +++++---- 5 files changed, 76 insertions(+), 18 deletions(-)