Populate the in_out_port tag for logical switch pipeline flows wherever possible.
Signed-off-by: Han Zhou <hz...@ovn.org> --- northd/ovn-northd.c | 272 +++++++++++++++++++++++++------------------- 1 file changed, 155 insertions(+), 117 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 83746f4ab..f60dab7a9 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -4046,6 +4046,7 @@ struct ovn_lflow { uint16_t priority; char *match; char *actions; + char *io_port; char *stage_hint; const char *where; }; @@ -4081,7 +4082,7 @@ ovn_lflow_equal(const struct ovn_lflow *a, const struct ovn_datapath *od, static void ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od, enum ovn_stage stage, uint16_t priority, - char *match, char *actions, char *stage_hint, + char *match, char *actions, char *io_port, char *stage_hint, const char *where) { hmapx_init(&lflow->od_group); @@ -4090,6 +4091,7 @@ ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od, lflow->priority = priority; lflow->match = match; lflow->actions = actions; + lflow->io_port = io_port; lflow->stage_hint = stage_hint; lflow->where = where; } @@ -4107,7 +4109,7 @@ static struct hashrow_locks lflow_locks; static void do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, uint32_t hash, enum ovn_stage stage, uint16_t priority, - const char *match, const char *actions, + const char *match, const char *actions, const char *io_port, const struct ovsdb_idl_row *stage_hint, const char *where) { @@ -4130,6 +4132,7 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, * one datapath in a group, so it could be hashed correctly. */ ovn_lflow_init(lflow, NULL, stage, priority, xstrdup(match), xstrdup(actions), + io_port ? xstrdup(io_port) : NULL, ovn_lflow_hint(stage_hint), where); hmapx_add(&lflow->od_group, od); hmap_insert_fast(lflow_map, &lflow->hmap_node, hash); @@ -4139,7 +4142,7 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, static void ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, enum ovn_stage stage, uint16_t priority, - const char *match, const char *actions, + const char *match, const char *actions, const char *io_port, const struct ovsdb_idl_row *stage_hint, const char *where) { ovs_assert(ovn_stage_to_datapath_type(stage) == ovn_datapath_get_type(od)); @@ -4154,11 +4157,11 @@ ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, if (use_logical_dp_groups && use_parallel_build) { lock_hash_row(&lflow_locks, hash); do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match, - actions, stage_hint, where); + actions, io_port, stage_hint, where); unlock_hash_row(&lflow_locks, hash); } else { do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match, - actions, stage_hint, where); + actions, io_port, stage_hint, where); } } @@ -4166,11 +4169,27 @@ ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, #define ovn_lflow_add_with_hint(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, \ ACTIONS, STAGE_HINT) \ ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ - STAGE_HINT, OVS_SOURCE_LOCATOR) + NULL, STAGE_HINT, OVS_SOURCE_LOCATOR) + +/* This macro is similar to ovn_lflow_add_with_hint, except that it requires + * the IN_OUT_PORT argument, which tells the lport name that appears in the + * MATCH, which helps ovn-controller to bypass lflows parsing when the lport is + * not local to the chassis. The critiera of the lport to be added using this + * argument: + * + * - For ingress pipeline, the lport that is used to match "inport". + * - For egress pipeline, the lport that is used to match "outport". + * + * For now, only LS pipelines should use this macro. */ +#define ovn_lflow_add_with_lport_and_hint(LFLOW_MAP, OD, STAGE, PRIORITY, \ + MATCH, ACTIONS, IN_OUT_PORT, \ + STAGE_HINT) \ + ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ + IN_OUT_PORT, STAGE_HINT, OVS_SOURCE_LOCATOR) #define ovn_lflow_add(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS) \ ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ - NULL, OVS_SOURCE_LOCATOR) + NULL, NULL, OVS_SOURCE_LOCATOR) static struct ovn_lflow * ovn_lflow_find(const struct hmap *lflows, const struct ovn_datapath *od, @@ -4196,6 +4215,7 @@ ovn_lflow_destroy(struct hmap *lflows, struct ovn_lflow *lflow) hmapx_destroy(&lflow->od_group); free(lflow->match); free(lflow->actions); + free(lflow->io_port); free(lflow->stage_hint); free(lflow); } @@ -4365,8 +4385,10 @@ build_port_security_nd(struct ovn_port *op, struct hmap *lflows, ds_chomp(&match, ','); ds_put_cstr(&match, "}"); } - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND, - 90, ds_cstr(&match), "next;", stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_PORT_SEC_ND, 90, + ds_cstr(&match), "next;", + op->key, stage_hint); } if (ps->n_ipv6_addrs || no_ip) { @@ -4375,15 +4397,18 @@ build_port_security_nd(struct ovn_port *op, struct hmap *lflows, op->json_key, ps->ea_s); build_port_security_ipv6_nd_flow(&match, ps->ea, ps->ipv6_addrs, ps->n_ipv6_addrs); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND, - 90, ds_cstr(&match), "next;", stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_PORT_SEC_ND, 90, + ds_cstr(&match), "next;", + op->key, stage_hint); } } ds_clear(&match); ds_put_format(&match, "inport == %s && (arp || nd)", op->json_key); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND, 80, - ds_cstr(&match), "drop;", stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_ND, + 80, ds_cstr(&match), "drop;", op->key, + stage_hint); ds_destroy(&match); } @@ -4435,9 +4460,10 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, " && ip4.dst == 255.255.255.255" " && udp.src == 68 && udp.dst == 67", op->json_key, ps->ea_s); - ovn_lflow_add_with_hint(lflows, op->od, stage, 90, - ds_cstr(&dhcp_match), "next;", - stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, stage, 90, + ds_cstr(&dhcp_match), + "next;", op->key, + stage_hint); ds_destroy(&dhcp_match); ds_put_format(&match, "inport == %s && eth.src == %s" " && ip4.src == {", op->json_key, @@ -4476,9 +4502,9 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, ds_chomp(&match, ' '); ds_chomp(&match, ','); ds_put_cstr(&match, "}"); - ovn_lflow_add_with_hint(lflows, op->od, stage, 90, - ds_cstr(&match), "next;", - stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, stage, 90, + ds_cstr(&match), "next;", + op->key, stage_hint); ds_destroy(&match); } @@ -4492,11 +4518,11 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, " && eth.src == %s" " && ip6.src == ::" " && ip6.dst == ff02::/16" - " && icmp6.type == {131, 135, 143}", op->json_key, - ps->ea_s); - ovn_lflow_add_with_hint(lflows, op->od, stage, 90, - ds_cstr(&dad_match), "next;", - stage_hint); + " && icmp6.type == {131, 135, 143}", + op->json_key, ps->ea_s); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, stage, 90, + ds_cstr(&dad_match), "next;", + op->key, stage_hint); ds_destroy(&dad_match); } ds_put_format(&match, "%s == %s && %s == %s", @@ -4504,9 +4530,9 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, pipeline == P_IN ? "eth.src" : "eth.dst", ps->ea_s); build_port_security_ipv6_flow(pipeline, &match, ps->ea, ps->ipv6_addrs, ps->n_ipv6_addrs); - ovn_lflow_add_with_hint(lflows, op->od, stage, 90, - ds_cstr(&match), "next;", - stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, stage, 90, + ds_cstr(&match), "next;", + op->key, stage_hint); ds_destroy(&match); } @@ -4514,8 +4540,8 @@ build_port_security_ip(enum ovn_pipeline pipeline, struct ovn_port *op, port_direction, op->json_key, pipeline == P_IN ? "eth.src" : "eth.dst", ps->ea_s); - ovn_lflow_add_with_hint(lflows, op->od, stage, 80, match, "drop;", - stage_hint); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, stage, 80, match, + "drop;", op->key, stage_hint); free(match); } @@ -4836,9 +4862,9 @@ build_lswitch_input_port_sec_op( ds_put_format(actions, "set_queue(%s); ", queue_id); } ds_put_cstr(actions, "next;"); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_L2, 50, - ds_cstr(match), ds_cstr(actions), - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, S_SWITCH_IN_PORT_SEC_L2, + 50, ds_cstr(match), ds_cstr(actions), + op->key, &op->nbsp->header_); if (op->nbsp->n_port_security) { build_port_security_ip(P_IN, op, lflows, &op->nbsp->header_); @@ -4872,16 +4898,18 @@ build_lswitch_learn_fdb_op( ds_put_format(match, "inport == %s", op->json_key); ds_put_format(actions, REGBIT_LKUP_FDB " = lookup_fdb(inport, eth.src); next;"); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_LOOKUP_FDB, 100, - ds_cstr(match), ds_cstr(actions), - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_LOOKUP_FDB, 100, + ds_cstr(match), ds_cstr(actions), + op->key, &op->nbsp->header_); ds_put_cstr(match, " && "REGBIT_LKUP_FDB" == 0"); ds_clear(actions); ds_put_cstr(actions, "put_fdb(inport, eth.src); next;"); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PUT_FDB, 100, - ds_cstr(match), ds_cstr(actions), - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, S_SWITCH_IN_PUT_FDB, + 100, ds_cstr(match), + ds_cstr(actions), op->key, + &op->nbsp->header_); } } @@ -4931,13 +4959,15 @@ build_lswitch_output_port_sec_op(struct ovn_port *op, } } ds_put_cstr(actions, "output;"); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_OUT_PORT_SEC_L2, - 50, ds_cstr(match), ds_cstr(actions), - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_OUT_PORT_SEC_L2, 50, + ds_cstr(match), ds_cstr(actions), + op->key, &op->nbsp->header_); } else { - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_OUT_PORT_SEC_L2, - 150, ds_cstr(match), "drop;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_OUT_PORT_SEC_L2, 150, + ds_cstr(match), "drop;", op->key, + &op->nbsp->header_); } if (op->nbsp->n_port_security) { @@ -4979,12 +5009,12 @@ skip_port_from_conntrack(struct ovn_datapath *od, struct ovn_port *op, ds_put_format(&match_in, "ip && inport == %s", op->json_key); ds_put_format(&match_out, "ip && outport == %s", op->json_key); - ovn_lflow_add_with_hint(lflows, od, in_stage, priority, - ds_cstr(&match_in), "next;", - &op->nbsp->header_); - ovn_lflow_add_with_hint(lflows, od, out_stage, priority, - ds_cstr(&match_out), "next;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, od, in_stage, priority, + ds_cstr(&match_in), "next;", op->key, + &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, od, out_stage, priority, + ds_cstr(&match_out), "next;", op->key, + &op->nbsp->header_); ds_destroy(&match_in); ds_destroy(&match_out); @@ -5519,7 +5549,8 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, "outport <-> inport; %s };", next_action); ovn_lflow_add_with_hint(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, - ds_cstr(&match), ds_cstr(&actions), stage_hint); + ds_cstr(&match), ds_cstr(&actions), + stage_hint); free(next_action); ds_destroy(&match); @@ -5892,9 +5923,10 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, "&& ip4.src == %s && udp && udp.src == 67 " "&& udp.dst == 68", od->nbs->ports[i]->name, server_mac, server_id); - ovn_lflow_add_with_hint( + ovn_lflow_add_with_lport_and_hint( lflows, od, S_SWITCH_OUT_ACL, 34000, ds_cstr(&match), - dhcp_actions, &od->nbs->ports[i]->dhcpv4_options->header_); + dhcp_actions, od->nbs->ports[i]->name, + &od->nbs->ports[i]->dhcpv4_options->header_); } } @@ -5918,9 +5950,9 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, "&& ip6.src == %s && udp && udp.src == 547 " "&& udp.dst == 546", od->nbs->ports[i]->name, server_mac, server_ip); - ovn_lflow_add_with_hint( + ovn_lflow_add_with_lport_and_hint( lflows, od, S_SWITCH_OUT_ACL, 34000, ds_cstr(&match), - dhcp6_actions, + dhcp6_actions, od->nbs->ports[i]->name, &od->nbs->ports[i]->dhcpv6_options->header_); } } @@ -6632,7 +6664,7 @@ build_lswitch_rport_arp_req_flows(struct ovn_port *op, static void build_dhcpv4_options_flows(struct ovn_port *op, struct lport_addresses *lsp_addrs, - const char *json_key, bool is_external, + struct ovn_port *inport, bool is_external, struct hmap *lflows) { struct ds match = DS_EMPTY_INITIALIZER; @@ -6649,18 +6681,17 @@ build_dhcpv4_options_flows(struct ovn_port *op, &match, "inport == %s && eth.src == %s && " "ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && " "udp.src == 68 && udp.dst == 67", - json_key, lsp_addrs->ea_s); + inport->json_key, lsp_addrs->ea_s); if (is_external) { ds_put_format(&match, " && is_chassis_resident(%s)", op->json_key); } - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_DHCP_OPTIONS, 100, - ds_cstr(&match), - ds_cstr(&options_action), - &op->nbsp->dhcpv4_options->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_DHCP_OPTIONS, 100, ds_cstr(&match), + ds_cstr(&options_action), inport->key, + &op->nbsp->dhcpv4_options->header_); ds_clear(&match); /* Allow ip4.src = OFFER_IP and * ip4.dst = {SERVER_IP, 255.255.255.255} for the below @@ -6673,18 +6704,17 @@ build_dhcpv4_options_flows(struct ovn_port *op, ds_put_format( &match, "inport == %s && eth.src == %s && " "%s && udp.src == 68 && udp.dst == 67", - json_key, lsp_addrs->ea_s, ds_cstr(&ipv4_addr_match)); + inport->json_key, lsp_addrs->ea_s, ds_cstr(&ipv4_addr_match)); if (is_external) { ds_put_format(&match, " && is_chassis_resident(%s)", op->json_key); } - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_DHCP_OPTIONS, 100, - ds_cstr(&match), - ds_cstr(&options_action), - &op->nbsp->dhcpv4_options->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_DHCP_OPTIONS, 100, ds_cstr(&match), + ds_cstr(&options_action), inport->key, + &op->nbsp->dhcpv4_options->header_); ds_clear(&match); /* If REGBIT_DHCP_OPTS_RESULT is set, it means the @@ -6693,18 +6723,17 @@ build_dhcpv4_options_flows(struct ovn_port *op, &match, "inport == %s && eth.src == %s && " "ip4 && udp.src == 68 && udp.dst == 67" " && "REGBIT_DHCP_OPTS_RESULT, - json_key, lsp_addrs->ea_s); + inport->json_key, lsp_addrs->ea_s); if (is_external) { ds_put_format(&match, " && is_chassis_resident(%s)", op->json_key); } - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_DHCP_RESPONSE, 100, - ds_cstr(&match), - ds_cstr(&response_action), - &op->nbsp->dhcpv4_options->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_DHCP_RESPONSE, 100, + ds_cstr(&match), ds_cstr(&response_action), inport->key, + &op->nbsp->dhcpv4_options->header_); ds_destroy(&options_action); ds_destroy(&response_action); ds_destroy(&ipv4_addr_match); @@ -6717,7 +6746,7 @@ build_dhcpv4_options_flows(struct ovn_port *op, static void build_dhcpv6_options_flows(struct ovn_port *op, struct lport_addresses *lsp_addrs, - const char *json_key, bool is_external, + struct ovn_port *inport, bool is_external, struct hmap *lflows) { struct ds match = DS_EMPTY_INITIALIZER; @@ -6733,27 +6762,25 @@ build_dhcpv6_options_flows(struct ovn_port *op, &match, "inport == %s && eth.src == %s" " && ip6.dst == ff02::1:2 && udp.src == 546 &&" " udp.dst == 547", - json_key, lsp_addrs->ea_s); + inport->json_key, lsp_addrs->ea_s); if (is_external) { ds_put_format(&match, " && is_chassis_resident(%s)", op->json_key); } - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_DHCP_OPTIONS, 100, - ds_cstr(&match), - ds_cstr(&options_action), - &op->nbsp->dhcpv6_options->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_DHCP_OPTIONS, 100, ds_cstr(&match), + ds_cstr(&options_action), inport->key, + &op->nbsp->dhcpv6_options->header_); /* If REGBIT_DHCP_OPTS_RESULT is set to 1, it means the * put_dhcpv6_opts action is successful */ ds_put_cstr(&match, " && "REGBIT_DHCP_OPTS_RESULT); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_DHCP_RESPONSE, 100, - ds_cstr(&match), - ds_cstr(&response_action), - &op->nbsp->dhcpv6_options->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_DHCP_RESPONSE, 100, + ds_cstr(&match), ds_cstr(&response_action), inport->key, + &op->nbsp->dhcpv6_options->header_); ds_destroy(&options_action); ds_destroy(&response_action); break; @@ -6782,10 +6809,10 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op, port->json_key, op->lsp_addrs[i].ea_s, op->json_key, rp->lsp_addrs[k].ipv4_addrs[l].addr_s); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_EXTERNAL_PORT, - 100, ds_cstr(&match), "drop;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_EXTERNAL_PORT, 100, + ds_cstr(&match), "drop;", port->key, + &op->nbsp->header_); } for (size_t l = 0; l < rp->lsp_addrs[k].n_ipv6_addrs; l++) { ds_clear(&match); @@ -6798,10 +6825,10 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op, rp->lsp_addrs[k].ipv6_addrs[l].addr_s, rp->lsp_addrs[k].ipv6_addrs[l].sn_addr_s, rp->lsp_addrs[k].ipv6_addrs[l].addr_s); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_EXTERNAL_PORT, 100, - ds_cstr(&match), "drop;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint( + lflows, op->od, S_SWITCH_IN_EXTERNAL_PORT, 100, + ds_cstr(&match), "drop;", port->key, + &op->nbsp->header_); } ds_clear(&match); @@ -6812,10 +6839,11 @@ build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op, port->json_key, op->lsp_addrs[i].ea_s, rp->lsp_addrs[k].ea_s, op->json_key); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_EXTERNAL_PORT, - 100, ds_cstr(&match), "drop;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_EXTERNAL_PORT, + 100, ds_cstr(&match), + "drop;", port->key, + &op->nbsp->header_); } } } @@ -6921,9 +6949,10 @@ build_lswitch_arp_nd_responder_skip_local(struct ovn_port *op, (!strcmp(op->nbsp->type, "vtep"))) { ds_clear(match); ds_put_format(match, "inport == %s", op->json_key); - ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, - 100, ds_cstr(match), "next;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_ARP_ND_RSP, 100, + ds_cstr(match), "next;", op->key, + &op->nbsp->header_); } } } @@ -6980,10 +7009,11 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, "bind_vport(%s, inport); " "next;", op->json_key); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_ARP_ND_RSP, 100, - ds_cstr(match), ds_cstr(actions), - &vp->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_ARP_ND_RSP, 100, + ds_cstr(match), + ds_cstr(actions), vparent, + &vp->nbsp->header_); } free(tokstr); @@ -7046,10 +7076,11 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, * network is not working as configured, so dropping the * request would frustrate that intent.) */ ds_put_format(match, " && inport == %s", op->json_key); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_ARP_ND_RSP, 100, - ds_cstr(match), "next;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_ARP_ND_RSP, + 100, ds_cstr(match), + "next;", op->key, + &op->nbsp->header_); } /* For ND solicitations, we need to listen for both the @@ -7088,10 +7119,11 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, /* Do not reply to a solicitation from the port that owns * the address (otherwise DAD detection will fail). */ ds_put_format(match, " && inport == %s", op->json_key); - ovn_lflow_add_with_hint(lflows, op->od, - S_SWITCH_IN_ARP_ND_RSP, 100, - ds_cstr(match), "next;", - &op->nbsp->header_); + ovn_lflow_add_with_lport_and_hint(lflows, op->od, + S_SWITCH_IN_ARP_ND_RSP, + 100, ds_cstr(match), + "next;", op->key, + &op->nbsp->header_); } } } @@ -7231,17 +7263,17 @@ build_lswitch_dhcp_options_and_response(struct ovn_port *op, for (size_t j = 0; j < op->od->n_localnet_ports; j++) { build_dhcpv4_options_flows( op, &op->lsp_addrs[i], - op->od->localnet_ports[j]->json_key, is_external, + op->od->localnet_ports[j], is_external, lflows); build_dhcpv6_options_flows( op, &op->lsp_addrs[i], - op->od->localnet_ports[j]->json_key, is_external, + op->od->localnet_ports[j], is_external, lflows); } } else { - build_dhcpv4_options_flows(op, &op->lsp_addrs[i], op->json_key, + build_dhcpv4_options_flows(op, &op->lsp_addrs[i], op, is_external, lflows); - build_dhcpv6_options_flows(op, &op->lsp_addrs[i], op->json_key, + build_dhcpv6_options_flows(op, &op->lsp_addrs[i], op, is_external, lflows); } } @@ -12480,6 +12512,12 @@ build_lflows(struct northd_context *ctx, struct hmap *datapaths, sbrec_logical_flow_set_priority(sbflow, lflow->priority); sbrec_logical_flow_set_match(sbflow, lflow->match); sbrec_logical_flow_set_actions(sbflow, lflow->actions); + if (lflow->io_port) { + struct smap tags = SMAP_INITIALIZER(&tags); + smap_add(&tags, "in_out_port", lflow->io_port); + sbrec_logical_flow_set_tags(sbflow, &tags); + smap_destroy(&tags); + } /* Trim the source locator lflow->where, which looks something like * "ovn/northd/ovn-northd.c:1234", down to just the part following the -- 2.30.2 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev