This helps simplifying logical flows that need to use the port's configured ETH address: - ARP responders for owned IPs - NS responders for owned IPs
Signed-off-by: Dumitru Ceara <[email protected]> --- northd/ovn-northd.8.xml | 22 ++++++------ northd/ovn-northd.c | 87 +++++++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index a7639f3..ec89a63 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -1487,7 +1487,9 @@ output; For each enabled router port <var>P</var> with Ethernet address <var>E</var>, a priority-50 flow that matches <code>inport == <var>P</var> && (eth.mcast || eth.dst == - <var>E</var></code>), with action <code>next;</code>. + <var>E</var></code>), stores the router port ethernet address + and advances to next table, with action + <code>xxreg0[80..127]=E; next;</code>. </p> <p> @@ -1507,7 +1509,7 @@ output; a priority-50 flow that matches <code>inport == <var>GW</var> && eth.dst == <var>E</var></code>, where <var>GW</var> is the logical router gateway port, with action - <code>next;</code>. + <code>xxreg0[80..127]=E; next;</code>. </p> <p> @@ -1770,10 +1772,10 @@ next; <pre> eth.dst = eth.src; -eth.src = <var>E</var>; +eth.src = xxreg0[80..127]; arp.op = 2; /* ARP reply. */ arp.tha = arp.sha; -arp.sha = <var>E</var>; +arp.sha = xxreg0[80..127]; arp.tpa = arp.spa; arp.spa = <var>A</var>; outport = <var>P</var>; @@ -1822,10 +1824,10 @@ output; <pre> nd_na_router { - eth.src = <var>E</var>; + eth.src = xxreg0[80..127]; ip6.src = <var>A</var>; nd.target = <var>A</var>; - nd.tll = <var>E</var>; + nd.tll = xxreg0[80..127]; outport = inport; flags.loopback = 1; output; @@ -1862,10 +1864,10 @@ nd_na_router { <pre> eth.dst = eth.src; -eth.src = <var>E</var>; +eth.src = xxreg0[80..127]; arp.op = 2; /* ARP reply. */ arp.tha = arp.sha; -arp.sha = <var>E</var>; +arp.sha = xxreg0[80..127]; arp.tpa = arp.spa; arp.spa = <var>A</var>; outport = <var>P</var>; @@ -1894,8 +1896,8 @@ output; <pre> eth.dst = eth.src; nd_na { - eth.src = <var>E</var>; - nd.tll = <var>E</var>; + eth.src = xxreg0[80..127]; + nd.tll = xxreg0[80..127]; ip6.src = <var>A</var>; nd.target = <var>A</var>; outport = <var>P</var>; diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index d02447c..92fff92 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -222,6 +222,11 @@ enum ovn_stage { #define REGBIT_LOOKUP_NEIGHBOR_RESULT "reg9[2]" #define REGBIT_SKIP_LOOKUP_NEIGHBOR "reg9[3]" +/* Register to store the eth address associated to a router port for packets + * received in S_ROUTER_IN_ADMISSION. + */ +#define REG_INPORT_ETH_ADDR "xxreg0[80..127]" + /* Register for ECMP bucket selection. */ #define REG_ECMP_GROUP_ID "reg8[0..15]" #define REG_ECMP_MEMBER_ID "reg8[16..31]" @@ -7927,10 +7932,19 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, continue; } + /* Store the ethernet address of the port receiving the packet. + * This will save us from having to match on inport further down in + * the pipeline. + */ + ds_clear(&actions); + ds_put_format(&actions, REG_INPORT_ETH_ADDR " = %s; next;", + op->lrp_networks.ea_s); + ds_clear(&match); ds_put_format(&match, "eth.mcast && inport == %s", op->json_key); ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_ADMISSION, 50, - ds_cstr(&match), "next;", &op->nbrp->header_); + ds_cstr(&match), ds_cstr(&actions), + &op->nbrp->header_); ds_clear(&match); ds_put_format(&match, "eth.dst == %s && inport == %s", @@ -7943,7 +7957,8 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, op->od->l3redirect_port->json_key); } ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_ADMISSION, 50, - ds_cstr(&match), "next;", &op->nbrp->header_); + ds_cstr(&match), ds_cstr(&actions), + &op->nbrp->header_); } /* Logical router ingress table 1: LOOKUP_NEIGHBOR and @@ -8210,17 +8225,15 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_clear(&actions); ds_put_format(&actions, "eth.dst = eth.src; " - "eth.src = %s; " + "eth.src = " REG_INPORT_ETH_ADDR "; " "arp.op = 2; /* ARP reply */ " "arp.tha = arp.sha; " - "arp.sha = %s; " + "arp.sha = " REG_INPORT_ETH_ADDR "; " "arp.tpa = arp.spa; " "arp.spa = %s; " "outport = %s; " "flags.loopback = 1; " "output;", - op->lrp_networks.ea_s, - op->lrp_networks.ea_s, op->lrp_networks.ipv4_addrs[i].addr_s, op->json_key); ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 90, @@ -8247,17 +8260,15 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_clear(&actions); ds_put_format(&actions, "eth.dst = eth.src; " - "eth.src = %s; " + "eth.src = " REG_INPORT_ETH_ADDR "; " "arp.op = 2; /* ARP reply */ " "arp.tha = arp.sha; " - "arp.sha = %s; " + "arp.sha = " REG_INPORT_ETH_ADDR "; " "arp.tpa = arp.spa; " "arp.spa = %s; " "outport = %s; " "flags.loopback = 1; " "output;", - op->lrp_networks.ea_s, - op->lrp_networks.ea_s, ip_address, op->json_key); @@ -8278,18 +8289,16 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_clear(&actions); ds_put_format(&actions, "nd_na { " - "eth.src = %s; " + "eth.src = " REG_INPORT_ETH_ADDR "; " "ip6.src = %s; " "nd.target = %s; " - "nd.tll = %s; " + "nd.tll = " REG_INPORT_ETH_ADDR "; " "outport = inport; " "flags.loopback = 1; " "output; " "};", - op->lrp_networks.ea_s, ip_address, - ip_address, - op->lrp_networks.ea_s); + ip_address); ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 90, ds_cstr(&match), ds_cstr(&actions)); @@ -8412,18 +8421,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, nat->logical_port); } else { if (is_v6) { - ds_put_format(&actions, - "eth.src = %s; " - "nd.tll = %s; ", - op->lrp_networks.ea_s, - op->lrp_networks.ea_s); + ds_put_cstr(&actions, + "eth.src = " REG_INPORT_ETH_ADDR "; " + "nd.tll = " REG_INPORT_ETH_ADDR "; "); } else { - ds_put_format(&actions, - "eth.src = %s; " - "arp.sha = %s; ", - op->lrp_networks.ea_s, - op->lrp_networks.ea_s); + ds_put_cstr(&actions, + "eth.src = "REG_INPORT_ETH_ADDR "; " + "arp.sha = " REG_INPORT_ETH_ADDR "; "); } /* Traffic with eth.src = l3dgw_port->lrp_networks.ea_s * should only be sent from the "redirect-chassis", so that @@ -8437,17 +8442,13 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, } } else { if (is_v6) { - ds_put_format(&actions, - "eth.src = %s; " - "nd.tll = %s; ", - op->lrp_networks.ea_s, - op->lrp_networks.ea_s); + ds_put_cstr(&actions, + "eth.src = " REG_INPORT_ETH_ADDR "; " + "nd.tll = " REG_INPORT_ETH_ADDR "; "); } else { ds_put_format(&actions, - "eth.src = %s; " - "arp.sha = %s; ", - op->lrp_networks.ea_s, - op->lrp_networks.ea_s); + "eth.src = " REG_INPORT_ETH_ADDR "; " + "arp.sha = " REG_INPORT_ETH_ADDR "; "); } } if (is_v6) { @@ -8665,18 +8666,16 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, ds_clear(&actions); ds_put_format(&actions, "nd_na_router { " - "eth.src = %s; " + "eth.src = " REG_INPORT_ETH_ADDR "; " "ip6.src = %s; " "nd.target = %s; " - "nd.tll = %s; " + "nd.tll = " REG_INPORT_ETH_ADDR "; " "outport = inport; " "flags.loopback = 1; " "output; " "};", - op->lrp_networks.ea_s, - op->lrp_networks.ipv6_addrs[i].addr_s, op->lrp_networks.ipv6_addrs[i].addr_s, - op->lrp_networks.ea_s); + op->lrp_networks.ipv6_addrs[i].addr_s); ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 90, ds_cstr(&match), ds_cstr(&actions), &op->nbrp->header_); @@ -9177,6 +9176,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, * on the l3dgw_port instance where nat->logical_port is * resident. */ if (distributed) { + /* Store the ethernet address of the port receiving the packet. + * This will save us from having to match on inport further + * down in the pipeline. + */ + ds_clear(&actions); + ds_put_format(&actions, REG_INPORT_ETH_ADDR " = %s; next;", + od->l3dgw_port->lrp_networks.ea_s); + ds_clear(&match); ds_put_format(&match, "eth.dst == "ETH_ADDR_FMT" && inport == %s" @@ -9185,7 +9192,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, od->l3dgw_port->json_key, nat->logical_port); ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ADMISSION, 50, - ds_cstr(&match), "next;", + ds_cstr(&match), ds_cstr(&actions), &nat->header_); } _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
