diff mbox series

[ovs-dev] nb: Add Load_Balancer.options:neighbor_responder knob.

Message ID 20220428153314.31498-1-dceara@redhat.com
State Accepted
Headers show
Series [ovs-dev] nb: Add Load_Balancer.options:neighbor_responder knob. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test fail github build: failed
ovsrobot/github-robot-_ovn-kubernetes fail github build: failed

Commit Message

Dumitru Ceara April 28, 2022, 3:33 p.m. UTC
This allows CMS to tweak the way logical routers reply to ARP/ND packets
targeting load balancer VIPs.  By default a router only replies for VIPs
that are reachable locally (they're part of a subnet configured on the
router).  There are cases though when it's desirable for routers to
reply for all VIPs.

Reported-at: https://github.com/ovn-org/ovn/issues/124
Reported-by: Tom Parrott <tomp@tomp.uk>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
---
 NEWS                |  4 ++++
 northd/northd.c     | 20 ++++++++++++++++++++
 ovn-nb.xml          |  9 +++++++++
 tests/ovn-northd.at | 10 ++++++++--
 4 files changed, 41 insertions(+), 2 deletions(-)

Comments

Mark Michelson May 11, 2022, 6:48 p.m. UTC | #1
Thanks for this Dumitru.

Acked-by: Mark Michelson <mmichels@redhat.com>

