These functions will have an additional user in an upcoming commit. Signed-off-by: Ben Pfaff <b...@ovn.org> --- ovn/controller/physical.c | 227 +++++++++++++++++++++++++++------------------- 1 file changed, 134 insertions(+), 93 deletions(-)
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 41673e5..5de3530 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -153,6 +153,136 @@ get_localnet_port(struct hmap *local_datapaths, int64_t tunnel_key) return ld ? ld->localnet_port : NULL; } +/* Datapath zone IDs for connection tracking and NAT */ +struct zone_ids { + int ct; /* MFF_LOG_CT_ZONE. */ + int dnat; /* MFF_LOG_DNAT_ZONE. */ + int snat; /* MFF_LOG_SNAT_ZONE. */ +}; + +static struct zone_ids +get_zone_ids(const struct sbrec_port_binding *binding, + const struct simap *ct_zones) +{ + struct zone_ids zone_ids; + + zone_ids.ct = simap_get(ct_zones, binding->logical_port); + + const struct uuid *key = &binding->datapath->header_.uuid; + + char *dnat = alloc_nat_zone_key(key, "dnat"); + zone_ids.dnat = simap_get(ct_zones, dnat); + free(dnat); + + char *snat = alloc_nat_zone_key(key, "snat"); + zone_ids.snat = simap_get(ct_zones, snat); + free(snat); + + return zone_ids; +} + +static void +put_local_common_flows(uint32_t dp_key, uint32_t port_key, + bool nested_container, const struct zone_ids *zone_ids, + struct ofpbuf *ofpacts_p, struct hmap *flow_table) +{ + struct match match; + + /* Table 33, priority 100. + * ======================= + * + * Implements output to local hypervisor. Each flow matches a + * logical output port on the local hypervisor, and resubmits to + * table 34. + */ + + match_init_catchall(&match); + ofpbuf_clear(ofpacts_p); + + /* Match MFF_LOG_DATAPATH, MFF_LOG_OUTPORT. */ + match_set_metadata(&match, htonll(dp_key)); + match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); + + if (zone_ids) { + if (zone_ids->ct) { + put_load(zone_ids->ct, MFF_LOG_CT_ZONE, 0, 32, ofpacts_p); + } + if (zone_ids->dnat) { + put_load(zone_ids->dnat, MFF_LOG_DNAT_ZONE, 0, 32, ofpacts_p); + } + if (zone_ids->snat) { + put_load(zone_ids->snat, MFF_LOG_SNAT_ZONE, 0, 32, ofpacts_p); + } + } + + /* Resubmit to table 34. */ + put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p); + ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, + &match, ofpacts_p); + + /* Table 34, Priority 100. + * ======================= + * + * Drop packets whose logical inport and outport are the same + * and the MLF_ALLOW_LOOPBACK flag is not set. */ + match_init_catchall(&match); + ofpbuf_clear(ofpacts_p); + match_set_metadata(&match, htonll(dp_key)); + match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0, + 0, MLF_ALLOW_LOOPBACK); + match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, port_key); + match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); + ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 100, + &match, ofpacts_p); + + /* Table 64, Priority 100. + * ======================= + * + * If the packet is supposed to hair-pin because the "loopback" + * flag is set (or if the destination is a nested container), + * temporarily set the in_port to zero, resubmit to + * table 65 for logical-to-physical translation, then restore + * the port number. */ + match_init_catchall(&match); + ofpbuf_clear(ofpacts_p); + match_set_metadata(&match, htonll(dp_key)); + match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); + if (!nested_container) { + match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0, + MLF_ALLOW_LOOPBACK, MLF_ALLOW_LOOPBACK); + } + + put_stack(MFF_IN_PORT, ofpact_put_STACK_PUSH(ofpacts_p)); + put_load(0, MFF_IN_PORT, 0, 16, ofpacts_p); + put_resubmit(OFTABLE_LOG_TO_PHY, ofpacts_p); + put_stack(MFF_IN_PORT, ofpact_put_STACK_POP(ofpacts_p)); + ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 100, &match, ofpacts_p); +} + +static void +load_logical_ingress_metadata(const struct sbrec_port_binding *binding, + const struct zone_ids *zone_ids, + struct ofpbuf *ofpacts_p) +{ + if (zone_ids) { + if (zone_ids->ct) { + put_load(zone_ids->ct, MFF_LOG_CT_ZONE, 0, 32, ofpacts_p); + } + if (zone_ids->dnat) { + put_load(zone_ids->dnat, MFF_LOG_DNAT_ZONE, 0, 32, ofpacts_p); + } + if (zone_ids->snat) { + put_load(zone_ids->snat, MFF_LOG_SNAT_ZONE, 0, 32, ofpacts_p); + } + } + + /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */ + uint32_t dp_key = binding->datapath->tunnel_key; + uint32_t port_key = binding->tunnel_key; + put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, ofpacts_p); + put_load(port_key, MFF_LOG_INPORT, 0, 32, ofpacts_p); +} + static void consider_port_binding(enum mf_field_id mff_ovn_geneve, const struct simap *ct_zones, @@ -237,7 +367,6 @@ consider_port_binding(enum mf_field_id mff_ovn_geneve, struct match match; if (!is_remote) { - int zone_id = simap_get(ct_zones, binding->logical_port); /* Packets that arrive from a vif can belong to a VM or * to a container located inside that VM. Packets that * arrive from containers have a tag (vlan) associated with them. @@ -280,30 +409,8 @@ consider_port_binding(enum mf_field_id mff_ovn_geneve, * as we're going to remove this with ofpbuf_pull() later. */ uint32_t ofpacts_orig_size = ofpacts_p->size; - if (zone_id) { - put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, ofpacts_p); - } - - int zone_id_dnat, zone_id_snat; - const struct uuid *key = &binding->datapath->header_.uuid; - char *dnat = alloc_nat_zone_key(key, "dnat"); - char *snat = alloc_nat_zone_key(key, "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_p); - } - 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_p); - } - free(snat); - - /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */ - put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, ofpacts_p); - put_load(port_key, MFF_LOG_INPORT, 0, 32, ofpacts_p); + struct zone_ids zone_ids = get_zone_ids(binding, ct_zones); + load_logical_ingress_metadata(binding, &zone_ids, ofpacts_p); /* Resubmit to first logical ingress pipeline table. */ put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p); @@ -321,74 +428,8 @@ consider_port_binding(enum mf_field_id mff_ovn_geneve, ofctrl_add_flow(flow_table, 0, 100, &match, ofpacts_p); } - /* Table 33, priority 100. - * ======================= - * - * Implements output to local hypervisor. Each flow matches a - * logical output port on the local hypervisor, and resubmits to - * table 34. - */ - - match_init_catchall(&match); - ofpbuf_clear(ofpacts_p); - - /* Match MFF_LOG_DATAPATH, MFF_LOG_OUTPORT. */ - match_set_metadata(&match, htonll(dp_key)); - match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); - - if (zone_id) { - put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, ofpacts_p); - } - if (zone_id_dnat) { - put_load(zone_id_dnat, MFF_LOG_DNAT_ZONE, 0, 32, ofpacts_p); - } - if (zone_id_snat) { - put_load(zone_id_snat, MFF_LOG_SNAT_ZONE, 0, 32, ofpacts_p); - } - - /* Resubmit to table 34. */ - put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p); - ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100, - &match, ofpacts_p); - - /* Table 34, Priority 100. - * ======================= - * - * Drop packets whose logical inport and outport are the same - * and the MLF_ALLOW_LOOPBACK flag is not set. */ - match_init_catchall(&match); - ofpbuf_clear(ofpacts_p); - match_set_metadata(&match, htonll(dp_key)); - match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0, - 0, MLF_ALLOW_LOOPBACK); - match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, port_key); - match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); - ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 100, - &match, ofpacts_p); - - /* Table 64, Priority 100. - * ======================= - * - * If the packet is supposed to hair-pin because the "loopback" - * flag is set (or if the destination is a nested container), - * temporarily set the in_port to zero, resubmit to - * table 65 for logical-to-physical translation, then restore - * the port number. */ - match_init_catchall(&match); - ofpbuf_clear(ofpacts_p); - match_set_metadata(&match, htonll(dp_key)); - match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, port_key); - if (!nested_container) { - match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0, - MLF_ALLOW_LOOPBACK, MLF_ALLOW_LOOPBACK); - } - - put_stack(MFF_IN_PORT, ofpact_put_STACK_PUSH(ofpacts_p)); - put_load(0, MFF_IN_PORT, 0, 16, ofpacts_p); - put_resubmit(OFTABLE_LOG_TO_PHY, ofpacts_p); - put_stack(MFF_IN_PORT, ofpact_put_STACK_POP(ofpacts_p)); - ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 100, - &match, ofpacts_p); + put_local_common_flows(dp_key, port_key, nested_container, &zone_ids, + ofpacts_p, flow_table); /* Table 65, Priority 100. * ======================= -- 2.10.2 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev