Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd - Exclude case for remote prefix w/o link-local #16198 #16219

Merged
merged 1 commit into from
Sep 24, 2024

Conversation

cunningr
Copy link
Contributor

This is another potential fix for #16198

  • First we modify the original (from == bgp->peer_self || peer->sort == BGP_PEER_EBGP) to an && operator.
  • Then we create a second case for a remote_peer and check IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local) (e.g. link-local nh is actually included by remote peer.

In rfc2545 section 3 we have:

The link-local address shall be included in the Next Hop field if and
only if the BGP speaker shares a common subnet with the entity
identified by the global IPv6 address carried in the Network Address
of Next Hop field and the peer the route is being advertised to.
In all other cases a BGP speaker shall advertise to its peer in the
Network Address field only the global IPv6 address of the next hop
(the value of the Length of Network Address of Next Hop field shall
be set to 16).

The code in FRR assumes that a remote prefix from a device on the same segment as an eBGP peer already has it's link-local next-hop field set and sets attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL. If this field is empty our own link-local will be added later in the update formation code HOWEVER the global next-hop is left unchanged.

This proposal expands the truth of (A OR B) to "(A AND B) OR (!A AND B) OR (A AND !B)" such that we can isolate (!A AND B) and add an extra test to ensure that original next-hop actually contains a link-local.

Fixes: #16198

@cunningr
Copy link
Contributor Author

How does one include topology tests?

@cunningr cunningr force-pushed the prevent-ipv6-link-local-injection branch from ff7584d to 32f263a Compare June 13, 2024 14:28
@cunningr
Copy link
Contributor Author

Some topo test are failing and I can see why this would break some other valid scenarios. Maybe the previous proposal to put this check behind PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED is a better fix?

@cunningr
Copy link
Contributor Author

An alternative potential fix:

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 94c21e1861..1ed9133742 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2482,7 +2482,12 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
         */
        if (NEXTHOP_IS_V6) {
                attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
-               if ((CHECK_FLAG(peer->af_flags[afi][safi],
+               if (CHECK_FLAG(peer->af_flags[afi][safi],
+                               PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
+                    && !IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) {
+                               if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+                                       zlog_debug("No link-local next-hop. Ignoring other checks");
+               } else if ((CHECK_FLAG(peer->af_flags[afi][safi],
                                PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
                     && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
                    || (!reflect && !transparent

@cunningr
Copy link
Contributor Author

/cc @ton31337, @mjstapp, @riw777 - I really don't think I have the skills and knowledge to fix this and I am struggling to get resources to run tests locally. Would anyone be willing to guide me and help get a resolution for us?

@donaldsharp donaldsharp requested a review from riw777 June 18, 2024 15:20
Copy link
Member

@riw777 riw777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@cunningr
Copy link
Contributor Author

cunningr commented Jun 21, 2024

I dug into the failing test some more and I believe that this code breaks that valid scenario, where the destination_peer is EBGP and we are actually replacing the next-hop with the outgoing interface global IPv6, so adding our own link-link is valid.

I am finding it difficult to isolate our specific case which is not represented in these topology tests. In our case the prefix originator is also on the same network as the EBGP peer and so our DUT is NOT replacing the global next-hop, but that decision (not to update the global next-hop) is made in a different part of the code :-/

@riw777
Copy link
Member

riw777 commented Aug 14, 2024

I think the test needs to be modified to support this change ... :-(

@cunningr
Copy link
Contributor Author

Thanks @riw777 . Do you already ready have an idea how those test changes would look like? Happy to add them to get this PR in but I don’t have the resources to build a test environment currently.

@cunningr cunningr force-pushed the prevent-ipv6-link-local-injection branch 3 times, most recently from 945f6ef to 5cdec85 Compare August 29, 2024 17:50
@github-actions github-actions bot added size/S and removed size/XS labels Aug 29, 2024
@cunningr cunningr force-pushed the prevent-ipv6-link-local-injection branch from 5cdec85 to 34f3352 Compare August 29, 2024 17:51
@frrbot frrbot bot added the bgp label Aug 29, 2024
If we expand the truth (A || B) to "(A && B) || (A && !B) || (!A && B)"
so that we can isolate the case (!A && B), we then add the additional
check (C) to ensure that original route actually has a link-local hext-hop

Signed-off-by: Richard Cunningham <[email protected]>
@cunningr cunningr force-pushed the prevent-ipv6-link-local-injection branch from 34f3352 to 5f6a61f Compare August 29, 2024 19:59
@cunningr
Copy link
Contributor Author

@riw777 - After a rebase to pick up the latest test refactors looks like all tests are now passing. Is this now good to go?

@cunningr cunningr requested a review from riw777 August 31, 2024 06:51
@anaperic
Copy link

anaperic commented Sep 5, 2024

Hey @riw777 - as the tests are passing now, can we kindly ask you to recheck the code and give us a stamp, please? We have a blocker using FRR w/ IPv6 now for a while that is soon reaching the deadline. So your help would be more than appreciated. Thank you!

Copy link
Member

@riw777 riw777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@riw777 riw777 merged commit de43ca8 into FRRouting:master Sep 24, 2024
11 checks passed
@louis-6wind
Copy link
Contributor

This PR now removes the link-local in cases it was valid.

Why doesn't this pull-request have any topotests? I cannot reproduce the issue that was described in the initial issue.

About the change:

((from == bgp->peer_self && peer->sort == BGP_PEER_EBGP) ||
		      (from == bgp->peer_self && peer->sort != BGP_PEER_EBGP) ||
		      (from != bgp->peer_self &&
		       IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local) &&
		       peer->sort == BGP_PEER_EBGP))

is actually:

((from == bgp->peer_self) ||
		      (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local) &&
		       peer->sort == BGP_PEER_EBGP))

@cunningr @anaperic could you provide the failing configuration ? And a topotests to check the issue

@cunningr
Copy link
Contributor Author

cunningr commented Oct 7, 2024

If you use a BGPClient other than FRR (ExaBGP, BIRD) and advertise a locally originated IPv6 prefix, it will NOT add the link-local, even though the global NH is on the same network segment. Then FRR, when onward advertising the IPv6 prefix to a peer also on the same network segment, FRR will now insert it's own link-local NH.

            FRR
              |
BGPClient --- | --- Cisco

So now the "Cisco" router gets a prefix with the Global NH of the BGPClient (OK) but a link-local NH of the FRR (NOK). If the link-local is present the link-local is preferred and connectivity breaks (since our FRR is not forwarding traffic). Since the link-local is not present when advertised by the BGPClient, we expect FRR to NOT insert it's own in this case.

@louis-6wind
Copy link
Contributor

@cunningr I cannot reproduce the issue with the described use case. Please provide more info to reproduce.

I tried to do the reproduce the use case in the #17037 topotest

louis-6wind added a commit to louis-6wind/frr that referenced this pull request Oct 11, 2024
AS 65000  | AS 65001
          |
      RR  |
       |  |
R1 --- | --- R2
          |

When r1 peer is an iBGP route reflector client of rr and r2 peer is a
eBGP neighbor of rr, and all three routers shares the same network, r2
receives announcements coming from r1 with a IPv6 link-local nexthop
from rr. This is incorrect as r2 should send traffic to r1 without
involving rr.

Do not send an IPv6 link-local nexthop if the originating peer is a
route-reflector client.

Link: FRRouting#16219 (comment)
Link: FRRouting#17037 (comment)
Signed-off-by: Louis Scalbert <[email protected]>
louis-6wind added a commit to louis-6wind/frr that referenced this pull request Oct 14, 2024
AS 65000  | AS 65001
          |
      RR  |
       |  |
R1 --- | --- R2
          |

When r1 peer is an iBGP route reflector client of rr and r2 peer is a
eBGP neighbor of rr, and all three routers shares the same network, r2
receives announcements coming from r1 with a IPv6 link-local nexthop
from rr. This is incorrect as r2 should send traffic to r1 without
involving rr.

Do not send an IPv6 link-local nexthop if the originating peer is a
route-reflector client.

Link: FRRouting#16219 (comment)
Link: FRRouting#17037 (comment)
Signed-off-by: Louis Scalbert <[email protected]>
zice312963205 pushed a commit to wenwang00/frr that referenced this pull request Nov 28, 2024
AS 65000  | AS 65001
          |
      RR  |
       |  |
R1 --- | --- R2
          |

When r1 peer is an iBGP route reflector client of rr and r2 peer is a
eBGP neighbor of rr, and all three routers shares the same network, r2
receives announcements coming from r1 with a IPv6 link-local nexthop
from rr. This is incorrect as r2 should send traffic to r1 without
involving rr.

Do not send an IPv6 link-local nexthop if the originating peer is a
route-reflector client.

Link: FRRouting#16219 (comment)
Link: FRRouting#17037 (comment)
Signed-off-by: Louis Scalbert <[email protected]>
zice312963205 pushed a commit to wenwang00/frr that referenced this pull request Nov 28, 2024
AS 65000  | AS 65001
          |
      RR  |
       |  |
R1 --- | --- R2
          |

When r1 peer is an iBGP route reflector client of rr and r2 peer is a
eBGP neighbor of rr, and all three routers shares the same network, r2
receives announcements coming from r1 with a IPv6 link-local nexthop
from rr. This is incorrect as r2 should send traffic to r1 without
involving rr.

Do not send an IPv6 link-local nexthop if the originating peer is a
route-reflector client.

Link: FRRouting#16219 (comment)
Link: FRRouting#17037 (comment)
Signed-off-by: Louis Scalbert <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants