Re: [ovs-dev] [PATCH v3 ovn 2/4] ovn-northd: Move NAT ARP/ND resolution to separate functions.

2020-09-22 Thread Numan Siddique
On Mon, Sep 21, 2020 at 12:23 PM Han Zhou  wrote:

> On Thu, Sep 17, 2020 at 5:51 AM Dumitru Ceara  wrote:
> >
> > To avoid duplicating code later on, move out the code that generates
> ARP/ND
> > replies for NAT external IPs to separate functions.
> >
> > Signed-off-by: Dumitru Ceara 
> > ---
> >  northd/ovn-northd.c |  172
> ---
> >  1 file changed, 94 insertions(+), 78 deletions(-)
> >
> > diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> > index d5d7631..f79ed99 100644
> > --- a/northd/ovn-northd.c
> > +++ b/northd/ovn-northd.c
> > @@ -8636,6 +8636,94 @@ build_lrouter_nd_flow(struct ovn_datapath *od,
> struct ovn_port *op,
> >  }
> >
> >  static void
> > +build_lrouter_nat_arp_nd_flow(struct ovn_datapath *od,
> > +  struct ovn_nat *nat_entry,
> > +  struct hmap *lflows)
> > +{
> > +struct lport_addresses *ext_addrs = _entry->ext_addrs;
> > +const struct nbrec_nat *nat = nat_entry->nb;
> > +
> > +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,
> > +  >header_, lflows);
> > +} else {
> > +build_lrouter_arp_flow(od, NULL,
> > +   ext_addrs->ipv4_addrs[0].addr_s,
> > +   REG_INPORT_ETH_ADDR, NULL, false, 90,
> > +   >header_, lflows);
> > +}
> > +}
> > +
> > +static void
> > +build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
> > +   struct ovn_nat *nat_entry,
> > +   struct hmap *lflows)
> > +{
> > +struct lport_addresses *ext_addrs = _entry->ext_addrs;
> > +const struct nbrec_nat *nat = nat_entry->nb;
> > +struct ds match = DS_EMPTY_INITIALIZER;
> > +
> > +/* Mac address to use when replying to ARP/NS. */
> > +const char *mac_s = REG_INPORT_ETH_ADDR;
> > +struct eth_addr mac;
> > +
> > +if (nat->external_mac &&
> > +eth_addr_from_string(nat->external_mac, )
> > +&& nat->logical_port) {
> > +/* distributed NAT case, use nat->external_mac */
> > +mac_s = nat->external_mac;
> > +/* Traffic with eth.src = nat->external_mac should only be
> > + * sent from the chassis where nat->logical_port is
> > + * resident, so that upstream MAC learning points to the
> > + * correct chassis.  Also need to avoid generation of
> > + * multiple ARP responses from different chassis. */
> > +ds_put_format(, "is_chassis_resident(\"%s\")",
> > +  nat->logical_port);
> > +} else {
> > +mac_s = REG_INPORT_ETH_ADDR;
> > +/* Traffic with eth.src = l3dgw_port->lrp_networks.ea_s
> > + * should only be sent from the "redirect-chassis", so that
> > + * upstream MAC learning points to the "redirect-chassis".
> > + * Also need to avoid generation of multiple ARP responses
> > + * from different chassis. */
> > +if (op->od->l3redirect_port) {
> > +ds_put_format(, "is_chassis_resident(%s)",
> > +  op->od->l3redirect_port->json_key);
> > +}
> > +}
> > +
> > +/* Respond to ARP/NS requests on the chassis that binds the gw
> > + * port. Drop the ARP/NS requests on other chassis.
> > + */
> > +if (nat_entry_is_v6(nat_entry)) {
> > +build_lrouter_nd_flow(op->od, op, "nd_na",
> > +  ext_addrs->ipv6_addrs[0].addr_s,
> > +  ext_addrs->ipv6_addrs[0].sn_addr_s,
> > +  mac_s, , false, 92,
> > +  >header_, lflows);
> > +build_lrouter_nd_flow(op->od, op, "nd_na",
> > +  ext_addrs->ipv6_addrs[0].addr_s,
> > +  ext_addrs->ipv6_addrs[0].sn_addr_s,
> > +  mac_s, NULL, true, 91,
> > +  >header_, lflows);
> > +} else {
> > +build_lrouter_arp_flow(op->od, op,
> > +   ext_addrs->ipv4_addrs[0].addr_s,
> > +   mac_s, , false, 92,
> > +   >header_, lflows);
> > +build_lrouter_arp_flow(op->od, op,
> > +   ext_addrs->ipv4_addrs[0].addr_s,
> > +   mac_s, NULL, true, 91,
> > +   >header_, lflows);
> > +}
> > +
> > +ds_destroy();
> > +}
> > +
> > +static void
> >  build_lrouter_force_snat_flows(struct hmap *lflows, struct ovn_datapath
> *od,
> > const char *ip_version, const char
> *ip_addr,
> >   

Re: [ovs-dev] [PATCH v3 ovn 2/4] ovn-northd: Move NAT ARP/ND resolution to separate functions.

2020-09-21 Thread Han Zhou
On Thu, Sep 17, 2020 at 5:51 AM Dumitru Ceara  wrote:
>
> To avoid duplicating code later on, move out the code that generates
ARP/ND
> replies for NAT external IPs to separate functions.
>
> Signed-off-by: Dumitru Ceara 
> ---
>  northd/ovn-northd.c |  172
---
>  1 file changed, 94 insertions(+), 78 deletions(-)
>
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index d5d7631..f79ed99 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -8636,6 +8636,94 @@ build_lrouter_nd_flow(struct ovn_datapath *od,
struct ovn_port *op,
>  }
>
>  static void
> +build_lrouter_nat_arp_nd_flow(struct ovn_datapath *od,
> +  struct ovn_nat *nat_entry,
> +  struct hmap *lflows)
> +{
> +struct lport_addresses *ext_addrs = _entry->ext_addrs;
> +const struct nbrec_nat *nat = nat_entry->nb;
> +
> +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,
> +  >header_, lflows);
> +} else {
> +build_lrouter_arp_flow(od, NULL,
> +   ext_addrs->ipv4_addrs[0].addr_s,
> +   REG_INPORT_ETH_ADDR, NULL, false, 90,
> +   >header_, lflows);
> +}
> +}
> +
> +static void
> +build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
> +   struct ovn_nat *nat_entry,
> +   struct hmap *lflows)
> +{
> +struct lport_addresses *ext_addrs = _entry->ext_addrs;
> +const struct nbrec_nat *nat = nat_entry->nb;
> +struct ds match = DS_EMPTY_INITIALIZER;
> +
> +/* Mac address to use when replying to ARP/NS. */
> +const char *mac_s = REG_INPORT_ETH_ADDR;
> +struct eth_addr mac;
> +
> +if (nat->external_mac &&
> +eth_addr_from_string(nat->external_mac, )
> +&& nat->logical_port) {
> +/* distributed NAT case, use nat->external_mac */
> +mac_s = nat->external_mac;
> +/* Traffic with eth.src = nat->external_mac should only be
> + * sent from the chassis where nat->logical_port is
> + * resident, so that upstream MAC learning points to the
> + * correct chassis.  Also need to avoid generation of
> + * multiple ARP responses from different chassis. */
> +ds_put_format(, "is_chassis_resident(\"%s\")",
> +  nat->logical_port);
> +} else {
> +mac_s = REG_INPORT_ETH_ADDR;
> +/* Traffic with eth.src = l3dgw_port->lrp_networks.ea_s
> + * should only be sent from the "redirect-chassis", so that
> + * upstream MAC learning points to the "redirect-chassis".
> + * Also need to avoid generation of multiple ARP responses
> + * from different chassis. */
> +if (op->od->l3redirect_port) {
> +ds_put_format(, "is_chassis_resident(%s)",
> +  op->od->l3redirect_port->json_key);
> +}
> +}
> +
> +/* Respond to ARP/NS requests on the chassis that binds the gw
> + * port. Drop the ARP/NS requests on other chassis.
> + */
> +if (nat_entry_is_v6(nat_entry)) {
> +build_lrouter_nd_flow(op->od, op, "nd_na",
> +  ext_addrs->ipv6_addrs[0].addr_s,
> +  ext_addrs->ipv6_addrs[0].sn_addr_s,
> +  mac_s, , false, 92,
> +  >header_, lflows);
> +build_lrouter_nd_flow(op->od, op, "nd_na",
> +  ext_addrs->ipv6_addrs[0].addr_s,
> +  ext_addrs->ipv6_addrs[0].sn_addr_s,
> +  mac_s, NULL, true, 91,
> +  >header_, lflows);
> +} else {
> +build_lrouter_arp_flow(op->od, op,
> +   ext_addrs->ipv4_addrs[0].addr_s,
> +   mac_s, , false, 92,
> +   >header_, lflows);
> +build_lrouter_arp_flow(op->od, op,
> +   ext_addrs->ipv4_addrs[0].addr_s,
> +   mac_s, NULL, true, 91,
> +   >header_, lflows);
> +}
> +
> +ds_destroy();
> +}
> +
> +static void
>  build_lrouter_force_snat_flows(struct hmap *lflows, struct ovn_datapath
*od,
> const char *ip_version, const char
*ip_addr,
> const char *context)
> @@ -8869,6 +8957,10 @@ build_lrouter_flows(struct hmap *datapaths, struct
hmap *ports,
>  /* Priority-90-92 flows handle ARP requests and ND packets. Most
are
>   * per logical port but DNAT addresses can be