From patchwork Thu Mar 4 04:10:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 1447082 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Drcq92KSWz9sRf for ; Thu, 4 Mar 2021 15:10:45 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 34D1E4EBF0; Thu, 4 Mar 2021 04:10:43 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3QQcgwib7HNU; Thu, 4 Mar 2021 04:10:38 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTP id 7F3C74EBCF; Thu, 4 Mar 2021 04:10:37 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9CACFC0001; Thu, 4 Mar 2021 04:10:35 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 250CDC000F for ; Thu, 4 Mar 2021 04:10:33 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 21D226FB11 for ; Thu, 4 Mar 2021 04:10:31 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VPSnqwGGHd99 for ; Thu, 4 Mar 2021 04:10:25 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by smtp3.osuosl.org (Postfix) with ESMTPS id 57B156F4D5 for ; Thu, 4 Mar 2021 04:10:24 +0000 (UTC) X-Originating-IP: 75.54.222.30 Received: from sigfpe.attlocal.net (75-54-222-30.lightspeed.rdcyca.sbcglobal.net [75.54.222.30]) (Authenticated sender: blp@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 57759FF806; Thu, 4 Mar 2021 04:10:21 +0000 (UTC) From: Ben Pfaff To: dev@openvswitch.org Date: Wed, 3 Mar 2021 20:10:04 -0800 Message-Id: <20210304041012.4128938-4-blp@ovn.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210304041012.4128938-1-blp@ovn.org> References: <20210304041012.4128938-1-blp@ovn.org> MIME-Version: 1.0 Cc: Ben Pfaff Subject: [ovs-dev] [PATCH ovn 03/11] ovn-northd-ddlog: Improve type safety for datapath stages. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Until now, whether a logical flow stage was for a logical router or switch, whether it was ingress or egress, and what particular stage it was were each separate attributes. It was possible to create an invalid stage, e.g. a "logical router" stage that was actually present only in logical switches. This would result in a bug. This commit makes such bugs much harder to cause. They will generally become compile-time errors. This code refactoring shouldn't change ovn-northd-ddlog behavior. Signed-off-by: Ben Pfaff --- northd/ovn_northd.dl | 788 ++++++++++++++++++++----------------------- 1 file changed, 365 insertions(+), 423 deletions(-) diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl index 4482cffc0324..7d636df8b69a 100644 --- a/northd/ovn_northd.dl +++ b/northd/ovn_northd.dl @@ -1358,146 +1358,80 @@ nb::Out_Logical_Router_Port(._uuid = _uuid, nb::Logical_Router_Port(._uuid = _uuid, .name = name), LRPIPv6Prefix(_uuid, ipv6_prefix). -typedef Direction = IN | OUT - -typedef PipelineStage = PORT_SEC_L2 - | PORT_SEC_IP - | PORT_SEC_ND - | LOOKUP_FDB - | PUT_FDB - | PRE_ACL - | PRE_LB - | PRE_STATEFUL - | ACL_HINT - | ACL - | QOS_MARK - | QOS_METER - | LB - | STATEFUL - | PRE_HAIRPIN - | HAIRPIN - | NAT_HAIRPIN - | ARP_ND_RSP - | DHCP_OPTIONS - | DHCP_RESPONSE - | DNS_LOOKUP - | DNS_RESPONSE - | EXTERNAL_PORT - | L2_LKUP - | L2_UNKNOWN - | ADMISSION - | LOOKUP_NEIGHBOR - | LEARN_NEIGHBOR - | IP_INPUT - | DEFRAG - | UNSNAT - | DNAT - | ECMP_STATEFUL - | ND_RA_OPTIONS - | ND_RA_RESPONSE - | IP_ROUTING - | IP_ROUTING_ECMP - | POLICY - | POLICY_ECMP - | ARP_RESOLVE - | CHK_PKT_LEN - | LARGER_PKTS - | GW_REDIRECT - | ARP_REQUEST - | UNDNAT - | SNAT - | EGR_LOOP - | DELIVERY - -typedef DatapathType = LSwitch | LRouter +typedef Pipeline = Ingress | Egress typedef Stage = Stage{ - datapath : DatapathType, - direction : Direction, - stage : PipelineStage + pipeline : Pipeline, + table_id : integer, + table_name : string } -function switch_stage(direction: Direction, stage: PipelineStage): Stage = { - Stage{LSwitch, direction, stage} -} - -function router_stage(direction: Direction, stage: PipelineStage): Stage = { - Stage{LRouter, direction, stage} -} - -function stage_id(stage: Stage): (integer, string) = -{ - match ((stage.datapath, stage.direction, stage.stage)) { - /* Logical switch ingress stages. */ - (LSwitch, IN, PORT_SEC_L2) -> (0, "ls_in_port_sec_l2"), - (LSwitch, IN, PORT_SEC_IP) -> (1, "ls_in_port_sec_ip"), - (LSwitch, IN, PORT_SEC_ND) -> (2, "ls_in_port_sec_nd"), - (LSwitch, IN, LOOKUP_FDB) -> (3, "ls_in_lookup_fdb"), - (LSwitch, IN, PUT_FDB) -> (4, "ls_in_put_fdb"), - (LSwitch, IN, PRE_ACL) -> (5, "ls_in_pre_acl"), - (LSwitch, IN, PRE_LB) -> (6, "ls_in_pre_lb"), - (LSwitch, IN, PRE_STATEFUL) -> (7, "ls_in_pre_stateful"), - (LSwitch, IN, ACL_HINT) -> (8, "ls_in_acl_hint"), - (LSwitch, IN, ACL) -> (9, "ls_in_acl"), - (LSwitch, IN, QOS_MARK) -> (10, "ls_in_qos_mark"), - (LSwitch, IN, QOS_METER) -> (11, "ls_in_qos_meter"), - (LSwitch, IN, LB) -> (12, "ls_in_lb"), - (LSwitch, IN, STATEFUL) -> (13, "ls_in_stateful"), - (LSwitch, IN, PRE_HAIRPIN) -> (14, "ls_in_pre_hairpin"), - (LSwitch, IN, NAT_HAIRPIN) -> (15, "ls_in_nat_hairpin"), - (LSwitch, IN, HAIRPIN) -> (16, "ls_in_hairpin"), - (LSwitch, IN, ARP_ND_RSP) -> (17, "ls_in_arp_rsp"), - (LSwitch, IN, DHCP_OPTIONS) -> (18, "ls_in_dhcp_options"), - (LSwitch, IN, DHCP_RESPONSE) -> (19, "ls_in_dhcp_response"), - (LSwitch, IN, DNS_LOOKUP) -> (20, "ls_in_dns_lookup"), - (LSwitch, IN, DNS_RESPONSE) -> (21, "ls_in_dns_response"), - (LSwitch, IN, EXTERNAL_PORT) -> (22, "ls_in_external_port"), - (LSwitch, IN, L2_LKUP) -> (23, "ls_in_l2_lkup"), - (LSwitch, IN, L2_UNKNOWN) -> (24, "ls_in_l2_unknown"), - - /* Logical switch egress stages. */ - (LSwitch, OUT, PRE_LB) -> (0, "ls_out_pre_lb"), - (LSwitch, OUT, PRE_ACL) -> (1, "ls_out_pre_acl"), - (LSwitch, OUT, PRE_STATEFUL) -> (2, "ls_out_pre_stateful"), - (LSwitch, OUT, LB) -> (3, "ls_out_lb"), - (LSwitch, OUT, ACL_HINT) -> (4, "ls_out_acl_hint"), - (LSwitch, OUT, ACL) -> (5, "ls_out_acl"), - (LSwitch, OUT, QOS_MARK) -> (6, "ls_out_qos_mark"), - (LSwitch, OUT, QOS_METER) -> (7, "ls_out_qos_meter"), - (LSwitch, OUT, STATEFUL) -> (8, "ls_out_stateful"), - (LSwitch, OUT, PORT_SEC_IP) -> (9, "ls_out_port_sec_ip"), - (LSwitch, OUT, PORT_SEC_L2) -> (10, "ls_out_port_sec_l2"), - - /* Logical router ingress stages. */ - (LRouter, IN, ADMISSION) -> (0, "lr_in_admission"), - (LRouter, IN, LOOKUP_NEIGHBOR) -> (1, "lr_in_lookup_neighbor"), - (LRouter, IN, LEARN_NEIGHBOR) -> (2, "lr_in_learn_neighbor"), - (LRouter, IN, IP_INPUT) -> (3, "lr_in_ip_input"), - (LRouter, IN, DEFRAG) -> (4, "lr_in_defrag"), - (LRouter, IN, UNSNAT) -> (5, "lr_in_unsnat"), - (LRouter, IN, DNAT) -> (6, "lr_in_dnat"), - (LRouter, IN, ECMP_STATEFUL) -> (7, "lr_in_ecmp_stateful"), - (LRouter, IN, ND_RA_OPTIONS) -> (8, "lr_in_nd_ra_options"), - (LRouter, IN, ND_RA_RESPONSE)-> (9, "lr_in_nd_ra_response"), - (LRouter, IN, IP_ROUTING) -> (10, "lr_in_ip_routing"), - (LRouter, IN, IP_ROUTING_ECMP) -> (11, "lr_in_ip_routing_ecmp"), - (LRouter, IN, POLICY) -> (12, "lr_in_policy"), - (LRouter, IN, POLICY_ECMP) -> (13, "lr_in_policy_ecmp"), - (LRouter, IN, ARP_RESOLVE) -> (14, "lr_in_arp_resolve"), - (LRouter, IN, CHK_PKT_LEN) -> (15, "lr_in_chk_pkt_len"), - (LRouter, IN, LARGER_PKTS) -> (16, "lr_in_larger_pkts"), - (LRouter, IN, GW_REDIRECT) -> (17, "lr_in_gw_redirect"), - (LRouter, IN, ARP_REQUEST) -> (18, "lr_in_arp_request"), - - /* Logical router egress stages. */ - (LRouter, OUT, UNDNAT) -> (0, "lr_out_undnat"), - (LRouter, OUT, SNAT) -> (1, "lr_out_snat"), - (LRouter, OUT, EGR_LOOP) -> (2, "lr_out_egr_loop"), - (LRouter, OUT, DELIVERY) -> (3, "lr_out_delivery"), - - _ -> (64'hffffffffffffffff, "") /* alternatively crash? */ - } -} +/* Logical switch ingress stages. */ +function s_SWITCH_IN_PORT_SEC_L2(): Stage { Stage{Ingress, 0, "ls_in_port_sec_l2"} } +function s_SWITCH_IN_PORT_SEC_IP(): Stage { Stage{Ingress, 1, "ls_in_port_sec_ip"} } +function s_SWITCH_IN_PORT_SEC_ND(): Stage { Stage{Ingress, 2, "ls_in_port_sec_nd"} } +function s_SWITCH_IN_LOOKUP_FDB(): Stage { Stage{Ingress, 3, "ls_in_lookup_fdb"} } +function s_SWITCH_IN_PUT_FDB(): Stage { Stage{Ingress, 4, "ls_in_put_fdb"} } +function s_SWITCH_IN_PRE_ACL(): Stage { Stage{Ingress, 5, "ls_in_pre_acl"} } +function s_SWITCH_IN_PRE_LB(): Stage { Stage{Ingress, 6, "ls_in_pre_lb"} } +function s_SWITCH_IN_PRE_STATEFUL(): Stage { Stage{Ingress, 7, "ls_in_pre_stateful"} } +function s_SWITCH_IN_ACL_HINT(): Stage { Stage{Ingress, 8, "ls_in_acl_hint"} } +function s_SWITCH_IN_ACL(): Stage { Stage{Ingress, 9, "ls_in_acl"} } +function s_SWITCH_IN_QOS_MARK(): Stage { Stage{Ingress, 10, "ls_in_qos_mark"} } +function s_SWITCH_IN_QOS_METER(): Stage { Stage{Ingress, 11, "ls_in_qos_meter"} } +function s_SWITCH_IN_LB(): Stage { Stage{Ingress, 12, "ls_in_lb"} } +function s_SWITCH_IN_STATEFUL(): Stage { Stage{Ingress, 13, "ls_in_stateful"} } +function s_SWITCH_IN_PRE_HAIRPIN(): Stage { Stage{Ingress, 14, "ls_in_pre_hairpin"} } +function s_SWITCH_IN_NAT_HAIRPIN(): Stage { Stage{Ingress, 15, "ls_in_nat_hairpin"} } +function s_SWITCH_IN_HAIRPIN(): Stage { Stage{Ingress, 16, "ls_in_hairpin"} } +function s_SWITCH_IN_ARP_ND_RSP(): Stage { Stage{Ingress, 17, "ls_in_arp_rsp"} } +function s_SWITCH_IN_DHCP_OPTIONS(): Stage { Stage{Ingress, 18, "ls_in_dhcp_options"} } +function s_SWITCH_IN_DHCP_RESPONSE(): Stage { Stage{Ingress, 19, "ls_in_dhcp_response"} } +function s_SWITCH_IN_DNS_LOOKUP(): Stage { Stage{Ingress, 20, "ls_in_dns_lookup"} } +function s_SWITCH_IN_DNS_RESPONSE(): Stage { Stage{Ingress, 21, "ls_in_dns_response"} } +function s_SWITCH_IN_EXTERNAL_PORT(): Stage { Stage{Ingress, 22, "ls_in_external_port"} } +function s_SWITCH_IN_L2_LKUP(): Stage { Stage{Ingress, 23, "ls_in_l2_lkup"} } +function s_SWITCH_IN_L2_UNKNOWN(): Stage { Stage{Ingress, 24, "ls_in_l2_unknown"} } + +/* Logical switch egress stages. */ +function s_SWITCH_OUT_PRE_LB(): Stage { Stage{ Egress, 0, "ls_out_pre_lb"} } +function s_SWITCH_OUT_PRE_ACL(): Stage { Stage{ Egress, 1, "ls_out_pre_acl"} } +function s_SWITCH_OUT_PRE_STATEFUL(): Stage { Stage{ Egress, 2, "ls_out_pre_stateful"} } +function s_SWITCH_OUT_LB(): Stage { Stage{ Egress, 3, "ls_out_lb"} } +function s_SWITCH_OUT_ACL_HINT(): Stage { Stage{ Egress, 4, "ls_out_acl_hint"} } +function s_SWITCH_OUT_ACL(): Stage { Stage{ Egress, 5, "ls_out_acl"} } +function s_SWITCH_OUT_QOS_MARK(): Stage { Stage{ Egress, 6, "ls_out_qos_mark"} } +function s_SWITCH_OUT_QOS_METER(): Stage { Stage{ Egress, 7, "ls_out_qos_meter"} } +function s_SWITCH_OUT_STATEFUL(): Stage { Stage{ Egress, 8, "ls_out_stateful"} } +function s_SWITCH_OUT_PORT_SEC_IP(): Stage { Stage{ Egress, 9, "ls_out_port_sec_ip"} } +function s_SWITCH_OUT_PORT_SEC_L2(): Stage { Stage{ Egress, 10, "ls_out_port_sec_l2"} } + +/* Logical router ingress stages. */ +function s_ROUTER_IN_ADMISSION(): Stage { Stage{Ingress, 0, "lr_in_admission"} } +function s_ROUTER_IN_LOOKUP_NEIGHBOR(): Stage { Stage{Ingress, 1, "lr_in_lookup_neighbor"} } +function s_ROUTER_IN_LEARN_NEIGHBOR(): Stage { Stage{Ingress, 2, "lr_in_learn_neighbor"} } +function s_ROUTER_IN_IP_INPUT(): Stage { Stage{Ingress, 3, "lr_in_ip_input"} } +function s_ROUTER_IN_DEFRAG(): Stage { Stage{Ingress, 4, "lr_in_defrag"} } +function s_ROUTER_IN_UNSNAT(): Stage { Stage{Ingress, 5, "lr_in_unsnat"} } +function s_ROUTER_IN_DNAT(): Stage { Stage{Ingress, 6, "lr_in_dnat"} } +function s_ROUTER_IN_ECMP_STATEFUL(): Stage { Stage{Ingress, 7, "lr_in_ecmp_stateful"} } +function s_ROUTER_IN_ND_RA_OPTIONS(): Stage { Stage{Ingress, 8, "lr_in_nd_ra_options"} } +function s_ROUTER_IN_ND_RA_RESPONSE(): Stage { Stage{Ingress, 9, "lr_in_nd_ra_response"} } +function s_ROUTER_IN_IP_ROUTING(): Stage { Stage{Ingress, 10, "lr_in_ip_routing"} } +function s_ROUTER_IN_IP_ROUTING_ECMP(): Stage { Stage{Ingress, 11, "lr_in_ip_routing_ecmp"} } +function s_ROUTER_IN_POLICY(): Stage { Stage{Ingress, 12, "lr_in_policy"} } +function s_ROUTER_IN_POLICY_ECMP(): Stage { Stage{Ingress, 13, "lr_in_policy_ecmp"} } +function s_ROUTER_IN_ARP_RESOLVE(): Stage { Stage{Ingress, 14, "lr_in_arp_resolve"} } +function s_ROUTER_IN_CHK_PKT_LEN(): Stage { Stage{Ingress, 15, "lr_in_chk_pkt_len"} } +function s_ROUTER_IN_LARGER_PKTS(): Stage { Stage{Ingress, 16, "lr_in_larger_pkts"} } +function s_ROUTER_IN_GW_REDIRECT(): Stage { Stage{Ingress, 17, "lr_in_gw_redirect"} } +function s_ROUTER_IN_ARP_REQUEST(): Stage { Stage{Ingress, 18, "lr_in_arp_request"} } + +/* Logical router egress stages. */ +function s_ROUTER_OUT_UNDNAT(): Stage { Stage{ Egress, 0, "lr_out_undnat"} } +function s_ROUTER_OUT_SNAT(): Stage { Stage{ Egress, 1, "lr_out_snat"} } +function s_ROUTER_OUT_EGR_LOOP(): Stage { Stage{ Egress, 2, "lr_out_egr_loop"} } +function s_ROUTER_OUT_DELIVERY(): Stage { Stage{ Egress, 3, "lr_out_delivery"} } /* * OVS register usage: @@ -1685,9 +1619,8 @@ AggregatedFlow(.logical_datapaths = set_singleton(logical_datapath), AnnotatedFlow(Flow{logical_datapath, stage, priority, __match, actions, external_ids}, false). for (f in AggregatedFlow()) { - (var table_id, var table_name) = stage_id(f.stage) in - var pipeline = if (f.stage.direction == IN) "ingress" else "egress" in - var external_ids = f.external_ids.insert_imm("stage-name", table_name) in + var pipeline = if (f.stage.pipeline == Ingress) "ingress" else "egress" in + var external_ids = f.external_ids.insert_imm("stage-name", f.stage.table_name) in if (f.logical_datapaths.size() == 1) { Some{var dp} = f.logical_datapaths.nth(0) in sb::Out_Logical_Flow( @@ -1695,7 +1628,7 @@ for (f in AggregatedFlow()) { .logical_datapath = Some{dp}, .logical_dp_group = None, .pipeline = pipeline, - .table_id = table_id, + .table_id = f.stage.table_id, .priority = f.priority, .__match = f.__match, .actions = f.actions, @@ -1707,7 +1640,7 @@ for (f in AggregatedFlow()) { .logical_datapath = None, .logical_dp_group = Some{group_uuid}, .pipeline = pipeline, - .table_id = table_id, + .table_id = f.stage.table_id, .priority = f.priority, .__match = f.__match, .actions = f.actions, @@ -1719,7 +1652,7 @@ for (f in AggregatedFlow()) { /* Logical flows for forwarding groups. */ Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 50, .__match = __match, .actions = actions, @@ -1748,7 +1681,7 @@ function escape_child_ports(child_port: Set): string { escaped.join(",") } Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 50, .__match = __match, .actions = actions, @@ -1768,7 +1701,7 @@ for (sw in &Switch()) { if (not sw.is_vlan_transparent) { /* Block logical VLANs. */ Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_L2), + .stage = s_SWITCH_IN_PORT_SEC_L2(), .priority = 100, .__match = "vlan.present", .actions = "drop;", @@ -1777,7 +1710,7 @@ for (sw in &Switch()) { /* Broadcast/multicast source address is invalid */ Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_L2), + .stage = s_SWITCH_IN_PORT_SEC_L2(), .priority = 100, .__match = "eth.src[40]", .actions = "drop;", @@ -1792,7 +1725,7 @@ function join(strings: Set, sep: string): string { } function build_port_security_ipv6_flow( - pipeline: Direction, + pipeline: Pipeline, ea: eth_addr, ipv6_addrs: Vec): string = { @@ -1802,14 +1735,14 @@ function build_port_security_ipv6_flow( ip6_addrs.push(ipv6_string_mapped(in6_generate_lla(ea))); /* Allow ip6.dst=ff00::/8 for multicast packets */ - if (pipeline == OUT) { + if (pipeline == Egress) { ip6_addrs.push("ff00::/8") }; for (addr in ipv6_addrs) { ip6_addrs.push(ipv6_netaddr_match_network(addr)) }; - var dir = if (pipeline == IN) { "src" } else { "dst" }; + var dir = if (pipeline == Ingress) { "src" } else { "dst" }; " && ip6.${dir} == {" ++ ip6_addrs.join(", ") ++ "}" } @@ -1839,26 +1772,26 @@ for (&Switch(.ls =ls)) { /* Ingress and Egress Pre-ACL Table (Priority 0): Packets are * allowed by default. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_ACL), + .stage = s_SWITCH_IN_PRE_ACL(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_ACL), + .stage = s_SWITCH_OUT_PRE_ACL(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_ACL), + .stage = s_SWITCH_IN_PRE_ACL(), .priority = 110, .__match = "eth.dst == $svc_monitor_mac", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_ACL), + .stage = s_SWITCH_OUT_PRE_ACL(), .priority = 110, .__match = "eth.src == $svc_monitor_mac", .actions = "next;", @@ -1886,13 +1819,13 @@ for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "router"}, * on hostA, not hostB. This would only work with * distributed conntrack state across all chassis. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_ACL), + .stage = s_SWITCH_IN_PRE_ACL(), .priority = 110, .__match = "ip && inport == ${lsp_name}", .actions = "next;", .external_ids = stage_hint(lsp._uuid)); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_ACL), + .stage = s_SWITCH_OUT_PRE_ACL(), .priority = 110, .__match = "ip && outport == ${lsp_name}", .actions = "next;", @@ -1903,13 +1836,13 @@ for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = "localnet"}, .json_name = lsp_name, .sw = &Switch{.ls = ls, .has_stateful_acl = true})) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_ACL), + .stage = s_SWITCH_IN_PRE_ACL(), .priority = 110, .__match = "ip && inport == ${lsp_name}", .actions = "next;", .external_ids = stage_hint(lsp._uuid)); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_ACL), + .stage = s_SWITCH_OUT_PRE_ACL(), .priority = 110, .__match = "ip && outport == ${lsp_name}", .actions = "next;", @@ -1922,14 +1855,14 @@ for (&Switch(.ls = ls, .has_stateful_acl = true)) { * Not to do conntrack on ND and ICMP destination * unreachable packets. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_ACL), + .stage = s_SWITCH_IN_PRE_ACL(), .priority = 110, .__match = "nd || nd_rs || nd_ra || mldv1 || mldv2 || " "(udp && udp.src == 546 && udp.dst == 547)", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_ACL), + .stage = s_SWITCH_OUT_PRE_ACL(), .priority = 110, .__match = "nd || nd_rs || nd_ra || mldv1 || mldv2 || " "(udp && udp.src == 546 && udp.dst == 547)", @@ -1945,13 +1878,13 @@ for (&Switch(.ls = ls, .has_stateful_acl = true)) { * 'REGBIT_CONNTRACK_DEFRAG' is set to let the pre-stateful table send * it to conntrack for tracking and defragmentation. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_ACL), + .stage = s_SWITCH_IN_PRE_ACL(), .priority = 100, .__match = "ip", .actions = "${rEGBIT_CONNTRACK_DEFRAG()} = 1; next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_ACL), + .stage = s_SWITCH_OUT_PRE_ACL(), .priority = 100, .__match = "ip", .actions = "${rEGBIT_CONNTRACK_DEFRAG()} = 1; next;", @@ -1963,13 +1896,13 @@ for (&Switch(.ls = ls)) { /* Do not send ND packets to conntrack */ var __match = "nd || nd_rs || nd_ra || mldv1 || mldv2" in { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_LB), + .stage = s_SWITCH_IN_PRE_LB(), .priority = 110, .__match = __match, .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_LB), + .stage = s_SWITCH_OUT_PRE_LB(), .priority = 110, .__match = __match, .actions = "next;", @@ -1978,13 +1911,13 @@ for (&Switch(.ls = ls)) { /* Do not send service monitor packets to conntrack. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_LB), + .stage = s_SWITCH_IN_PRE_LB(), .priority = 110, .__match = "eth.dst == $svc_monitor_mac", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_LB), + .stage = s_SWITCH_OUT_PRE_LB(), .priority = 110, .__match = "eth.src == $svc_monitor_mac", .actions = "next;", @@ -1992,13 +1925,13 @@ for (&Switch(.ls = ls)) { /* Allow all packets to go to next tables by default. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_LB), + .stage = s_SWITCH_IN_PRE_LB(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_LB), + .stage = s_SWITCH_OUT_PRE_LB(), .priority = 0, .__match = "1", .actions = "next;", @@ -2008,13 +1941,13 @@ for (&Switch(.ls = ls)) { for (&SwitchPort(.lsp = lsp, .json_name = lsp_name, .sw = &Switch{.ls = ls})) if (lsp.__type == "router" or lsp.__type == "localnet") { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_LB), + .stage = s_SWITCH_IN_PRE_LB(), .priority = 110, .__match = "ip && inport == ${lsp_name}", .actions = "next;", .external_ids = stage_hint(lsp._uuid)); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_LB), + .stage = s_SWITCH_OUT_PRE_LB(), .priority = 110, .__match = "ip && outport == ${lsp_name}", .actions = "next;", @@ -2085,7 +2018,7 @@ LoadBalancerEmptyEvents(lb) :- global_events or local_events. Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PRE_LB), + .stage = s_SWITCH_IN_PRE_LB(), .priority = 130, .__match = __match, .actions = __action, @@ -2130,13 +2063,13 @@ Flow(.logical_datapath = sw.ls._uuid, */ for (sw in &Switch(.has_lb_vip = true)) { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PRE_LB), + .stage = s_SWITCH_IN_PRE_LB(), .priority = 100, .__match = "ip", .actions = "${rEGBIT_CONNTRACK_DEFRAG()} = 1; next;", .external_ids = map_empty()); Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, PRE_LB), + .stage = s_SWITCH_OUT_PRE_LB(), .priority = 100, .__match = "ip", .actions = "${rEGBIT_CONNTRACK_DEFRAG()} = 1; next;", @@ -2148,13 +2081,13 @@ for (&Switch(.ls = ls)) { /* Ingress and Egress pre-stateful Table (Priority 0): Packets are * allowed by default. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_STATEFUL), + .stage = s_SWITCH_IN_PRE_STATEFUL(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_STATEFUL), + .stage = s_SWITCH_OUT_PRE_STATEFUL(), .priority = 0, .__match = "1", .actions = "next;", @@ -2163,13 +2096,13 @@ for (&Switch(.ls = ls)) { /* If REGBIT_CONNTRACK_DEFRAG is set as 1, then the packets should be * sent to conntrack for tracking and defragmentation. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PRE_STATEFUL), + .stage = s_SWITCH_IN_PRE_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_DEFRAG()} == 1", .actions = "ct_next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PRE_STATEFUL), + .stage = s_SWITCH_OUT_PRE_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_DEFRAG()} == 1", .actions = "ct_next;", @@ -2236,7 +2169,7 @@ function oVN_ACL_PRI_OFFSET(): integer = 1000 */ relation Reject( lsuuid: uuid, - pipeline: string, + pipeline: Pipeline, stage: Stage, acl: nb::ACL, fair_meter: bool, @@ -2244,6 +2177,13 @@ relation Reject( extra_actions: string) /* build_reject_acl_rules() */ +function next_to_stage(stage: Stage): string { + var pipeline = match (stage.pipeline) { + Ingress -> "ingress", + Egress -> "egress" + }; + "next(pipeline=${pipeline},table=${stage.table_id})" +} for (Reject(lsuuid, pipeline, stage, acl, fair_meter, extra_match_, extra_actions_)) { var extra_match = match (extra_match_) { "" -> "", @@ -2253,16 +2193,16 @@ for (Reject(lsuuid, pipeline, stage, acl, fair_meter, extra_match_, extra_action "" -> "", s -> "${s} " } in - var next = match (pipeline == "ingress") { - true -> "next(pipeline=egress,table=${stage_id(switch_stage(OUT, QOS_MARK)).0})", - false -> "next(pipeline=ingress,table=${stage_id(switch_stage(IN, L2_LKUP)).0})" + var next_stage = match (pipeline) { + Ingress -> s_SWITCH_OUT_QOS_MARK(), + Egress -> s_SWITCH_IN_L2_LKUP() } in var acl_log = build_acl_log(acl, fair_meter) in var __match = extra_match ++ acl.__match in var actions = acl_log ++ extra_actions ++ "reg0 = 0; " "reject { " "/* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ " - "outport <-> inport; ${next}; };" in + "outport <-> inport; ${next_to_stage(next_stage)}; };" in Flow(.logical_datapath = lsuuid, .stage = stage, .priority = acl.priority + oVN_ACL_PRI_OFFSET(), @@ -2279,13 +2219,13 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * default. A related rule at priority 1 is added below if there * are any stateful ACLs in this datapath. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 0, .__match = "1", .actions = "next;", @@ -2314,13 +2254,13 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * Subsequent packets will hit the flow at priority 0 that just * uses "next;". */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 1, .__match = "ip && (!ct.est || (ct.est && ct_label.blocked == 1))", .actions = "${rEGBIT_CONNTRACK_COMMIT()} = 1; next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 1, .__match = "ip && (!ct.est || (ct.est && ct_label.blocked == 1))", .actions = "${rEGBIT_CONNTRACK_COMMIT()} = 1; next;", @@ -2334,13 +2274,13 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * * This is enforced at a higher priority than ACLs can be defined. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 65535, .__match = "ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)", .actions = "drop;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 65535, .__match = "ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)", .actions = "drop;", @@ -2356,14 +2296,14 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * * This is enforced at a higher priority than ACLs can be defined. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 65535, .__match = "ct.est && !ct.rel && !ct.new && !ct.inv " "&& ct.rpl && ct_label.blocked == 0", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 65535, .__match = "ct.est && !ct.rel && !ct.new && !ct.inv " "&& ct.rpl && ct_label.blocked == 0", @@ -2382,14 +2322,14 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * related traffic such as an ICMP Port Unreachable through * that's generated from a non-listening UDP port. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 65535, .__match = "!ct.est && ct.rel && !ct.new && !ct.inv " "&& ct_label.blocked == 0", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 65535, .__match = "!ct.est && ct.rel && !ct.new && !ct.inv " "&& ct_label.blocked == 0", @@ -2400,13 +2340,13 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * * Not to do conntrack on ND packets. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 65535, .__match = "nd || nd_ra || nd_rs || mldv1 || mldv2", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 65535, .__match = "nd || nd_ra || nd_rs || mldv1 || mldv2", .actions = "next;", @@ -2418,7 +2358,7 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in */ if (sw.has_dns_records) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 34000, .__match = "udp.src == 53", .actions = if has_stateful "ct_commit; next;" else "next;", @@ -2428,13 +2368,13 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in /* Add a 34000 priority flow to advance the service monitor reply * packets to skip applying ingress ACLs. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ACL), + .stage = s_SWITCH_IN_ACL(), .priority = 34000, .__match = "eth.dst == $svc_monitor_mac", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 34000, .__match = "eth.src == $svc_monitor_mac", .actions = "next;", @@ -2454,8 +2394,8 @@ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in * corresponding to all potential matches are set. */ input relation AclHintStages[Stage] -AclHintStages[switch_stage(IN, ACL_HINT)]. -AclHintStages[switch_stage(OUT, ACL_HINT)]. +AclHintStages[s_SWITCH_IN_ACL_HINT()]. +AclHintStages[s_SWITCH_OUT_ACL_HINT()]. for (sw in &Switch(.ls = ls)) { for (AclHintStages[stage]) { /* In any case, advance to the next stage. */ @@ -2530,8 +2470,8 @@ for (&SwitchACL(.sw = sw@&Switch{.ls = ls}, .acl = &acl, .has_fair_meter = fair_ /* consider_acl */ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in var ingress = acl.direction == "from-lport" in - var stage = if (ingress) { switch_stage(IN, ACL) } else { switch_stage(OUT, ACL) } in - var pipeline = if ingress "ingress" else "egress" in + var stage = if (ingress) { s_SWITCH_IN_ACL() } else { s_SWITCH_OUT_ACL() } in + var pipeline = if ingress Ingress else Egress in var stage_hint = stage_hint(acl._uuid) in var acl_log = build_acl_log(acl, fair_meter) in if (acl.action == "allow" or acl.action == "allow-related") { @@ -2650,7 +2590,7 @@ for (SwitchPortDHCPv4Options(.port = &SwitchPort{.lsp = lsp, .sw = &sw}, (options.get("server_id"), options.get("server_mac"), options.get("lease_time")) in var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 34000, .__match = "outport == ${json_string_escape(lsp.name)} " "&& eth.src == ${server_mac} " @@ -2670,7 +2610,7 @@ for (SwitchPortDHCPv6Options(.port = &SwitchPort{.lsp = lsp, .sw = &sw}, * server MAC. */ var has_stateful = sw.has_stateful_acl or sw.has_lb_vip in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, ACL), + .stage = s_SWITCH_OUT_ACL(), .priority = 34000, .__match = "outport == ${json_string_escape(lsp.name)} " "&& eth.src == ${server_mac} " @@ -2690,25 +2630,25 @@ QoSAction(qos, k, v) :- /* QoS rules */ for (&Switch(.ls = ls)) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, QOS_MARK), + .stage = s_SWITCH_IN_QOS_MARK(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, QOS_MARK), + .stage = s_SWITCH_OUT_QOS_MARK(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, QOS_METER), + .stage = s_SWITCH_IN_QOS_METER(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, QOS_METER), + .stage = s_SWITCH_OUT_QOS_METER(), .priority = 0, .__match = "1", .actions = "next;", @@ -2718,7 +2658,7 @@ for (&Switch(.ls = ls)) { for (SwitchQoS(.sw = &sw, .qos = &qos)) { var ingress = if (qos.direction == "from-lport") true else false in var pipeline = if ingress "ingress" else "egress" in { - var stage = if (ingress) { switch_stage(IN, QOS_MARK) } else { switch_stage(OUT, QOS_MARK) } in + var stage = if (ingress) { s_SWITCH_IN_QOS_MARK() } else { s_SWITCH_OUT_QOS_MARK() } in /* FIXME: Can value_action be negative? */ for (QoSAction(qos._uuid, key_action, value_action)) { if (key_action == "dscp") { @@ -2746,7 +2686,7 @@ for (SwitchQoS(.sw = &sw, .qos = &qos)) { (burst, rate) } in if (rate != 0) { - var stage = if (ingress) { switch_stage(IN, QOS_METER) } else { switch_stage(OUT, QOS_METER) } in + var stage = if (ingress) { s_SWITCH_IN_QOS_METER() } else { s_SWITCH_OUT_QOS_METER() } in var meter_action = if (burst != 0) { "set_meter(${rate}, ${burst}); next;" } else { @@ -2771,13 +2711,13 @@ for (&Switch(.ls = ls, .has_lb_vip = has_lb_vip)) { /* Ingress and Egress LB Table (Priority 0): Packets are allowed by * default. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, LB), + .stage = s_SWITCH_IN_LB(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, LB), + .stage = s_SWITCH_OUT_LB(), .priority = 0, .__match = "1", .actions = "next;", @@ -2788,13 +2728,13 @@ for (&Switch(.ls = ls, .has_lb_vip = has_lb_vip)) { .json_name = lsp_name, .sw = &Switch{.ls = ls})) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, LB), + .stage = s_SWITCH_IN_LB(), .priority = 65535, .__match = "ip && inport == ${lsp_name}", .actions = "next;", .external_ids = stage_hint(lsp._uuid)); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, LB), + .stage = s_SWITCH_OUT_LB(), .priority = 65535, .__match = "ip && outport == ${lsp_name}", .actions = "next;", @@ -2807,13 +2747,13 @@ for (&Switch(.ls = ls, .has_lb_vip = has_lb_vip)) { * * Send established traffic through conntrack for just NAT. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, LB), + .stage = s_SWITCH_IN_LB(), .priority = 65534, .__match = "ct.est && !ct.rel && !ct.new && !ct.inv && ct_label.natted == 1", .actions = "${rEGBIT_CONNTRACK_NAT()} = 1; next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, LB), + .stage = s_SWITCH_OUT_LB(), .priority = 65534, .__match = "ct.est && !ct.rel && !ct.new && !ct.inv && ct_label.natted == 1", .actions = "${rEGBIT_CONNTRACK_NAT()} = 1; next;", @@ -2830,13 +2770,13 @@ for (&Switch(.ls = ls)) { /* Ingress and Egress stateful Table (Priority 0): Packets are * allowed by default. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, STATEFUL), + .stage = s_SWITCH_IN_STATEFUL(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, STATEFUL), + .stage = s_SWITCH_OUT_STATEFUL(), .priority = 0, .__match = "1", .actions = "next;", @@ -2847,13 +2787,13 @@ for (&Switch(.ls = ls)) { * any packet that makes it this far is part of a connection we * want to allow to continue. */ Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, STATEFUL), + .stage = s_SWITCH_IN_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_COMMIT()} == 1", .actions = "ct_commit { ct_label.blocked = 0; }; next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, STATEFUL), + .stage = s_SWITCH_OUT_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_COMMIT()} == 1", .actions = "ct_commit { ct_label.blocked = 0; }; next;", @@ -2871,14 +2811,14 @@ for (&Switch(.ls = ls)) { */ for (LbProtocol[protocol]) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, STATEFUL), + .stage = s_SWITCH_IN_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_NAT()} == 1 && ip4 && ${protocol}", .actions = "${rEG_ORIG_DIP_IPV4()} = ip4.dst; " "${rEG_ORIG_TP_DPORT()} = ${protocol}.dst; ct_lb;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, STATEFUL), + .stage = s_SWITCH_IN_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_NAT()} == 1 && ip6 && ${protocol}", .actions = "${rEG_ORIG_DIP_IPV6()} = ip6.dst; " @@ -2887,7 +2827,7 @@ for (&Switch(.ls = ls)) { }; Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, STATEFUL), + .stage = s_SWITCH_OUT_STATEFUL(), .priority = 100, .__match = "${rEGBIT_CONNTRACK_NAT()} == 1", .actions = "ct_lb;", @@ -2945,7 +2885,7 @@ function ct_lb(backends: string, "ct_lb(" ++ args.join("; ") ++ ");" } function build_lb_vip_actions(lbvip: Ref, - table: integer, + stage: Stage, actions0: string): string { var up_backends = set_empty(); for (pair in lbvip.backends) { @@ -2957,7 +2897,7 @@ function build_lb_vip_actions(lbvip: Ref, if (up_backends.is_empty()) { if (map_get_bool_def(lbvip.lb.options, "reject", false)) { - return "reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=${table});};" + return "reg0 = 0; reject { outport <-> inport; ${next_to_stage(stage)};};" } else if (lbvip.health_check.is_some()) { return "drop;" } // else fall through @@ -2968,7 +2908,7 @@ function build_lb_vip_actions(lbvip: Ref, actions0 ++ actions } Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, STATEFUL), + .stage = s_SWITCH_IN_STATEFUL(), .priority = priority, .__match = __match, .actions = actions, @@ -2995,7 +2935,7 @@ Flow(.logical_datapath = sw.ls._uuid, "" }; - build_lb_vip_actions(lbvip, stage_id(switch_stage(OUT, QOS_MARK)).0, actions0 ++ actions1) + build_lb_vip_actions(lbvip, s_SWITCH_OUT_QOS_MARK(), actions0 ++ actions1) }, var __match = "ct.new && " ++ get_match_for_lb_key(lbvip.vip_addr, lbvip.vip_port, lb.protocol, false). @@ -3003,13 +2943,15 @@ Flow(.logical_datapath = sw.ls._uuid, * Packets that don't need hairpinning should continue processing. */ Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, stage), + .stage = stage, .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()) :- &Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}), - var stages = [PRE_HAIRPIN, NAT_HAIRPIN, HAIRPIN], + var stages = [s_SWITCH_IN_PRE_HAIRPIN(), + s_SWITCH_IN_NAT_HAIRPIN(), + s_SWITCH_IN_HAIRPIN()], var stage = FlatMap(stages). for (&Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}, .has_lb_vip = true)) { /* Check if the packet needs to be hairpinned. @@ -3017,7 +2959,7 @@ for (&Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}, .has_lb_vip = true)) { * REGBIT_HAIRPIN_REPLY in the reply direction. */ Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, PRE_HAIRPIN), + .stage = s_SWITCH_IN_PRE_HAIRPIN(), .priority = 100, .__match = "ip && ct.trk", .actions = "${rEGBIT_HAIRPIN()} = chk_lb_hairpin(); " @@ -3028,7 +2970,7 @@ for (&Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}, .has_lb_vip = true)) { /* If packet needs to be hairpinned, snat the src ip with the VIP * for new sessions. */ Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, NAT_HAIRPIN), + .stage = s_SWITCH_IN_NAT_HAIRPIN(), .priority = 100, .__match = "ip && ct.new && ct.trk && ${rEGBIT_HAIRPIN()} == 1", .actions = "ct_snat_to_vip; next;", @@ -3038,7 +2980,7 @@ for (&Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}, .has_lb_vip = true)) { * should already be an SNAT conntrack entry. */ Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, NAT_HAIRPIN), + .stage = s_SWITCH_IN_NAT_HAIRPIN(), .priority = 100, .__match = "ip && ct.est && ct.trk && ${rEGBIT_HAIRPIN()} == 1", .actions = "ct_snat;", @@ -3046,7 +2988,7 @@ for (&Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}, .has_lb_vip = true)) { /* For the reply of hairpinned traffic, snat the src ip to the VIP. */ Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, NAT_HAIRPIN), + .stage = s_SWITCH_IN_NAT_HAIRPIN(), .priority = 90, .__match = "ip && ${rEGBIT_HAIRPIN_REPLY()} == 1", .actions = "ct_snat;", @@ -3057,7 +2999,7 @@ for (&Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid}, .has_lb_vip = true)) { * looped back (i.e., swap ETH addresses and send back on inport). */ Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, HAIRPIN), + .stage = s_SWITCH_IN_HAIRPIN(), .priority = 1, .__match = "(${rEGBIT_HAIRPIN()} == 1 || ${rEGBIT_HAIRPIN_REPLY()} == 1)", .actions = "eth.dst <-> eth.src; outport = inport; flags.loopback = 1; output;", @@ -3080,7 +3022,7 @@ for (&SwitchPort(.lsp = lsp, .sw = &sw, .json_name = json_name, .ps_eth_addresse Some{id} -> "set_queue(${id}); next;" } in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_L2), + .stage = s_SWITCH_IN_PORT_SEC_L2(), .priority = 50, .__match = __match, .actions = actions, @@ -3115,7 +3057,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) " && ip4.dst == 255.255.255.255" " && udp.src == 68 && udp.dst == 67" in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_IP), + .stage = s_SWITCH_IN_PORT_SEC_IP(), .priority = 90, .__match = dhcp_match, .actions = "next;", @@ -3138,7 +3080,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) addrs.join(", ") ++ "}" in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_IP), + .stage = s_SWITCH_IN_PORT_SEC_IP(), .priority = 90, .__match = __match, .actions = "next;", @@ -3153,17 +3095,17 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) " && icmp6.type == {131, 135, 143}" in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_IP), + .stage = s_SWITCH_IN_PORT_SEC_IP(), .priority = 90, .__match = dad_match, .actions = "next;", .external_ids = stage_hint(port.lsp._uuid)) }; var __match = "inport == ${port.json_name} && eth.src == ${ps.ea}" ++ - build_port_security_ipv6_flow(IN, ps.ea, ps.ipv6_addrs) in + build_port_security_ipv6_flow(Ingress, ps.ea, ps.ipv6_addrs) in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_IP), + .stage = s_SWITCH_IN_PORT_SEC_IP(), .priority = 90, .__match = __match, .actions = "next;", @@ -3173,7 +3115,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) var __match = "inport == ${port.json_name} && eth.src == ${ps.ea} && ip" in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_IP), + .stage = s_SWITCH_IN_PORT_SEC_IP(), .priority = 80, .__match = __match, .actions = "drop;", @@ -3221,7 +3163,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) } } in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_ND), + .stage = s_SWITCH_IN_PORT_SEC_ND(), .priority = 90, .__match = __match, .actions = "next;", @@ -3233,7 +3175,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) build_port_security_ipv6_nd_flow(ps.ea, ps.ipv6_addrs) in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_ND), + .stage = s_SWITCH_IN_PORT_SEC_ND(), .priority = 90, .__match = __match, .actions = "next;", @@ -3241,7 +3183,7 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) } }; Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, PORT_SEC_ND), + .stage = s_SWITCH_IN_PORT_SEC_ND(), .priority = 80, .__match = "inport == ${port.json_name} && (arp || nd)", .actions = "drop;", @@ -3253,13 +3195,13 @@ for (SwitchPortPSAddresses(.port = &port@SwitchPort{.sw = &sw}, .ps_addrs = ps) * default goto next. (priority 0)*/ for (&Switch(.ls = ls)) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PORT_SEC_ND), + .stage = s_SWITCH_IN_PORT_SEC_ND(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PORT_SEC_IP), + .stage = s_SWITCH_IN_PORT_SEC_IP(), .priority = 0, .__match = "1", .actions = "next;", @@ -3274,7 +3216,7 @@ for (&SwitchPort(.lsp = lsp, .sw = &sw, .json_name = json_name) (lsp.__type == "localnet" or lsp.__type == "vtep")) { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 100, .__match = "inport == ${json_name}", .actions = "next;", @@ -3295,7 +3237,7 @@ function lsp_is_up(lsp: nb::Logical_Switch_Port): bool = { * port of type 'virtual' and bind that port. * */ Flow(.logical_datapath = sp.sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 100, .__match = "inport == ${vp.json_name} && " "((arp.op == 1 && arp.spa == ${virtual_ip} && arp.tpa == ${virtual_ip}) || " @@ -3338,7 +3280,7 @@ for (CheckLspIsUp[check_lsp_is_up]) { "flags.loopback = 1; " "output;" in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 50, .__match = __match, .actions = actions, @@ -3357,7 +3299,7 @@ for (CheckLspIsUp[check_lsp_is_up]) { * configured, so dropping the request would frustrate that * intent.) */ Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 100, .__match = __match ++ " && inport == ${json_name}", .actions = "next;", @@ -3387,7 +3329,7 @@ for (SwitchPortIPv6Address(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam "};" in { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 50, .__match = __match, .actions = actions, @@ -3396,7 +3338,7 @@ for (SwitchPortIPv6Address(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam /* Do not reply to a solicitation from the port that owns the * address (otherwise DAD detection will fail). */ Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 100, .__match = __match ++ " && inport == ${json_name}", .actions = "next;", @@ -3408,7 +3350,7 @@ for (SwitchPortIPv6Address(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam * (priority 0)*/ for (ls in nb::Logical_Switch) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 0, .__match = "1", .actions = "next;", @@ -3418,7 +3360,7 @@ for (ls in nb::Logical_Switch) { /* Ingress table ARP_ND_RSP: ARP/ND responder for service monitor source ip. * (priority 110)*/ Flow(.logical_datapath = sp.sw.ls._uuid, - .stage = switch_stage(IN, ARP_ND_RSP), + .stage = s_SWITCH_IN_ARP_ND_RSP(), .priority = 110, .__match = "arp.tpa == ${svc_mon_src_ip} && arp.op == 1", .actions = "eth.dst = eth.src; " @@ -3638,7 +3580,7 @@ for (lsp in &SwitchPort "udp.src == 68 && udp.dst == 67" ++ sfx in Flow(.logical_datapath = lsuuid, - .stage = switch_stage(IN, DHCP_OPTIONS), + .stage = s_SWITCH_IN_DHCP_OPTIONS(), .priority = 100, .__match = __match, .actions = options_action, @@ -3655,7 +3597,7 @@ for (lsp in &SwitchPort var __match = pfx ++ "eth.src == ${ea} && " "${ipv4_addr_match} && udp.src == 68 && udp.dst == 67" ++ sfx in Flow(.logical_datapath = lsuuid, - .stage = switch_stage(IN, DHCP_OPTIONS), + .stage = s_SWITCH_IN_DHCP_OPTIONS(), .priority = 100, .__match = __match, .actions = options_action, @@ -3667,7 +3609,7 @@ for (lsp in &SwitchPort "ip4 && udp.src == 68 && udp.dst == 67 && " ++ rEGBIT_DHCP_OPTS_RESULT() ++ sfx in Flow(.logical_datapath = lsuuid, - .stage = switch_stage(IN, DHCP_RESPONSE), + .stage = s_SWITCH_IN_DHCP_RESPONSE(), .priority = 100, .__match = __match, .actions = response_action, @@ -3694,7 +3636,7 @@ for (lsp in &SwitchPort " udp.dst == 547" ++ sfx in { Flow(.logical_datapath = lsuuid, - .stage = switch_stage(IN, DHCP_OPTIONS), + .stage = s_SWITCH_IN_DHCP_OPTIONS(), .priority = 100, .__match = __match, .actions = options_action, @@ -3703,7 +3645,7 @@ for (lsp in &SwitchPort /* If REGBIT_DHCP_OPTS_RESULT is set to 1, it means the * put_dhcpv6_opts action is successful */ Flow(.logical_datapath = lsuuid, - .stage = switch_stage(IN, DHCP_RESPONSE), + .stage = s_SWITCH_IN_DHCP_RESPONSE(), .priority = 100, .__match = __match ++ " && ${rEGBIT_DHCP_OPTS_RESULT()}", .actions = response_action, @@ -3727,7 +3669,7 @@ for (lsp in &SwitchPort for (LogicalSwitchHasDNSRecords(ls, true)) { Flow(.logical_datapath = ls, - .stage = switch_stage(IN, DNS_LOOKUP), + .stage = s_SWITCH_IN_DNS_LOOKUP(), .priority = 100, .__match = "udp.dst == 53", .actions = "${rEGBIT_DNS_LOOKUP_RESULT()} = dns_lookup(); next;", @@ -3737,7 +3679,7 @@ for (LogicalSwitchHasDNSRecords(ls, true)) "udp.dst = udp.src; udp.src = 53; outport = inport; " "flags.loopback = 1; output;" in Flow(.logical_datapath = ls, - .stage = switch_stage(IN, DNS_RESPONSE), + .stage = s_SWITCH_IN_DNS_RESPONSE(), .priority = 100, .__match = "udp.dst == 53 && ${rEGBIT_DNS_LOOKUP_RESULT()}", .actions = action, @@ -3747,7 +3689,7 @@ for (LogicalSwitchHasDNSRecords(ls, true)) "udp.dst = udp.src; udp.src = 53; outport = inport; " "flags.loopback = 1; output;" in Flow(.logical_datapath = ls, - .stage = switch_stage(IN, DNS_RESPONSE), + .stage = s_SWITCH_IN_DNS_RESPONSE(), .priority = 100, .__match = "udp.dst == 53 && ${rEGBIT_DNS_LOOKUP_RESULT()}", .actions = action, @@ -3764,35 +3706,35 @@ for (LogicalSwitchHasDNSRecords(ls, true)) * (priority 0). */ for (ls in nb::Logical_Switch) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, DHCP_OPTIONS), + .stage = s_SWITCH_IN_DHCP_OPTIONS(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, DHCP_RESPONSE), + .stage = s_SWITCH_IN_DHCP_RESPONSE(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, DNS_LOOKUP), + .stage = s_SWITCH_IN_DNS_LOOKUP(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, DNS_RESPONSE), + .stage = s_SWITCH_IN_DNS_RESPONSE(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, EXTERNAL_PORT), + .stage = s_SWITCH_IN_EXTERNAL_PORT(), .priority = 0, .__match = "1", .actions = "next;", @@ -3800,7 +3742,7 @@ for (ls in nb::Logical_Switch) { } Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 110, .__match = "eth.dst == $svc_monitor_mac", .actions = "handle_svc_check(inport);", @@ -3828,7 +3770,7 @@ for (sw in &Switch(.ls = ls, .mcast_cfg = &mcast_cfg) } in { /* Punt IGMP traffic to controller. */ UniqueFlow[Flow{.logical_datapath = ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 100, .__match = "ip4 && ip.proto == 2", .actions = "${igmp_act}", @@ -3836,7 +3778,7 @@ for (sw in &Switch(.ls = ls, .mcast_cfg = &mcast_cfg) /* Punt MLD traffic to controller. */ UniqueFlow[Flow{.logical_datapath = ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 100, .__match = "mldv1 || mldv2", .actions = "${igmp_act}", @@ -3847,7 +3789,7 @@ for (sw in &Switch(.ls = ls, .mcast_cfg = &mcast_cfg) */ var flood = json_string_escape(mC_FLOOD().0) in UniqueFlow[Flow{.logical_datapath = ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 85, .__match = "ip4.mcast && ip4.dst == 224.0.0.0/24", .actions = "outport = ${flood}; output;", @@ -3858,7 +3800,7 @@ for (sw in &Switch(.ls = ls, .mcast_cfg = &mcast_cfg) */ var flood = json_string_escape(mC_FLOOD().0) in UniqueFlow[Flow{.logical_datapath = ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 85, .__match = "ip6.mcast_flood", .actions = "outport = ${flood}; output;", @@ -3897,7 +3839,7 @@ for (sw in &Switch(.ls = ls, .mcast_cfg = &mcast_cfg) } } in UniqueFlow[Flow{.logical_datapath = ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 80, .__match = "ip4.mcast || ip6.mcast", .actions = @@ -3951,7 +3893,7 @@ for (IgmpSwitchMulticastGroup(.address = address, .switch = &sw)) { } } in UniqueFlow[Flow{.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 90, .__match = "eth.mcast && ${ipX} && ${ipX}.dst == ${address}", .actions = @@ -3971,7 +3913,7 @@ for (IgmpSwitchMulticastGroup(.address = address, .switch = &sw)) { * address, if the ARP request is asking to translate the IP address of a * router port on LS. */ Flow(.logical_datapath = sp.sw.ls._uuid, - .stage = switch_stage(IN, EXTERNAL_PORT), + .stage = s_SWITCH_IN_EXTERNAL_PORT(), .priority = 100, .__match = ("inport == ${json_string_escape(localnet_port.1)} && " "eth.src == ${lp_addr.ea} && " @@ -3987,7 +3929,7 @@ Flow(.logical_datapath = sp.sw.ls._uuid, rp.lsp.__type == "router", SwitchPortIPv4Address(.port = rp, .addr = rp_addr). Flow(.logical_datapath = sp.sw.ls._uuid, - .stage = switch_stage(IN, EXTERNAL_PORT), + .stage = s_SWITCH_IN_EXTERNAL_PORT(), .priority = 100, .__match = ("inport == ${json_string_escape(localnet_port.1)} && " "eth.src == ${lp_addr.ea} && " @@ -4004,7 +3946,7 @@ Flow(.logical_datapath = sp.sw.ls._uuid, rp.lsp.__type == "router", SwitchPortIPv6Address(.port = rp, .addr = rp_addr). Flow(.logical_datapath = sp.sw.ls._uuid, - .stage = switch_stage(IN, EXTERNAL_PORT), + .stage = s_SWITCH_IN_EXTERNAL_PORT(), .priority = 100, .__match = ("inport == ${json_string_escape(localnet_port.1)} && " "eth.src == ${lp_addr.ea} && " @@ -4025,7 +3967,7 @@ Flow(.logical_datapath = sp.sw.ls._uuid, for (ls in nb::Logical_Switch) { var mc_flood = json_string_escape(mC_FLOOD().0) in UniqueFlow[Flow{.logical_datapath = ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 70, .__match = "eth.mcast", .actions = "outport = ${mc_flood}; output;", @@ -4038,7 +3980,7 @@ for (SwitchPortStaticAddresses(.port = &SwitchPort{.lsp = lsp, .json_name = json .addrs = addrs) if lsp.__type != "external") { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 50, .__match = "eth.dst == ${addrs.ea}", .actions = "outport = ${json_name}; output;", @@ -4079,7 +4021,7 @@ function lrouter_port_ip_reachable(rp: Ref, addr: v46_ip): bool { false } UniqueFlow[Flow{.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 75, .__match = __match, .actions = actions, @@ -4167,7 +4109,7 @@ function get_arp_forward_ips(rp: Ref): (Set, Set) = * (This is why we match against fLAGBIT_NOT_VXLAN() here.) */ AnnotatedFlow(.f = Flow{.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 80, .__match = fLAGBIT_NOT_VXLAN() ++ " && arp.op == 1 && arp.tpa == { " ++ @@ -4186,7 +4128,7 @@ AnnotatedFlow(.f = Flow{.logical_datapath = sw.ls._uuid, not all_ips_v4.is_empty(), var mc_flood_l2 = json_string_escape(mC_FLOOD_L2().0). AnnotatedFlow(.f = Flow{.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 80, .__match = fLAGBIT_NOT_VXLAN() ++ " && nd_ns && nd.target == { " ++ @@ -4209,7 +4151,7 @@ for (SwitchPortNewDynamicAddress(.port = &SwitchPort{.lsp = lsp, .json_name = js .address = Some{addrs}) if lsp.__type != "external") { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 50, .__match = "eth.dst == ${addrs.ea}", .actions = "outport = ${json_name}; output;", @@ -4250,7 +4192,7 @@ for (&SwitchPort(.lsp = lsp, "eth.dst == ${mac}" } in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 50, .__match = __match, .actions = "outport = ${json_name}; output;", @@ -4266,7 +4208,7 @@ for (&SwitchPort(.lsp = lsp, Some{var nat_mac} = eth_addr_from_string(emac) in var __match = "eth.dst == ${nat_mac} && is_chassis_resident(${json_string_escape(lport)})" in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 50, .__match = __match, .actions = "outport = ${json_name}; output;", @@ -4288,14 +4230,14 @@ for (&SwitchPort(.lsp = lsp, /* Ingress table L2_LKUP and L2_UNKNOWN: Destination lookup for unknown MACs (priority 0). */ for (sw in &Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid})) { Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, L2_LKUP), + .stage = s_SWITCH_IN_L2_LKUP(), .priority = 0, .__match = "1", .actions = "outport = get_fdb(eth.dst); next;", .external_ids = map_empty()); Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, L2_UNKNOWN), + .stage = s_SWITCH_IN_L2_UNKNOWN(), .priority = 50, .__match = "outport == \"none\"", .actions = if (sw.has_unknown_ports) { @@ -4307,7 +4249,7 @@ for (sw in &Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid})) { .external_ids = map_empty()); Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, L2_UNKNOWN), + .stage = s_SWITCH_IN_L2_UNKNOWN(), .priority = 0, .__match = "1", .actions = "output;", @@ -4318,13 +4260,13 @@ for (sw in &Switch(.ls = nb::Logical_Switch{._uuid = ls_uuid})) { * Egress table PORT_SEC_L2: Egress port security L2 - multicast/broadcast (priority 100). */ for (&Switch(.ls = ls)) { Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_IP), + .stage = s_SWITCH_OUT_PORT_SEC_IP(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_L2), + .stage = s_SWITCH_OUT_PORT_SEC_L2(), .priority = 100, .__match = "eth.mcast", .actions = "output;", @@ -4332,13 +4274,13 @@ for (&Switch(.ls = ls)) { } Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, LOOKUP_FDB), + .stage = s_SWITCH_IN_LOOKUP_FDB(), .priority = 100, .__match = "inport == ${sp.json_name}", .actions = "$[rEGBIT_LKUP_FDB()} = lookup_fdb(inport, eth.src); next;", .external_ids = stage_hint(lsp_uuid)), Flow(.logical_datapath = ls_uuid, - .stage = switch_stage(IN, LOOKUP_FDB), + .stage = s_SWITCH_IN_LOOKUP_FDB(), .priority = 100, .__match = "inport == ${sp.json_name} && ${rEGBIT_LKUP_FDB()} == 0", .actions = "put_fdb(inport, eth.src); next;", @@ -4348,13 +4290,13 @@ Flow(.logical_datapath = ls_uuid, .ps_addresses = vec_empty()). Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, LOOKUP_FDB), + .stage = s_SWITCH_IN_LOOKUP_FDB(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()), Flow(.logical_datapath = ls._uuid, - .stage = switch_stage(IN, PUT_FDB), + .stage = s_SWITCH_IN_PUT_FDB(), .priority = 0, .__match = "1", .actions = "next;", @@ -4371,7 +4313,7 @@ Flow(.logical_datapath = ls._uuid, * Priority 150 rules drop packets to disabled logical ports, so that they * don't even receive multicast or broadcast packets. */ Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_L2), + .stage = s_SWITCH_OUT_PORT_SEC_L2(), .priority = 50, .__match = __match, .actions = queue_action ++ "output;", @@ -4394,7 +4336,7 @@ Flow(.logical_datapath = sw.ls._uuid, for (&SwitchPort(.lsp = lsp, .json_name = json_name, .sw = &sw) if not lsp.is_enabled() and lsp.__type != "external") { Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_L2), + .stage = s_SWITCH_OUT_PORT_SEC_L2(), .priority = 150, .__match = "outport == {$json_name}", .actions = "drop;", @@ -4426,7 +4368,7 @@ for (SwitchPortPSAddresses(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam "outport == ${json_name} && eth.dst == ${ps.ea} && ip4.dst == {255.255.255.255, 224.0.0.0/4, " ++ addrs.join(", ") ++ "}" in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_IP), + .stage = s_SWITCH_OUT_PORT_SEC_IP(), .priority = 90, .__match = __match, .actions = "next;", @@ -4434,9 +4376,9 @@ for (SwitchPortPSAddresses(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam }; if (ps.ipv6_addrs.len() > 0) { var __match = "outport == ${json_name} && eth.dst == ${ps.ea}" ++ - build_port_security_ipv6_flow(OUT, ps.ea, ps.ipv6_addrs) in + build_port_security_ipv6_flow(Egress, ps.ea, ps.ipv6_addrs) in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_IP), + .stage = s_SWITCH_OUT_PORT_SEC_IP(), .priority = 90, .__match = __match, .actions = "next;", @@ -4444,7 +4386,7 @@ for (SwitchPortPSAddresses(.port = &SwitchPort{.lsp = lsp, .json_name = json_nam }; var __match = "outport == ${json_name} && eth.dst == ${ps.ea} && ip" in Flow(.logical_datapath = sw.ls._uuid, - .stage = switch_stage(OUT, PORT_SEC_IP), + .stage = s_SWITCH_OUT_PORT_SEC_IP(), .priority = 80, .__match = __match, .actions = "drop;", @@ -4456,7 +4398,7 @@ for (&Router(.lr = lr)) { /* Logical VLANs not supported. * Broadcast/multicast source address is invalid. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ADMISSION), + .stage = s_ROUTER_IN_ADMISSION(), .priority = 100, .__match = "vlan.present || eth.src[40]", .actions = "drop;", @@ -4485,7 +4427,7 @@ for (&RouterPort(.lrp = lrp, */ var actions = "${rEG_INPORT_ETH_ADDR()} = ${lrp_networks.ea}; next;" in { Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ADMISSION), + .stage = s_ROUTER_IN_ADMISSION(), .priority = 50, .__match = "eth.mcast && inport == ${json_name}", .actions = actions, @@ -4499,7 +4441,7 @@ for (&RouterPort(.lrp = lrp, " && is_chassis_resident(${json_string_escape(chassis_redirect_name(lrp.name))})" } else { "" } in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ADMISSION), + .stage = s_ROUTER_IN_ADMISSION(), .priority = 50, .__match = __match, .actions = actions, @@ -4550,7 +4492,7 @@ var rLNR = rEGBIT_LOOKUP_NEIGHBOR_RESULT() in var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LOOKUP_NEIGHBOR), + .stage = s_ROUTER_IN_LOOKUP_NEIGHBOR(), .priority = 100, .__match = "arp.op == 2", .actions = @@ -4559,7 +4501,7 @@ var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in "next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LOOKUP_NEIGHBOR), + .stage = s_ROUTER_IN_LOOKUP_NEIGHBOR(), .priority = 100, .__match = "nd_na", .actions = @@ -4568,7 +4510,7 @@ var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in "next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LOOKUP_NEIGHBOR), + .stage = s_ROUTER_IN_LOOKUP_NEIGHBOR(), .priority = 100, .__match = "nd_ns", .actions = @@ -4581,7 +4523,7 @@ var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in /* For other packet types, we can skip neighbor learning. * So set REGBIT_LOOKUP_NEIGHBOR_RESULT to 1. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LOOKUP_NEIGHBOR), + .stage = s_ROUTER_IN_LOOKUP_NEIGHBOR(), .priority = 0, .__match = "1", .actions = "${rLNR} = 1; next;", @@ -4590,7 +4532,7 @@ var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in /* Flows for LEARN_NEIGHBOR. */ /* Skip Neighbor learning if not required. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LEARN_NEIGHBOR), + .stage = s_ROUTER_IN_LEARN_NEIGHBOR(), .priority = 100, .__match = "${rLNR} == 1" ++ @@ -4598,25 +4540,25 @@ var rLNIR = rEGBIT_LOOKUP_NEIGHBOR_IP_RESULT() in .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LEARN_NEIGHBOR), + .stage = s_ROUTER_IN_LEARN_NEIGHBOR(), .priority = 90, .__match = "arp", .actions = "put_arp(inport, arp.spa, arp.sha); next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LEARN_NEIGHBOR), + .stage = s_ROUTER_IN_LEARN_NEIGHBOR(), .priority = 90, .__match = "arp", .actions = "put_arp(inport, arp.spa, arp.sha); next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LEARN_NEIGHBOR), + .stage = s_ROUTER_IN_LEARN_NEIGHBOR(), .priority = 90, .__match = "nd_na", .actions = "put_nd(inport, nd.target, nd.tll); next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LEARN_NEIGHBOR), + .stage = s_ROUTER_IN_LEARN_NEIGHBOR(), .priority = 90, .__match = "nd_ns", .actions = "put_nd(inport, ip6.src, nd.sll); next;", @@ -4649,7 +4591,7 @@ for (RouterPortNetworksIPv4Addr(rp@&RouterPort{.router = router}, addr)) { "${rLNIR} = 1; " "next;" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, LOOKUP_NEIGHBOR), + .stage = s_ROUTER_IN_LOOKUP_NEIGHBOR(), .priority = 110, .__match = __match.join(" && "), .actions = actions, @@ -4661,7 +4603,7 @@ for (RouterPortNetworksIPv4Addr(rp@&RouterPort{.router = router}, addr)) { "${rLNIR} = lookup_arp_ip(inport, arp.spa); " } ++ "next;" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, LOOKUP_NEIGHBOR), + .stage = s_ROUTER_IN_LOOKUP_NEIGHBOR(), .priority = 100, .__match = "${match0} && ${match1}", .actions = actions, @@ -4676,7 +4618,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { * source or destination, and zero network source or destination * (priority 100). */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 100, .__match = "ip4.src_mcast ||" "ip4.src == 255.255.255.255 || " @@ -4693,7 +4635,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { * IPs are handled with priority-90 flows. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 85, .__match = "arp || nd", .actions = "drop;", @@ -4703,7 +4645,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { * router pipeline (e.g., router solicitations). */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 84, .__match = "nd_rs || nd_ra", .actions = "next;", @@ -4711,7 +4653,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { /* Drop other reserved multicast. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 83, .__match = "ip6.mcast_rsvd", .actions = "drop;", @@ -4720,7 +4662,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { /* Allow other multicast if relay enabled (priority 82). */ var mcast_action = { if (mcast_cfg.relay) { "next;" } else { "drop;" } } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 82, .__match = "ip4.mcast || ip6.mcast", .actions = mcast_action, @@ -4729,7 +4671,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { /* Drop Ethernet local broadcast. By definition this traffic should * not be forwarded.*/ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 50, .__match = "eth.bcast", .actions = "drop;", @@ -4738,7 +4680,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { /* TTL discard */ Flow( .logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 30, .__match = "ip4 && ip.ttl == {0, 1}", .actions = "drop;", @@ -4747,7 +4689,7 @@ for (router in &Router(.lr = lr, .mcast_cfg = &mcast_cfg)) { /* Pass other traffic not already handled to the next table for * routing. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 0, .__match = "1", .actions = "next;", @@ -4834,7 +4776,7 @@ for (&RouterPort(.router = &router, .networks = networks, .lrp = lrp) format_v4_networks(networks, true) ++ " && ${rEGBIT_EGRESS_LOOPBACK()} == 0" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 100, .__match = __match, .actions = "drop;", @@ -4849,7 +4791,7 @@ for (&RouterPort(.router = &router, .networks = networks, .lrp = lrp) format_v4_networks(networks, false) ++ " && icmp4.type == 8 && icmp4.code == 0" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 90, .__match = __match, .actions = "ip4.dst <-> ip4.src; " @@ -4969,7 +4911,7 @@ relation LogicalRouterArpFlow( priority: integer, external_ids: Map) Flow(.logical_datapath = lr.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = priority, .__match = __match, .actions = actions, @@ -5014,7 +4956,7 @@ relation LogicalRouterNdFlow( priority: integer, external_ids: Map) Flow(.logical_datapath = lr.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = priority, .__match = __match, .actions = actions, @@ -5059,7 +5001,7 @@ for (RouterPortNetworksIPv4Addr(.port = &RouterPort{.lrp = lrp, .addr = addr)) { Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 40, .__match = "inport == ${json_name} && ip4 && " "ip.ttl == {0, 1} && !ip.later_frag", @@ -5135,7 +5077,7 @@ var residence_check = match (is_redirect) { * Priority 60. */ Flow(.logical_datapath = lr_uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 60, .__match = "ip4.dst == {" ++ match_ips.join(", ") ++ "}", .actions = "drop;", @@ -5148,7 +5090,7 @@ Flow(.logical_datapath = lr_uuid, not snat_ips.contains_key(IPv4{addr.addr}), var match_ips = "${addr.addr}".group_by((lr_uuid, lrp_uuid)).to_vec(). Flow(.logical_datapath = lr_uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 60, .__match = "ip6.dst == {" ++ match_ips.join(", ") ++ "}", .actions = "drop;", @@ -5172,7 +5114,7 @@ for (RouterPortNetworksIPv4Addr( /* UDP/TCP/SCTP port unreachable. */ var __match = "ip4 && ip4.dst == ${addr.addr} && !ip.later_frag && udp" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 80, .__match = __match, .actions = "icmp4 {" @@ -5186,7 +5128,7 @@ for (RouterPortNetworksIPv4Addr( var __match = "ip4 && ip4.dst == ${addr.addr} && !ip.later_frag && tcp" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 80, .__match = __match, .actions = "tcp_reset {" @@ -5197,7 +5139,7 @@ for (RouterPortNetworksIPv4Addr( var __match = "ip4 && ip4.dst == ${addr.addr} && !ip.later_frag && sctp" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 80, .__match = __match, .actions = "sctp_abort {" @@ -5208,7 +5150,7 @@ for (RouterPortNetworksIPv4Addr( var __match = "ip4 && ip4.dst == ${addr.addr} && !ip.later_frag" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 70, .__match = __match, .actions = "icmp4 {" @@ -5223,7 +5165,7 @@ for (RouterPortNetworksIPv4Addr( /* DHCPv6 reply handling */ Flow(.logical_datapath = rp.router.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 100, .__match = "ip6.dst == ${ipv6_addr.addr} " "&& udp.src == 547 && udp.dst == 546", @@ -5248,7 +5190,7 @@ for (&RouterPort(.router = &router, .networks = networks, .lrp = lrp) format_v6_networks(networks) ++ " && icmp6.type == 128 && icmp6.code == 0" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 90, .__match = __match, .actions = "ip6.dst <-> ip6.src; " @@ -5299,7 +5241,7 @@ for (RouterPortNetworksIPv6Addr( { var __match = "ip6 && ip6.dst == ${addr.addr} && !ip.later_frag && tcp" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 80, .__match = __match, .actions = "tcp_reset {" @@ -5310,7 +5252,7 @@ for (RouterPortNetworksIPv6Addr( var __match = "ip6 && ip6.dst == ${addr.addr} && !ip.later_frag && sctp" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 80, .__match = __match, .actions = "sctp_abort {" @@ -5321,7 +5263,7 @@ for (RouterPortNetworksIPv6Addr( var __match = "ip6 && ip6.dst == ${addr.addr} && !ip.later_frag && udp" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 80, .__match = __match, .actions = "icmp6 {" @@ -5335,7 +5277,7 @@ for (RouterPortNetworksIPv6Addr( var __match = "ip6 && ip6.dst == ${addr.addr} && !ip.later_frag" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 70, .__match = __match, .actions = "icmp6 {" @@ -5368,7 +5310,7 @@ for (RouterPortNetworksIPv6Addr(.port = &RouterPort{.router = &router, "icmp6.code = 0; /* TTL exceeded in transit */ " "next; };" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 40, .__match = __match, .actions = actions, @@ -5387,19 +5329,19 @@ function default_allow_flow(datapath: uuid, stage: Stage): Flow { } for (&Router(.lr = lr)) { /* Packets are allowed by default. */ - Flow[default_allow_flow(lr._uuid, router_stage(IN, DEFRAG))]; - Flow[default_allow_flow(lr._uuid, router_stage(IN, UNSNAT))]; - Flow[default_allow_flow(lr._uuid, router_stage(OUT, SNAT))]; - Flow[default_allow_flow(lr._uuid, router_stage(IN, DNAT))]; - Flow[default_allow_flow(lr._uuid, router_stage(OUT, UNDNAT))]; - Flow[default_allow_flow(lr._uuid, router_stage(OUT, EGR_LOOP))]; - Flow[default_allow_flow(lr._uuid, router_stage(IN, ECMP_STATEFUL))]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_IN_DEFRAG())]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_IN_UNSNAT())]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_OUT_SNAT())]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_IN_DNAT())]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_OUT_UNDNAT())]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_OUT_EGR_LOOP())]; + Flow[default_allow_flow(lr._uuid, s_ROUTER_IN_ECMP_STATEFUL())]; /* Send the IPv6 NS packets to next table. When ovn-controller * generates IPv6 NS (for the action - nd_ns{}), the injected * packet would go through conntrack - which is not required. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, SNAT), + .stage = s_ROUTER_OUT_SNAT(), .priority = 120, .__match = "nd_ns", .actions = "next;", @@ -5462,7 +5404,7 @@ function lrouter_nat_add_ext_ip_match( ("", Some{Flow{.logical_datapath = router.lr._uuid, - .stage = if (is_src) { router_stage(IN, DNAT) } else { router_stage(OUT, SNAT) }, + .stage = if (is_src) { s_ROUTER_IN_DNAT() } else { s_ROUTER_OUT_SNAT() }, .priority = priority, .__match = "${__match} && ${ipX}.${dir} == $${__as.name}", .actions = "next;", @@ -5476,7 +5418,7 @@ relation LogicalRouterForceSnatFlows( ips: Set, context: string) Flow(.logical_datapath = logical_router, - .stage = router_stage(IN, UNSNAT), + .stage = s_ROUTER_IN_UNSNAT(), .priority = 110, .__match = "${ipX} && ${ipX}.dst == ${ip}", .actions = "ct_snat;", @@ -5485,7 +5427,7 @@ Flow(.logical_datapath = logical_router, * configured in the Gateway router. This only takes effect * when the packet has already been DNATed or load balanced once. */ Flow(.logical_datapath = logical_router, - .stage = router_stage(OUT, SNAT), + .stage = s_ROUTER_OUT_SNAT(), .priority = 100, .__match = "flags.force_snat_for_${context} == 1 && ${ipX}", .actions = "ct_snat(%{ip});", @@ -5503,7 +5445,7 @@ for (rp in &RouterPort(.router = &Router{.lr = lr}, .lrp = lrp)) { if (lb_force_snat_router_ip(lrp.options) and rp.peer != PeerNone) { Some{var ipv4} = rp.networks.ipv4_addrs.nth(0) in { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, SNAT), + .stage = s_ROUTER_OUT_SNAT(), .priority = 110, .__match = "flags.force_snat_for_lb == 1 && ip4 && outport == ${rp.json_name}", .actions = "ct_snat(${ipv4.addr});", @@ -5521,7 +5463,7 @@ for (rp in &RouterPort(.router = &Router{.lr = lr}, .lrp = lrp)) { if (rp.networks.ipv6_addrs.len() > 1) { Some{var ipv6} = rp.networks.ipv6_addrs.nth(0) in { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, SNAT), + .stage = s_ROUTER_OUT_SNAT(), .priority = 110, .__match = "flags.force_snat_for_lb == 1 && ip6 && outport == ${rp.json_name}", .actions = "ct_snat(${ipv6.addr});", @@ -5588,7 +5530,7 @@ for (r in &Router(.lr = lr, "ct_snat;" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, UNSNAT), + .stage = s_ROUTER_IN_UNSNAT(), .priority = 90, .__match = "ip && ${ipX}.dst == ${nat.nat.external_ip}", .actions = actions, @@ -5612,7 +5554,7 @@ for (r in &Router(.lr = lr, "ct_snat;" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, UNSNAT), + .stage = s_ROUTER_IN_UNSNAT(), .priority = 100, .__match = __match, .actions = actions, @@ -5655,7 +5597,7 @@ for (r in &Router(.lr = lr, "ct_dnat(${ip_and_ports});" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, DNAT), + .stage = s_ROUTER_IN_DNAT(), .priority = 100, .__match = __match ++ ext_ip_match, .actions = flag_action ++ nat_actions, @@ -5684,7 +5626,7 @@ for (r in &Router(.lr = lr, "ct_dnat(${ip_and_ports});" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, DNAT), + .stage = s_ROUTER_IN_DNAT(), .priority = 100, .__match = __match ++ ext_ip_match, .actions = actions, @@ -5699,7 +5641,7 @@ for (r in &Router(.lr = lr, var __match = "inport == ${gwport_name} && " "${ipX}.src == ${nat.nat.external_ip}" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 120, .__match = __match, .actions = "next;", @@ -5714,7 +5656,7 @@ for (r in &Router(.lr = lr, None -> gwport.mac } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = __match, .actions = "eth.dst = ${dst_mac}; next;", @@ -5751,7 +5693,7 @@ for (r in &Router(.lr = lr, "ct_dnat;" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, UNDNAT), + .stage = s_ROUTER_OUT_UNDNAT(), .priority = 100, .__match = __match, .actions = actions, @@ -5786,7 +5728,7 @@ for (r in &Router(.lr = lr, } in Some{var plen} = ip46_count_cidr_bits(mask) in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, SNAT), + .stage = s_ROUTER_OUT_SNAT(), .priority = plen as bit<64> + 1, .__match = __match ++ ext_ip_match, .actions = actions, @@ -5824,7 +5766,7 @@ for (r in &Router(.lr = lr, var priority = (plen as bit<64>) + 1 in var centralized_boost = if (mac == None) 128 else 0 in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, SNAT), + .stage = s_ROUTER_OUT_SNAT(), .priority = priority + centralized_boost, .__match = __match ++ ext_ip_match, .actions = actions, @@ -5849,7 +5791,7 @@ for (r in &Router(.lr = lr, */ var actions = "${rEG_INPORT_ETH_ADDR()} = ${gwport.mac}; next;" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ADMISSION), + .stage = s_ROUTER_IN_ADMISSION(), .priority = 50, .__match = __match, .actions = actions, @@ -5876,7 +5818,7 @@ for (r in &Router(.lr = lr, "${xx}${rEG_SRC()} = ${nat.nat.external_ip}; " "next;" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, GW_REDIRECT), + .stage = s_ROUTER_IN_GW_REDIRECT(), .priority = 100, .__match = __match, .actions = actions, @@ -5912,7 +5854,7 @@ for (r in &Router(.lr = lr, "${rEGBIT_EGRESS_LOOPBACK()} = 1; " "next(pipeline=ingress, table=0); };" in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, EGR_LOOP), + .stage = s_ROUTER_OUT_EGR_LOOP(), .priority = 100, .__match = __match, .actions = actions, @@ -5944,7 +5886,7 @@ for (r in &Router(.lr = lr, * ip address being external IP address for IP routing, * we can do it here, saving a future re-circulation. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, DNAT), + .stage = s_ROUTER_IN_DNAT(), .priority = 50, .__match = "ip", .actions = "flags.loopback = 1; ct_dnat;", @@ -5980,7 +5922,7 @@ for (RouterLBVIP( Some {(var __match, var __action)} = build_empty_lb_event_flow(vip, lb, has_elb_meter) in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, DNAT), + .stage = s_ROUTER_IN_DNAT(), .priority = 130, .__match = __match, .actions = __action, @@ -6012,7 +5954,7 @@ for (RouterLBVIP( * different port numbers will produce identical flows that will * get merged by DDlog. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, DEFRAG), + .stage = s_ROUTER_IN_DEFRAG(), .priority = 100, .__match = __match, .actions = "ct_next;", @@ -6045,7 +5987,7 @@ for (RouterLBVIP( false -> "ct_dnat;" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, DNAT), + .stage = s_ROUTER_IN_DNAT(), .priority = prio, .__match = est_match, .actions = actions, @@ -6067,7 +6009,7 @@ for (RouterLBVIP( if (port != 0) { " && ${proto}.dst == ${port}" } else { "" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, UNSNAT), + .stage = s_ROUTER_IN_UNSNAT(), .priority = 120, .__match = match3, .actions = "next;", @@ -6106,7 +6048,7 @@ for (RouterLBVIP( false -> "ct_dnat;" } in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, UNDNAT), + .stage = s_ROUTER_OUT_UNDNAT(), .priority = 120, .__match = undnat_match, .actions = action, @@ -6121,7 +6063,7 @@ for (RouterLBVIP( * on ct.new with an action of "ct_lb($targets);". The other * flow is for ct.est with an action of "ct_dnat;". */ Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, DNAT), + .stage = s_ROUTER_IN_DNAT(), .priority = priority, .__match = __match, .actions = actions, @@ -6139,7 +6081,7 @@ Flow(.logical_datapath = r.lr._uuid, }, var priority = if (lbvip.vip_port != 0) 120 else 110, var force_snat = if (has_force_snat_ip(r.lr, "lb")) "flags.force_snat_for_lb = 1; " else "", - var actions = build_lb_vip_actions(lbvip, stage_id(router_stage(OUT, SNAT)).0, force_snat). + var actions = build_lb_vip_actions(lbvip, s_ROUTER_OUT_SNAT(), force_snat). /* Defaults based on MaxRtrInterval and MinRtrInterval from RFC 4861 section @@ -6300,7 +6242,7 @@ for (&RouterPort[port@RouterPort{.lrp = lrp@nb::Logical_Router_Port{.peer = None } in var actions = actions0 ++ router_preference ++ prefix ++ "); next;" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ND_RA_OPTIONS), + .stage = s_ROUTER_IN_ND_RA_OPTIONS(), .priority = 50, .__match = __match, .actions = actions, @@ -6314,7 +6256,7 @@ for (&RouterPort[port@RouterPort{.lrp = lrp@nb::Logical_Router_Port{.peer = None "outport = inport; flags.loopback = 1; " "output;" in Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ND_RA_RESPONSE), + .stage = s_ROUTER_IN_ND_RA_RESPONSE(), .priority = 50, .__match = __match, .actions = actions, @@ -6329,13 +6271,13 @@ for (&RouterPort[port@RouterPort{.lrp = lrp@nb::Logical_Router_Port{.peer = None for (&Router(.lr = lr)) { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ND_RA_OPTIONS), + .stage = s_ROUTER_IN_ND_RA_OPTIONS(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ND_RA_RESPONSE), + .stage = s_ROUTER_IN_ND_RA_RESPONSE(), .priority = 0, .__match = "1", .actions = "next;", @@ -6397,7 +6339,7 @@ for (Route(.port = port, "next;" in { Flow(.logical_datapath = port.router.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = priority as integer, .__match = __match, .actions = "ip.ttl--; ${actions}", @@ -6405,7 +6347,7 @@ for (Route(.port = port, if (port.has_bfd) { Flow(.logical_datapath = port.router.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = priority as integer + 1, .__match = "${__match} && udp.dst == 3784", .actions = actions, @@ -6440,7 +6382,7 @@ Route(key, port, src_ip, None) :- var src_ip = IPv6{addr.addr}. Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, IP_ROUTING_ECMP), + .stage = s_ROUTER_IN_IP_ROUTING_ECMP(), .priority = 150, .__match = "${rEG_ECMP_GROUP_ID()} == 0", .actions = "next;", @@ -6482,7 +6424,7 @@ EcmpGroup(group_id, router, key, dsts, route_match, route_priority) :- var route_priority = route_priority0 as integer. Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = route_priority, .__match = route_match, .actions = actions, @@ -6502,7 +6444,7 @@ Flow(.logical_datapath = router.lr._uuid, "${rEG_ECMP_MEMBER_ID()} = select(${all_member_ids});". Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_ROUTING_ECMP), + .stage = s_ROUTER_IN_IP_ROUTING_ECMP(), .priority = 100, .__match = __match, .actions = actions, @@ -6535,7 +6477,7 @@ EcmpSymmetricReply(router, dst, route_match, tunkey) :- PortTunKeyAllocation(.port = dst.port.lrp._uuid, .tunkey = tunkey). Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, DEFRAG), + .stage = s_ROUTER_IN_DEFRAG(), .priority = 100, .__match = __match, .actions = "ct_next;", @@ -6550,7 +6492,7 @@ Flow(.logical_datapath = router.lr._uuid, * an ECMP route. */ Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ECMP_STATEFUL), + .stage = s_ROUTER_IN_ECMP_STATEFUL(), .priority = 100, .__match = __match, .actions = actions, @@ -6565,7 +6507,7 @@ Flow(.logical_datapath = router.lr._uuid, * for where to route the packet. */ Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = 100, .__match = "${ecmp_reply} && ${route_match}", .actions = "ip.ttl--; " @@ -6577,13 +6519,13 @@ Flow(.logical_datapath = router.lr._uuid, .external_ids = map_empty()), /* Egress reply traffic for symmetric ECMP routes skips router policies. */ Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, POLICY), + .stage = s_ROUTER_IN_POLICY(), .priority = 65535, .__match = ecmp_reply, .actions = "next;", .external_ids = map_empty()), Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 200, .__match = ecmp_reply, .actions = "eth.dst = ct_label.ecmp_reply_eth; next;", @@ -6600,7 +6542,7 @@ Flow(.logical_datapath = router.lr._uuid, * i.e., router solicitation and router advertisement. */ Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = 550, .__match = "nd_rs || nd_ra", .actions = "drop;", @@ -6625,7 +6567,7 @@ for (IgmpRouterMulticastGroup(address, &rtr, ports)) { Some{var ip} = ip46_parse(address) in var ipX = ip46_ipX(ip) in UniqueFlow[Flow{.logical_datapath = rtr.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = 500, .__match = "${ipX} && ${ipX}.dst == ${address} ", .actions = @@ -6651,7 +6593,7 @@ for (RouterMcastFloodPorts(&rtr, flood_ports) if rtr.mcast_cfg.relay) { "drop;" } in AnnotatedFlow(.f = Flow{.logical_datapath = rtr.lr._uuid, - .stage = router_stage(IN, IP_ROUTING), + .stage = s_ROUTER_IN_IP_ROUTING(), .priority = 450, .__match = "ip4.mcast || ip6.mcast", .actions = actions, @@ -6672,14 +6614,14 @@ for (&Router(.lr = lr)) { /* This is a catch-all rule. It has the lowest priority (0) * does a match-all("1") and pass-through (next) */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, POLICY), + .stage = s_ROUTER_IN_POLICY(), .priority = 0, .__match = "1", .actions = "${rEG_ECMP_GROUP_ID()} = 0; next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, POLICY_ECMP), + .stage = s_ROUTER_IN_POLICY_ECMP(), .priority = 150, .__match = "${rEG_ECMP_GROUP_ID()} == 0", .actions = "next;", @@ -6701,7 +6643,7 @@ function pkt_mark_policy(options: Map): string { } } Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, POLICY), + .stage = s_ROUTER_IN_POLICY(), .priority = policy.priority, .__match = policy.__match, .actions = actions, @@ -6762,7 +6704,7 @@ EcmpReroutePolicy(r, policy, ecmp_group_id) :- (var policy, var ecmp_group_id) = pair, all_same_addr_family(policy.nexthops). Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, POLICY_ECMP), + .stage = s_ROUTER_IN_POLICY_ECMP(), .priority = 100, .__match = __match, .actions = actions, @@ -6786,7 +6728,7 @@ Flow(.logical_datapath = r.lr._uuid, var __match = ("${rEG_ECMP_GROUP_ID()} == ${ecmp_group_id} && " "${rEG_ECMP_MEMBER_ID()} == ${member_id}"). Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, POLICY), + .stage = s_ROUTER_IN_POLICY(), .priority = policy.priority, .__match = policy.__match, .actions = actions, @@ -6804,7 +6746,7 @@ Flow(.logical_datapath = r.lr._uuid, "${rEG_ECMP_MEMBER_ID()} = select(${member_ids});"). Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, POLICY), + .stage = s_ROUTER_IN_POLICY(), .priority = policy.priority, .__match = policy.__match, .actions = "drop;", @@ -6814,7 +6756,7 @@ Flow(.logical_datapath = r.lr._uuid, policy in nb::Logical_Router_Policy(._uuid = policy_uuid), policy.action == "drop". Flow(.logical_datapath = r.lr._uuid, - .stage = router_stage(IN, POLICY), + .stage = s_ROUTER_IN_POLICY(), .priority = policy.priority, .__match = policy.__match, .actions = pkt_mark_policy(policy.options) ++ "${rEG_ECMP_GROUP_ID()} = 0; next;", @@ -6834,7 +6776,7 @@ Flow(.logical_datapath = r.lr._uuid, */ for (&Router(.lr = lr)) { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 500, .__match = "ip4.mcast || ip6.mcast", .actions = "next;", @@ -6869,7 +6811,7 @@ for (rp in &RouterPort(.peer = PeerRouter{peer_port, _}, "${rEG_NEXT_HOP()} == " ++ format_v4_networks(networks, false) in Flow(.logical_datapath = peer_router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = __match, .actions = "eth.dst = ${networks.ea}; next;", @@ -6881,7 +6823,7 @@ for (rp in &RouterPort(.peer = PeerRouter{peer_port, _}, "xx${rEG_NEXT_HOP()} == " ++ format_v6_networks(networks) in Flow(.logical_datapath = peer_router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = __match, .actions = "eth.dst = ${networks.ea}; next;", @@ -6897,7 +6839,7 @@ for (rp in &RouterPort(.peer = PeerRouter{peer_port, _}, * on this node, we will redirect the packet to gateway * chassis, by setting destination mac router port mac.*/ Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 50, .__match = "outport == ${rp.json_name} && " "!is_chassis_resident(${router.redirect_port_name})", @@ -6915,7 +6857,7 @@ Flow(.logical_datapath = router.lr._uuid, * Priority 1. */ Flow(.logical_datapath = lr_uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 1, .__match = "ip4.dst == {" ++ match_ips.join(", ") ++ "}", .actions = "drop;", @@ -6928,7 +6870,7 @@ Flow(.logical_datapath = lr_uuid, snat_ips.contains_key(IPv4{addr.addr}), var match_ips = "${addr.addr}".group_by((lr_uuid, lrp_uuid)).to_vec(). Flow(.logical_datapath = lr_uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 1, .__match = "ip6.dst == {" ++ match_ips.join(", ") ++ "}", .actions = "drop;", @@ -6957,7 +6899,7 @@ for (SwitchPortIPv4Address( { Some{_} = find_lrp_member_ip(peer.networks, IPv4{addr.addr}) in Flow(.logical_datapath = peer_router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = "outport == ${peer.json_name} && " "${rEG_NEXT_HOP()} == ${addr.addr}", @@ -6977,7 +6919,7 @@ for (SwitchPortIPv6Address( { Some{_} = find_lrp_member_ip(peer.networks, IPv6{addr.addr}) in Flow(.logical_datapath = peer_router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = "outport == ${peer.json_name} && " "xx${rEG_NEXT_HOP()} == ${addr.addr}", @@ -7007,7 +6949,7 @@ function is_empty_set_or_string(s: Option): bool = { * resolved by router pipeline using the arp{} action. * The MAC_Binding entry for the virtual ip might be invalid. */ Flow(.logical_datapath = peer.router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = "outport == ${peer.json_name} && " "${rEG_NEXT_HOP()} == ${virtual_ip}", @@ -7022,7 +6964,7 @@ Flow(.logical_datapath = peer.router.lr._uuid, sp2 in &SwitchPort(.sw = sp.sw, .peer = Some{peer}), Some{_} = find_lrp_member_ip(peer.networks, IPv4{virtual_ip}). Flow(.logical_datapath = peer.router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = "outport == ${peer.json_name} && " "${rEG_NEXT_HOP()} == ${virtual_ip}", @@ -7059,7 +7001,7 @@ for (&SwitchPort(.lsp = lsp1, { if (not peer2.networks.ipv4_addrs.is_empty()) { Flow(.logical_datapath = peer_router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = "outport == ${peer1.json_name} && " "${rEG_NEXT_HOP()} == ${format_v4_networks(peer2.networks, false)}", @@ -7069,7 +7011,7 @@ for (&SwitchPort(.lsp = lsp1, if (not peer2.networks.ipv6_addrs.is_empty()) { Flow(.logical_datapath = peer_router.lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 100, .__match = "outport == ${peer1.json_name} && " "xx${rEG_NEXT_HOP()} == ${format_v6_networks(peer2.networks)}", @@ -7082,13 +7024,13 @@ for (&SwitchPort(.lsp = lsp1, for (&Router(.lr = lr)) { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 0, .__match = "ip4", .actions = "get_arp(outport, ${rEG_NEXT_HOP()}); next;", .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_RESOLVE), + .stage = s_ROUTER_IN_ARP_RESOLVE(), .priority = 0, .__match = "ip6", .actions = "get_nd(outport, xx${rEG_NEXT_HOP()}); next;", @@ -7109,21 +7051,21 @@ for (&Router(.lr = lr)) * code 4 (Fragmentation needed). * */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, CHK_PKT_LEN), + .stage = s_ROUTER_IN_CHK_PKT_LEN(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()) :- &Router(.lr = lr). Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LARGER_PKTS), + .stage = s_ROUTER_IN_LARGER_PKTS(), .priority = 0, .__match = "1", .actions = "next;", .external_ids = map_empty()) :- &Router(.lr = lr). Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, CHK_PKT_LEN), + .stage = s_ROUTER_IN_CHK_PKT_LEN(), .priority = 50, .__match = "outport == ${l3dgw_port_json_name}", .actions = "${rEGBIT_PKT_LARGER()} = check_pkt_larger(${mtu}); " @@ -7137,7 +7079,7 @@ Flow(.logical_datapath = lr._uuid, gw_mtu > 0, var mtu = gw_mtu + vLAN_ETH_HEADER_LEN(). Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LARGER_PKTS), + .stage = s_ROUTER_IN_LARGER_PKTS(), .priority = 50, .__match = "inport == ${rp.json_name} && outport == ${l3dgw_port_json_name} && " "ip4 && ${rEGBIT_PKT_LARGER()}", @@ -7164,7 +7106,7 @@ Flow(.logical_datapath = lr._uuid, rp.lrp != l3dgw_port, Some{var first_ipv4} = rp.networks.ipv4_addrs.nth(0). Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, LARGER_PKTS), + .stage = s_ROUTER_IN_LARGER_PKTS(), .priority = 50, .__match = "inport == ${rp.json_name} && outport == ${l3dgw_port_json_name} && " "ip6 && ${rEGBIT_PKT_LARGER()}", @@ -7208,7 +7150,7 @@ for (&Router(.lr = lr, * instance of the l3dgw_port. */ Some{var gwport} = l3dgw_port in Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, GW_REDIRECT), + .stage = s_ROUTER_IN_GW_REDIRECT(), .priority = 50, .__match = "outport == ${json_string_escape(gwport.name)}", .actions = "outport = ${redirect_port_name}; next;", @@ -7216,7 +7158,7 @@ for (&Router(.lr = lr, /* Packets are allowed by default. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, GW_REDIRECT), + .stage = s_ROUTER_IN_GW_REDIRECT(), .priority = 0, .__match = "1", .actions = "next;", @@ -7229,7 +7171,7 @@ for (&Router(.lr = lr, * this table outputs the packet (priority 0). Otherwise, it composes * and sends an ARP/IPv6 NA request (priority 100). */ Flow(.logical_datapath = router.lr._uuid, - .stage = router_stage(IN, ARP_REQUEST), + .stage = s_ROUTER_IN_ARP_REQUEST(), .priority = 200, .__match = __match, .actions = actions, @@ -7252,7 +7194,7 @@ Flow(.logical_datapath = router.lr._uuid, for (&Router(.lr = lr)) { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_REQUEST), + .stage = s_ROUTER_IN_ARP_REQUEST(), .priority = 100, .__match = "eth.dst == 00:00:00:00:00:00 && ip4", .actions = "arp { " @@ -7265,7 +7207,7 @@ for (&Router(.lr = lr)) .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_REQUEST), + .stage = s_ROUTER_IN_ARP_REQUEST(), .priority = 100, .__match = "eth.dst == 00:00:00:00:00:00 && ip6", .actions = "nd_ns { " @@ -7275,7 +7217,7 @@ for (&Router(.lr = lr)) .external_ids = map_empty()); Flow(.logical_datapath = lr._uuid, - .stage = router_stage(IN, ARP_REQUEST), + .stage = s_ROUTER_IN_ARP_REQUEST(), .priority = 0, .__match = "1", .actions = "output;", @@ -7299,7 +7241,7 @@ for (&RouterPort(.lrp = lrp, */ if (mcast_cfg.relay) { Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, DELIVERY), + .stage = s_ROUTER_OUT_DELIVERY(), .priority = 110, .__match = "(ip4.mcast || ip6.mcast) && " "outport == ${json_name}", @@ -7312,7 +7254,7 @@ for (&RouterPort(.lrp = lrp, * pipeline stage before egress processing. */ Flow(.logical_datapath = lr._uuid, - .stage = router_stage(OUT, DELIVERY), + .stage = s_ROUTER_OUT_DELIVERY(), .priority = 100, .__match = "outport == ${json_name}", .actions = "output;", @@ -7947,13 +7889,13 @@ function lrouter_bfd_flows(lr_uuid: uuid, lrp_uuid: uuid, ipX: string, networks: : (Flow, Flow) { (Flow{.logical_datapath = lr_uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 110, .__match = "${ipX}.src == ${networks} && udp.dst == 3784", .actions = "next; ", .external_ids = stage_hint(lrp_uuid)}, Flow{.logical_datapath = lr_uuid, - .stage = router_stage(IN, IP_INPUT), + .stage = s_ROUTER_IN_IP_INPUT(), .priority = 110, .__match = "${ipX}.dst == ${networks} && udp.dst == 3784", .actions = "handle_bfd_msg(); ",