@@ -8505,6 +8505,12 @@ static void
build_lrouter_flows_lookup_and_learn_neighbour_op(
struct ovn_port *op, struct hmap *lflows,
struct ds *match, struct ds *actions);
+
+/* Logical router ingress table 3: IP Input. */
+static void
+build_lrouter_flows_ip_input_od(
+ struct ovn_datapath *od, struct hmap *lflows);
+
/*
* Do not remove this comment - it is here on purpose
* It serves as a marker so that pulling operations out
@@ -8545,102 +8551,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
}
HMAP_FOR_EACH (od, key_node, datapaths) {
- if (!od->nbr) {
- continue;
- }
-
- /* L3 admission control: drop multicast and broadcast source, localhost
- * source or destination, and zero network source or destination
- * (priority 100). */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 100,
- "ip4.src_mcast ||"
- "ip4.src == 255.255.255.255 || "
- "ip4.src == 127.0.0.0/8 || "
- "ip4.dst == 127.0.0.0/8 || "
- "ip4.src == 0.0.0.0/8 || "
- "ip4.dst == 0.0.0.0/8",
- "drop;");
-
- /* Priority-90-92 flows handle ARP requests and ND packets. Most are
- * per logical port but DNAT addresses can be handled per datapath
- * for non gateway router ports.
- */
- struct sset snat_ips = SSET_INITIALIZER(&snat_ips);
- for (int i = 0; i < od->nbr->n_nat; i++) {
- struct ovn_nat *nat_entry = &od->nat_entries[i];
- const struct nbrec_nat *nat = nat_entry->nb;
-
- /* Skip entries we failed to parse. */
- if (!nat_entry_is_valid(nat_entry)) {
- continue;
- }
-
- struct lport_addresses *ext_addrs = &nat_entry->ext_addrs;
- char *ext_addr = nat_entry_is_v6(nat_entry) ?
- ext_addrs->ipv6_addrs[0].addr_s :
- ext_addrs->ipv4_addrs[0].addr_s;
-
- if (!strcmp(nat->type, "snat")) {
- if (sset_contains(&snat_ips, ext_addr)) {
- continue;
- }
- sset_add(&snat_ips, ext_addr);
- }
-
- /* Priority 91 and 92 flows are added for each gateway router
- * port to handle the special cases. In case we get the packet
- * on a regular port, just reply with the port's ETH address.
- */
- if (nat_entry_is_v6(nat_entry)) {
- build_lrouter_nd_flow(od, NULL, "nd_na",
- ext_addrs->ipv6_addrs[0].addr_s,
- ext_addrs->ipv6_addrs[0].sn_addr_s,
- REG_INPORT_ETH_ADDR, NULL, false, 90,
- &nat->header_, lflows);
- } else {
- build_lrouter_arp_flow(od, NULL,
- ext_addrs->ipv4_addrs[0].addr_s,
- REG_INPORT_ETH_ADDR, NULL, false, 90,
- &nat->header_, lflows);
- }
- }
- sset_destroy(&snat_ips);
-
- /* Drop ARP packets (priority 85). ARP request packets for router's own
- * IPs are handled with priority-90 flows.
- * Drop IPv6 ND packets (priority 85). ND NA packets for router's own
- * IPs are handled with priority-90 flows.
- */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 85,
- "arp || nd", "drop;");
-
- /* Allow IPv6 multicast traffic that's supposed to reach the
- * router pipeline (e.g., router solicitations).
- */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 84, "nd_rs || nd_ra",
- "next;");
-
- /* Drop other reserved multicast. */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 83,
- "ip6.mcast_rsvd", "drop;");
-
- /* Allow other multicast if relay enabled (priority 82). */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 82,
- "ip4.mcast || ip6.mcast",
- od->mcast_info.rtr.relay ? "next;" : "drop;");
-
- /* Drop Ethernet local broadcast. By definition this traffic should
- * not be forwarded.*/
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 50,
- "eth.bcast", "drop;");
-
- /* TTL discard */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 30,
- "ip4 && ip.ttl == {0, 1}", "drop;");
-
- /* Pass other traffic not already handled to the next table for
- * routing. */
- ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 0, "1", "next;");
+ build_lrouter_flows_ip_input_od(od, lflows);
}
/* Logical router ingress table 3: IP Input for IPv4. */
@@ -11010,6 +10921,107 @@ build_lrouter_flows_lookup_and_learn_neighbour_op(
}
}
+static void
+build_lrouter_flows_ip_input_od(
+ struct ovn_datapath *od, struct hmap *lflows)
+{
+ if (od->nbr) {
+ /* L3 admission control: drop multicast and broadcast source, localhost
+ * source or destination, and zero network source or destination
+ * (priority 100). */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 100,
+ "ip4.src_mcast ||"
+ "ip4.src == 255.255.255.255 || "
+ "ip4.src == 127.0.0.0/8 || "
+ "ip4.dst == 127.0.0.0/8 || "
+ "ip4.src == 0.0.0.0/8 || "
+ "ip4.dst == 0.0.0.0/8",
+ "drop;");
+
+ /* Priority-90-92 flows handle ARP requests and ND packets. Most are
+ * per logical port but DNAT addresses can be handled per datapath
+ * for non gateway router ports.
+ */
+ struct sset snat_ips = SSET_INITIALIZER(&snat_ips);
+ for (int i = 0; i < od->nbr->n_nat; i++) {
+ struct ovn_nat *nat_entry = &od->nat_entries[i];
+ const struct nbrec_nat *nat = nat_entry->nb;
+
+ /* Skip entries we failed to parse. */
+ if (!nat_entry_is_valid(nat_entry)) {
+ continue;
+ }
+
+ struct lport_addresses *ext_addrs = &nat_entry->ext_addrs;
+ char *ext_addr = nat_entry_is_v6(nat_entry) ?
+ ext_addrs->ipv6_addrs[0].addr_s :
+ ext_addrs->ipv4_addrs[0].addr_s;
+
+ if (!strcmp(nat->type, "snat")) {
+ if (sset_contains(&snat_ips, ext_addr)) {
+ continue;
+ }
+ sset_add(&snat_ips, ext_addr);
+ }
+
+ /* Priority 91 and 92 flows are added for each gateway router
+ * port to handle the special cases. In case we get the packet
+ * on a regular port, just reply with the port's ETH address.
+ */
+ if (nat_entry_is_v6(nat_entry)) {
+ build_lrouter_nd_flow(od, NULL, "nd_na",
+ ext_addrs->ipv6_addrs[0].addr_s,
+ ext_addrs->ipv6_addrs[0].sn_addr_s,
+ REG_INPORT_ETH_ADDR, NULL, false, 90,
+ &nat->header_, lflows);
+ } else {
+ build_lrouter_arp_flow(od, NULL,
+ ext_addrs->ipv4_addrs[0].addr_s,
+ REG_INPORT_ETH_ADDR, NULL, false, 90,
+ &nat->header_, lflows);
+ }
+ }
+ sset_destroy(&snat_ips);
+
+ /* Drop ARP packets (priority 85). ARP request packets for router's own
+ * IPs are handled with priority-90 flows.
+ * Drop IPv6 ND packets (priority 85). ND NA packets for router's own
+ * IPs are handled with priority-90 flows.
+ */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 85,
+ "arp || nd", "drop;");
+
+ /* Allow IPv6 multicast traffic that's supposed to reach the
+ * router pipeline (e.g., router solicitations).
+ */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 84, "nd_rs || nd_ra",
+ "next;");
+
+ /* Drop other reserved multicast. */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 83,
+ "ip6.mcast_rsvd", "drop;");
+
+ /* Allow other multicast if relay enabled (priority 82). */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 82,
+ "ip4.mcast || ip6.mcast",
+ od->mcast_info.rtr.relay ? "next;" : "drop;");
+
+ /* Drop Ethernet local broadcast. By definition this traffic should
+ * not be forwarded.*/
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 50,
+ "eth.bcast", "drop;");
+
+ /* TTL discard */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 30,
+ "ip4 && ip.ttl == {0, 1}", "drop;");
+
+ /* Pass other traffic not already handled to the next table for
+ * routing. */
+ ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_INPUT, 0, "1", "next;");
+ }
+
+}
+
/* Updates the Logical_Flow and Multicast_Group tables in the OVN_SB database,
* constructing their contents based on the OVN_NB database. */
static void