On 4/28/22 11:33, Dumitru Ceara wrote:
> This allows CMS to tweak the way logical routers reply to ARP/ND packets
> targeting load balancer VIPs.  By default a router only replies for VIPs
> that are reachable locally (they're part of a subnet configured on the
> router).  There are cases though when it's desirable for routers to
> reply for all VIPs.
> 
> Reported-at: https://github.com/ovn-org/ovn/issues/124
> Reported-by: Tom Parrott <tomp@tomp.uk>
> Signed-off-by: Dumitru Ceara <dceara@redhat.com>
> ---
>   NEWS                |  4 ++++
>   northd/northd.c     | 20 ++++++++++++++++++++
>   ovn-nb.xml          |  9 +++++++++
>   tests/ovn-northd.at | 10 ++++++++--
>   4 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index dbe89e9cf..ed735c32c 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -7,6 +7,10 @@ Post v22.03.0
>     - Support NAT for logical routers with multiple distributed gateway ports.
>     - Add global option (NB_Global.options:default_acl_drop) to enable
>       implicit drop behavior on logical switches with ACLs applied.
> +  - Add NB.Load_Balancer.options:neighbor_responder to allow the CMS to
> +    explicitly request routers to reply to any ARP/ND request for a VIP
> +    (when set to "all") and only for reachable VIPs (when set to "reachable"
> +    or by default).
>   
>   OVN v22.03.0 - 11 Mar 2022
>   --------------------------
> diff --git a/northd/northd.c b/northd/northd.c
> index a56666297..f01bd2cf7 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -3920,6 +3920,26 @@ static void
>   build_lrouter_lb_reachable_ips(struct ovn_datapath *od,
>                                  const struct ovn_northd_lb *lb)
>   {
> +    const char *neighbor_responder_mode =
> +        smap_get_def(&lb->nlb->options, "neighbor_responder", "reachable");
> +
> +    /* If configured to reply to neighbor requests for all VIPs force them
> +     * all to be considered "reachable".
> +     */
> +    if (!strcmp(neighbor_responder_mode, "all")) {
> +        for (size_t i = 0; i < lb->n_vips; i++) {
> +            if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
> +                sset_add(&od->lb_ips_v4_reachable, lb->vips[i].vip_str);
> +            } else {
> +                sset_add(&od->lb_ips_v6_reachable, lb->vips[i].vip_str);
> +            }
> +        }
> +        return;
> +    }
> +
> +    /* Otherwise, a VIP is reachable if there's at least one router
> +     * subnet that includes it.
> +     */
>       for (size_t i = 0; i < lb->n_vips; i++) {
>           if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
>               ovs_be32 vip_ip4 = in6_addr_get_mapped_ipv4(&lb->vips[i].vip);
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 9010240a8..756c2a378 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -1856,6 +1856,15 @@
>           more information about what flows are added for IP routes, please
>           see the <code>ovn-northd</code> manpage section on IP Routing.
>         </column>
> +
> +      <column name="options" key="neighbor_responder">
> +        If set to <code>all</code>, then routers on which the load balancer
> +        is applied reply to ARP/neighbor discovery requests for all VIPs
> +        of the load balancer.  If set to <code>reachable</code>, then routers
> +        on which the load balancer is applied reply to ARP/neighbor discovery
> +        requests only for VIPs that are part of a router's subnet.  The default
> +        value of this option, if not specified, is <code>reachable</code>.
> +      </column>
>       </group>
>     </table>
>   
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 69ad85533..8e256de2e 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -1708,6 +1708,10 @@ ovn-nbctl lb-add lb5 "[[fe80::200:ff:fe00:101]]:8080" "[[fe02::200:ff:fe00:101]]
>   ovn-nbctl lb-add lb5 "[[fe80::200:ff:fe00:102]]:8080" "[[fe02::200:ff:fe00:102]]:8080"
>   ovn-nbctl lb-add lb6 "43.43.43.43:8080" "10.0.0.8:8080" udp
>   ovn-nbctl lb-add lb7 "[[4343::4343]]:8080" "[[10::10]]:8080" udp
> +ovn-nbctl lb-add lb8 "44.44.44.44:8080" "10.0.0.8:8080" udp
> +ovn-nbctl set Load_Balancer lb8 options:neighbor_responder=all
> +ovn-nbctl lb-add lb9 "[[4444::4444]]:8080" "[[10::10]]:8080" udp
> +ovn-nbctl set Load_Balancer lb9 options:neighbor_responder=all
>   
>   ovn-nbctl lr-lb-add lr lb1
>   ovn-nbctl lr-lb-add lr lb2
> @@ -1716,6 +1720,8 @@ ovn-nbctl lr-lb-add lr lb4
>   ovn-nbctl lr-lb-add lr lb5
>   ovn-nbctl lr-lb-add lr lb6
>   ovn-nbctl lr-lb-add lr lb7
> +ovn-nbctl lr-lb-add lr lb8
> +ovn-nbctl lr-lb-add lr lb9
>   
>   ovn-nbctl --wait=sb sync
>   lr_key=$(fetch_column sb:datapath_binding tunnel_key external_ids:name=lr)
> @@ -1723,8 +1729,8 @@ lb_as_v4="_rtr_lb_${lr_key}_ip4"
>   lb_as_v6="_rtr_lb_${lr_key}_ip6"
>   
>   # Check generated VIP address sets (only reachable IPs).
> -check_column '43.43.43.43' Address_Set addresses name=${lb_as_v4}
> -check_column '4343::4343 fe80::200:ff:fe00:101 fe80::200:ff:fe00:102' Address_Set addresses name=${lb_as_v6}
> +check_column '43.43.43.43 44.44.44.44' Address_Set addresses name=${lb_as_v4}
> +check_column '4343::4343 4444::4444 fe80::200:ff:fe00:101 fe80::200:ff:fe00:102' Address_Set addresses name=${lb_as_v6}
>   
>   # Ingress router port ETH address is stored in lr_in_admission.
>   AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_admission.*xreg0\[[0..47\]]" | sort], [0], [dnl
>
Mark Michelson May 18, 2022, 5:53 p.m. UTC | #2
I applied this to main.

On 5/11/22 14:48, Mark Michelson wrote:
> Thanks for this Dumitru.
> 
> Acked-by: Mark Michelson <mmichels@redhat.com>
> 
> On 4/28/22 11:33, Dumitru Ceara wrote:
>> This allows CMS to tweak the way logical routers reply to ARP/ND packets
>> targeting load balancer VIPs.  By default a router only replies for VIPs
>> that are reachable locally (they're part of a subnet configured on the
>> router).  There are cases though when it's desirable for routers to
>> reply for all VIPs.
>>
>> Reported-at: https://github.com/ovn-org/ovn/issues/124
>> Reported-by: Tom Parrott <tomp@tomp.uk>
>> Signed-off-by: Dumitru Ceara <dceara@redhat.com>
>> ---
>>   NEWS                |  4 ++++
>>   northd/northd.c     | 20 ++++++++++++++++++++
>>   ovn-nb.xml          |  9 +++++++++
>>   tests/ovn-northd.at | 10 ++++++++--
>>   4 files changed, 41 insertions(+), 2 deletions(-)
>>
>> diff --git a/NEWS b/NEWS
>> index dbe89e9cf..ed735c32c 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -7,6 +7,10 @@ Post v22.03.0
>>     - Support NAT for logical routers with multiple distributed 
>> gateway ports.
>>     - Add global option (NB_Global.options:default_acl_drop) to enable
>>       implicit drop behavior on logical switches with ACLs applied.
>> +  - Add NB.Load_Balancer.options:neighbor_responder to allow the CMS to
>> +    explicitly request routers to reply to any ARP/ND request for a VIP
>> +    (when set to "all") and only for reachable VIPs (when set to 
>> "reachable"
>> +    or by default).
>>   OVN v22.03.0 - 11 Mar 2022
>>   --------------------------
>> diff --git a/northd/northd.c b/northd/northd.c
>> index a56666297..f01bd2cf7 100644
>> --- a/northd/northd.c
>> +++ b/northd/northd.c
>> @@ -3920,6 +3920,26 @@ static void
>>   build_lrouter_lb_reachable_ips(struct ovn_datapath *od,
>>                                  const struct ovn_northd_lb *lb)
>>   {
>> +    const char *neighbor_responder_mode =
>> +        smap_get_def(&lb->nlb->options, "neighbor_responder", 
>> "reachable");
>> +
>> +    /* If configured to reply to neighbor requests for all VIPs force 
>> them
>> +     * all to be considered "reachable".
>> +     */
>> +    if (!strcmp(neighbor_responder_mode, "all")) {
>> +        for (size_t i = 0; i < lb->n_vips; i++) {
>> +            if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
>> +                sset_add(&od->lb_ips_v4_reachable, lb->vips[i].vip_str);
>> +            } else {
>> +                sset_add(&od->lb_ips_v6_reachable, lb->vips[i].vip_str);
>> +            }
>> +        }
>> +        return;
>> +    }
>> +
>> +    /* Otherwise, a VIP is reachable if there's at least one router
>> +     * subnet that includes it.
>> +     */
>>       for (size_t i = 0; i < lb->n_vips; i++) {
>>           if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
>>               ovs_be32 vip_ip4 = 
>> in6_addr_get_mapped_ipv4(&lb->vips[i].vip);
>> diff --git a/ovn-nb.xml b/ovn-nb.xml
>> index 9010240a8..756c2a378 100644
>> --- a/ovn-nb.xml
>> +++ b/ovn-nb.xml
>> @@ -1856,6 +1856,15 @@
>>           more information about what flows are added for IP routes, 
>> please
>>           see the <code>ovn-northd</code> manpage section on IP Routing.
>>         </column>
>> +
>> +      <column name="options" key="neighbor_responder">
>> +        If set to <code>all</code>, then routers on which the load 
>> balancer
>> +        is applied reply to ARP/neighbor discovery requests for all VIPs
>> +        of the load balancer.  If set to <code>reachable</code>, then 
>> routers
>> +        on which the load balancer is applied reply to ARP/neighbor 
>> discovery
>> +        requests only for VIPs that are part of a router's subnet.  
>> The default
>> +        value of this option, if not specified, is 
>> <code>reachable</code>.
>> +      </column>
>>       </group>
>>     </table>
>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
>> index 69ad85533..8e256de2e 100644
>> --- a/tests/ovn-northd.at
>> +++ b/tests/ovn-northd.at
>> @@ -1708,6 +1708,10 @@ ovn-nbctl lb-add lb5 
>> "[[fe80::200:ff:fe00:101]]:8080" "[[fe02::200:ff:fe00:101]]
>>   ovn-nbctl lb-add lb5 "[[fe80::200:ff:fe00:102]]:8080" 
>> "[[fe02::200:ff:fe00:102]]:8080"
>>   ovn-nbctl lb-add lb6 "43.43.43.43:8080" "10.0.0.8:8080" udp
>>   ovn-nbctl lb-add lb7 "[[4343::4343]]:8080" "[[10::10]]:8080" udp
>> +ovn-nbctl lb-add lb8 "44.44.44.44:8080" "10.0.0.8:8080" udp
>> +ovn-nbctl set Load_Balancer lb8 options:neighbor_responder=all
>> +ovn-nbctl lb-add lb9 "[[4444::4444]]:8080" "[[10::10]]:8080" udp
>> +ovn-nbctl set Load_Balancer lb9 options:neighbor_responder=all
>>   ovn-nbctl lr-lb-add lr lb1
>>   ovn-nbctl lr-lb-add lr lb2
>> @@ -1716,6 +1720,8 @@ ovn-nbctl lr-lb-add lr lb4
>>   ovn-nbctl lr-lb-add lr lb5
>>   ovn-nbctl lr-lb-add lr lb6
>>   ovn-nbctl lr-lb-add lr lb7
>> +ovn-nbctl lr-lb-add lr lb8
>> +ovn-nbctl lr-lb-add lr lb9
>>   ovn-nbctl --wait=sb sync
>>   lr_key=$(fetch_column sb:datapath_binding tunnel_key 
>> external_ids:name=lr)
>> @@ -1723,8 +1729,8 @@ lb_as_v4="_rtr_lb_${lr_key}_ip4"
>>   lb_as_v6="_rtr_lb_${lr_key}_ip6"
>>   # Check generated VIP address sets (only reachable IPs).
>> -check_column '43.43.43.43' Address_Set addresses name=${lb_as_v4}
>> -check_column '4343::4343 fe80::200:ff:fe00:101 fe80::200:ff:fe00:102' 
>> Address_Set addresses name=${lb_as_v6}
>> +check_column '43.43.43.43 44.44.44.44' Address_Set addresses 
>> name=${lb_as_v4}
>> +check_column '4343::4343 4444::4444 fe80::200:ff:fe00:101 
>> fe80::200:ff:fe00:102' Address_Set addresses name=${lb_as_v6}
>>   # Ingress router port ETH address is stored in lr_in_admission.
>>   AT_CHECK([ovn-sbctl lflow-list | grep -E 
>> "lr_in_admission.*xreg0\[[0..47\]]" | sort], [0], [dnl
>>
>
Tom Parrott May 19, 2022, 2:58 p.m. UTC | #3
Thanks!

On 2022-05-18 18:53, Mark Michelson wrote:

> I applied this to main.
> 
> On 5/11/22 14:48, Mark Michelson wrote: Thanks for this Dumitru.
> 
> Acked-by: Mark Michelson <mmichels@redhat.com>
> 
> On 4/28/22 11:33, Dumitru Ceara wrote: This allows CMS to tweak the way 
> logical routers reply to ARP/ND packets
> targeting load balancer VIPs.  By default a router only replies for 
> VIPs
> that are reachable locally (they're part of a subnet configured on the
> router).  There are cases though when it's desirable for routers to
> reply for all VIPs.
> 
> Reported-at: https://github.com/ovn-org/ovn/issues/124
> Reported-by: Tom Parrott <tomp@tomp.uk>
> Signed-off-by: Dumitru Ceara <dceara@redhat.com>
> ---
> NEWS                |  4 ++++
> northd/northd.c     | 20 ++++++++++++++++++++
> ovn-nb.xml          |  9 +++++++++
> tests/ovn-northd.at | 10 ++++++++--
> 4 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index dbe89e9cf..ed735c32c 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -7,6 +7,10 @@ Post v22.03.0
> - Support NAT for logical routers with multiple distributed gateway 
> ports.
> - Add global option (NB_Global.options:default_acl_drop) to enable
> implicit drop behavior on logical switches with ACLs applied.
> +  - Add NB.Load_Balancer.options:neighbor_responder to allow the CMS 
> to
> +    explicitly request routers to reply to any ARP/ND request for a 
> VIP
> +    (when set to "all") and only for reachable VIPs (when set to 
> "reachable"
> +    or by default).
> OVN v22.03.0 - 11 Mar 2022
> --------------------------
> diff --git a/northd/northd.c b/northd/northd.c
> index a56666297..f01bd2cf7 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -3920,6 +3920,26 @@ static void
> build_lrouter_lb_reachable_ips(struct ovn_datapath *od,
> const struct ovn_northd_lb *lb)
> {
> +    const char *neighbor_responder_mode =
> +        smap_get_def(&lb->nlb->options, "neighbor_responder", 
> "reachable");
> +
> +    /* If configured to reply to neighbor requests for all VIPs force 
> them
> +     * all to be considered "reachable".
> +     */
> +    if (!strcmp(neighbor_responder_mode, "all")) {
> +        for (size_t i = 0; i < lb->n_vips; i++) {
> +            if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
> +                sset_add(&od->lb_ips_v4_reachable, 
> lb->vips[i].vip_str);
> +            } else {
> +                sset_add(&od->lb_ips_v6_reachable, 
> lb->vips[i].vip_str);
> +            }
> +        }
> +        return;
> +    }
> +
> +    /* Otherwise, a VIP is reachable if there's at least one router
> +     * subnet that includes it.
> +     */
> for (size_t i = 0; i < lb->n_vips; i++) {
> if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
> ovs_be32 vip_ip4 = in6_addr_get_mapped_ipv4(&lb->vips[i].vip);
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 9010240a8..756c2a378 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -1856,6 +1856,15 @@
> more information about what flows are added for IP routes, please
> see the <code>ovn-northd</code> manpage section on IP Routing.
> </column>
> +
> +      <column name="options" key="neighbor_responder">
> +        If set to <code>all</code>, then routers on which the load 
> balancer
> +        is applied reply to ARP/neighbor discovery requests for all 
> VIPs
> +        of the load balancer.  If set to <code>reachable</code>, then 
> routers
> +        on which the load balancer is applied reply to ARP/neighbor 
> discovery
> +        requests only for VIPs that are part of a router's subnet.  
> The default
> +        value of this option, if not specified, is 
> <code>reachable</code>.
> +      </column>
> </group>
> </table>
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 69ad85533..8e256de2e 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -1708,6 +1708,10 @@ ovn-nbctl lb-add lb5 
> "[[fe80::200:ff:fe00:101]]:8080" "[[fe02::200:ff:fe00:101]]
> ovn-nbctl lb-add lb5 "[[fe80::200:ff:fe00:102]]:8080" 
> "[[fe02::200:ff:fe00:102]]:8080"
> ovn-nbctl lb-add lb6 "43.43.43.43:8080" "10.0.0.8:8080" udp
> ovn-nbctl lb-add lb7 "[[4343::4343]]:8080" "[[10::10]]:8080" udp
> +ovn-nbctl lb-add lb8 "44.44.44.44:8080" "10.0.0.8:8080" udp
> +ovn-nbctl set Load_Balancer lb8 options:neighbor_responder=all
> +ovn-nbctl lb-add lb9 "[[4444::4444]]:8080" "[[10::10]]:8080" udp
> +ovn-nbctl set Load_Balancer lb9 options:neighbor_responder=all
> ovn-nbctl lr-lb-add lr lb1
> ovn-nbctl lr-lb-add lr lb2
> @@ -1716,6 +1720,8 @@ ovn-nbctl lr-lb-add lr lb4
> ovn-nbctl lr-lb-add lr lb5
> ovn-nbctl lr-lb-add lr lb6
> ovn-nbctl lr-lb-add lr lb7
> +ovn-nbctl lr-lb-add lr lb8
> +ovn-nbctl lr-lb-add lr lb9
> ovn-nbctl --wait=sb sync
> lr_key=$(fetch_column sb:datapath_binding tunnel_key 
> external_ids:name=lr)
> @@ -1723,8 +1729,8 @@ lb_as_v4="_rtr_lb_${lr_key}_ip4"
> lb_as_v6="_rtr_lb_${lr_key}_ip6"
> # Check generated VIP address sets (only reachable IPs).
> -check_column '43.43.43.43' Address_Set addresses name=${lb_as_v4}
> -check_column '4343::4343 fe80::200:ff:fe00:101 fe80::200:ff:fe00:102' 
> Address_Set addresses name=${lb_as_v6}
> +check_column '43.43.43.43 44.44.44.44' Address_Set addresses 
> name=${lb_as_v4}
> +check_column '4343::4343 4444::4444 fe80::200:ff:fe00:101 
> fe80::200:ff:fe00:102' Address_Set addresses name=${lb_as_v6}
> # Ingress router port ETH address is stored in lr_in_admission.
> AT_CHECK([ovn-sbctl lflow-list | grep -E 
> "lr_in_admission.*xreg0\[[0..47\]]" | sort], [0], [dnl
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index dbe89e9cf..ed735c32c 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@  Post v22.03.0
   - Support NAT for logical routers with multiple distributed gateway ports.
   - Add global option (NB_Global.options:default_acl_drop) to enable
     implicit drop behavior on logical switches with ACLs applied.
+  - Add NB.Load_Balancer.options:neighbor_responder to allow the CMS to
+    explicitly request routers to reply to any ARP/ND request for a VIP
+    (when set to "all") and only for reachable VIPs (when set to "reachable"
+    or by default).
 
 OVN v22.03.0 - 11 Mar 2022
 --------------------------
diff --git a/northd/northd.c b/northd/northd.c
index a56666297..f01bd2cf7 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3920,6 +3920,26 @@  static void
 build_lrouter_lb_reachable_ips(struct ovn_datapath *od,
                                const struct ovn_northd_lb *lb)
 {
+    const char *neighbor_responder_mode =
+        smap_get_def(&lb->nlb->options, "neighbor_responder", "reachable");
+
+    /* If configured to reply to neighbor requests for all VIPs force them
+     * all to be considered "reachable".
+     */
+    if (!strcmp(neighbor_responder_mode, "all")) {
+        for (size_t i = 0; i < lb->n_vips; i++) {
+            if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
+                sset_add(&od->lb_ips_v4_reachable, lb->vips[i].vip_str);
+            } else {
+                sset_add(&od->lb_ips_v6_reachable, lb->vips[i].vip_str);
+            }
+        }
+        return;
+    }
+
+    /* Otherwise, a VIP is reachable if there's at least one router
+     * subnet that includes it.
+     */
     for (size_t i = 0; i < lb->n_vips; i++) {
         if (IN6_IS_ADDR_V4MAPPED(&lb->vips[i].vip)) {
             ovs_be32 vip_ip4 = in6_addr_get_mapped_ipv4(&lb->vips[i].vip);
diff --git a/ovn-nb.xml b/ovn-nb.xml
index 9010240a8..756c2a378 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -1856,6 +1856,15 @@ 
         more information about what flows are added for IP routes, please
         see the <code>ovn-northd</code> manpage section on IP Routing.
       </column>
+
+      <column name="options" key="neighbor_responder">
+        If set to <code>all</code>, then routers on which the load balancer
+        is applied reply to ARP/neighbor discovery requests for all VIPs
+        of the load balancer.  If set to <code>reachable</code>, then routers
+        on which the load balancer is applied reply to ARP/neighbor discovery
+        requests only for VIPs that are part of a router's subnet.  The default
+        value of this option, if not specified, is <code>reachable</code>.
+      </column>
     </group>
   </table>
 
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 69ad85533..8e256de2e 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -1708,6 +1708,10 @@  ovn-nbctl lb-add lb5 "[[fe80::200:ff:fe00:101]]:8080" "[[fe02::200:ff:fe00:101]]
 ovn-nbctl lb-add lb5 "[[fe80::200:ff:fe00:102]]:8080" "[[fe02::200:ff:fe00:102]]:8080"
 ovn-nbctl lb-add lb6 "43.43.43.43:8080" "10.0.0.8:8080" udp
 ovn-nbctl lb-add lb7 "[[4343::4343]]:8080" "[[10::10]]:8080" udp
+ovn-nbctl lb-add lb8 "44.44.44.44:8080" "10.0.0.8:8080" udp
+ovn-nbctl set Load_Balancer lb8 options:neighbor_responder=all
+ovn-nbctl lb-add lb9 "[[4444::4444]]:8080" "[[10::10]]:8080" udp
+ovn-nbctl set Load_Balancer lb9 options:neighbor_responder=all
 
 ovn-nbctl lr-lb-add lr lb1
 ovn-nbctl lr-lb-add lr lb2
@@ -1716,6 +1720,8 @@  ovn-nbctl lr-lb-add lr lb4
 ovn-nbctl lr-lb-add lr lb5
 ovn-nbctl lr-lb-add lr lb6
 ovn-nbctl lr-lb-add lr lb7
+ovn-nbctl lr-lb-add lr lb8
+ovn-nbctl lr-lb-add lr lb9
 
 ovn-nbctl --wait=sb sync
 lr_key=$(fetch_column sb:datapath_binding tunnel_key external_ids:name=lr)
@@ -1723,8 +1729,8 @@  lb_as_v4="_rtr_lb_${lr_key}_ip4"
 lb_as_v6="_rtr_lb_${lr_key}_ip6"
 
 # Check generated VIP address sets (only reachable IPs).
-check_column '43.43.43.43' Address_Set addresses name=${lb_as_v4}
-check_column '4343::4343 fe80::200:ff:fe00:101 fe80::200:ff:fe00:102' Address_Set addresses name=${lb_as_v6}
+check_column '43.43.43.43 44.44.44.44' Address_Set addresses name=${lb_as_v4}
+check_column '4343::4343 4444::4444 fe80::200:ff:fe00:101 fe80::200:ff:fe00:102' Address_Set addresses name=${lb_as_v6}
 
 # Ingress router port ETH address is stored in lr_in_admission.
 AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_admission.*xreg0\[[0..47\]]" | sort], [0], [dnl