On Thu, Sep 29, 2016 at 11:31 AM, Ben Pfaff <b...@ovn.org> wrote:
>
> When a VM sends an ARP or an ND NS for its own IP address, it is trying to
> check for a duplicate address in the network.  OVN needs to suppress the
> reply in such a case, otherwise the VM thinks that its address is a
> duplicate.
>
> Reported-by: Valentine Sinitsyn <valentine.sinit...@gmail.com>
> Reported-at:
http://openvswitch.org/pipermail/dev/2016-September/080037.html
> Signed-off-by: Ben Pfaff <b...@ovn.org>
> ---
>  ovn/northd/ovn-northd.8.xml | 23 +++++++++++++++++++++++
>  ovn/northd/ovn-northd.c     | 22 ++++++++++++++++++++++
>  tests/ovn.at                | 14 ++++++++++----
>  3 files changed, 55 insertions(+), 4 deletions(-)
>
> diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
> index 1da633a..77eb3d1 100644
> --- a/ovn/northd/ovn-northd.8.xml
> +++ b/ovn/northd/ovn-northd.8.xml
> @@ -479,6 +479,29 @@ nd_na {
>        </li>
>
>        <li>
> +        <p>
> +          Priority-100 flows with match criteria like the ARP and ND
flows
> +          above, except that they only match packets from the
> +          <code>inport</code> that owns the IP addresses in question,
with
> +          action <code>next;</code>.  These flows prevent OVN from
replying to,
> +          for example, an ARP request emitted by a VM for its own IP
address.
> +          A VM only makes this kind of request to attempt to detect a
duplicate
> +          IP address assignment, so sending a reply will prevent the VM
from
> +          accepting the IP address that it owns.
> +        </p>
> +
> +        <p>
> +          In place of <code>next;</code>, it would be reasonable to use
> +          <code>drop;</code> for the flows' actions.  If everything is
working
> +          as it is configured, then this would produce equivalent
results,
> +          since no host should reply to the request.  But ARPing for
one's own
> +          IP address is intended to detect situations where the network
is not
> +          working as configured, so dropping the request would frustrate
that
> +          intent.
> +        </p>
> +      </li>
> +
> +      <li>
>          One priority-0 fallback flow that matches all packets and
advances to
>          the next table.
>        </li>
> diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
> index cdc5525..eeeb41d 100644
> --- a/ovn/northd/ovn-northd.c
> +++ b/ovn/northd/ovn-northd.c
> @@ -2728,6 +2728,22 @@ build_lswitch_flows(struct hmap *datapaths, struct
hmap *ports,
>                      op->lsp_addrs[i].ipv4_addrs[j].addr_s);
>                  ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, 50,
>                                ds_cstr(&match), ds_cstr(&actions));
> +
> +                /* Do not reply to an ARP request from the port that
owns the
> +                 * address (otherwise a DHCP client that ARPs to check
for a
> +                 * duplicate address will fail).  Instead, forward it
the usual
> +                 * way.
> +                 *
> +                 * (Another alternative would be to simply drop the
packet.  If
> +                 * everything is working as it is configured, then this
would
> +                 * produce equivalent results, since no one should reply
to the
> +                 * request.  But ARPing for one's own IP address is
intended to
> +                 * detect situations where the network is not working as
> +                 * configured, so dropping the request would frustrate
that
> +                 * intent.) */
> +                ds_put_format(&match, " && inport == %s", op->json_key);
> +                ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP,
100,
> +                              ds_cstr(&match), "next;");
>              }
>
>              /* For ND solicitations, we need to listen for both the
> @@ -2758,6 +2774,12 @@ build_lswitch_flows(struct hmap *datapaths, struct
hmap *ports,
>                          op->lsp_addrs[i].ea_s);
>                  ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, 50,
>                                ds_cstr(&match), ds_cstr(&actions));
> +
> +                /* Do not reply to a solicitation from the port that
owns the
> +                 * address (otherwise DAD detection will fail). */
> +                ds_put_format(&match, " && inport == %s", op->json_key);
> +                ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP,
100,
> +                              ds_cstr(&match), "next;");
>              }
>          }
>      }
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 677ab46..68885b9 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -1159,13 +1159,18 @@ for is in 1 2 3; do
>                  sip=`ip_to_hex 192 168 0 $i$j`
>                  tip=`ip_to_hex 192 168 0 $id$jd`
>                  tip_unknown=`ip_to_hex 11 11 11 11`
> -                test_arp $s f000000000$s $sip $tip f000000000$d
   #9
> +                if test $d != $s; then
> +                    reply_ha=f000000000$d
> +                else
> +                    reply_ha=
> +                fi
> +                test_arp $s f000000000$s $sip $tip $reply_ha
  #9
>                  test_arp $s f000000000$s $sip $tip_unknown
  #10
>
>                  if test $jd = 3; then
>                      # lsp[123]3 has an additional ip 192.169.0.[123]3.
>                      tip=`ip_to_hex 192 169 0 $id$jd`
> -                    test_arp $s f000000000$s $sip $tip f000000000$d
   #9
> +                    test_arp $s f000000000$s $sip $tip $reply_ha
  #9
>                  fi
>              done
>          done
> @@ -1413,13 +1418,14 @@ for s in 1 2 3; do
>          sip=192.168.0.$s
>          tip=192.168.0.$d
>          tip_unknown=11.11.11.11
> -        test_arp $s f0:00:00:00:00:0$s $sip $tip f0:00:00:00:00:0$d
   #9
> +        if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else
reply_ha=; fi
> +        test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha
  #9
>          test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown
  #10
>
>          if test $d = 3; then
>              # lp3 has an additional ip 192.169.0.[123]3.
>              tip=192.169.0.$d
> -            test_arp $s f0:00:00:00:00:0$s $sip $tip f0:00:00:00:00:0$d
   #9
> +            test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha
  #9
>          fi
>      done
>
> --
> 2.1.3
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev

+1

It will also solve a problem when there are nested VMs (or network
namespaces) within the source VM, connected to VM port by a bridge inside,
sending ARP for the VM's IP, they would get duplicated responses.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to