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: fix ipv4-mapped ipv6 on non 6pe #15614

Merged
merged 13 commits into from May 10, 2024

Conversation

louis-6wind
Copy link
Contributor

0325116 ("bgpd: fix 6vpe nexthop") enforced sending an IPv4-mapped IPv6 address as nexthop when the BGP session is on IPv4 and address family IPv6. This is not always correct. In some cases, sending an IPv6 global address is valid on an IPv4 session:

  • MP-BGP is used and the sending router has an IPv4 and a global IPv6 address on the interface towards the peer.
  • nexthop is set by a route-map
  • router that is sending the UPDATE is a route-reflector

IPv4-mapped IPv6 nexthop should be limited to the 6PE /6vPE cases where the prefix is reachable via an IPv4 only MPLS backbone.

Do not replace the global IPv6 address when sending UPDATE if:

  • the nexthop is set by a route-map
  • a valid global IPv6 address is set on the interface towards the peer. The 6PE router is not supposed to have a global IPv6 address set on the interface. An IPv6 link-local may be set on it.
  • the sending router is a route-reflector

Fixes: 0325116 ("bgpd: fix 6vpe nexthop")

@ton31337
Copy link
Member

Isn't this the same technically as #15611?

@louis-6wind
Copy link
Contributor Author

Isn't this the same technically as #15611?

I have just updated the commit.

In comparison with your fix, I do not send IPv4-mapped IPv6 nexhop if:

  • route-reflector
  • route-map nexthop unchanged
  • interface has IPv4 and a global IPv6. If IPv4 only, IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg) || IN6_IS_ADDR_LINKLOCAL(mod_v6nhg) is true. I assume a 6PE/6vPE has an IPv4-only interface towards the peer.

I will see what the CI is saying and will do some manual tests to confirm the patch is correct

@ton31337
Copy link
Member

Actually, we should take care about RS (route-server) also. Can you check it?

Copy link
Member

@ton31337 ton31337 left a comment

Choose a reason for hiding this comment

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

A more elegant solution would be adding a separate flag and avoiding lots of checks (as now). For instance, doing something in bpacket_attr_vec_arr_set_vec(), like BPKT_ATTRVEC_FLAGS_NO_IPV4_MAPPING or so. Thoughts?

@louis-6wind
Copy link
Contributor Author

A more elegant solution would be adding a separate flag and avoiding lots of checks (as now). For instance, doing something in bpacket_attr_vec_arr_set_vec(), like BPKT_ATTRVEC_FLAGS_NO_IPV4_MAPPING or so. Thoughts?

I will try to do that

@github-actions github-actions bot added size/XL and removed size/S labels Mar 28, 2024
@frrbot frrbot bot added the tests Topotests, make check, etc label Mar 28, 2024
@github-actions github-actions bot added size/XXL and removed size/XL labels Mar 28, 2024
bgpd/bgp_zebra.c Outdated Show resolved Hide resolved
@bbs2web
Copy link

bbs2web commented Apr 7, 2024

Please ignore my ignorance, but could we perhaps honour when 'attribute-unchanged next-hop' is set on a peer?

We have interoperability problems with different vendors in our network whereby there is no uniform way of stitching the layer 2 fabric together amongst those devices. We subsequently have layer 2 presented to FRR, where some of these could be route reflectors (these would work with the suggestion of not altering the next-hop when using route reflection or route servers, but also some that provide certain other functions. In those cases MBGP exchanges both IPv4 and IPv6 address families over a single session, the next-hop is the PE router that ingested the prefix via eBGP and the IPv6 next-hop is directly reachable from every device in the network. The key point being that the interface that talks IPv4 + MPLS does not hold the IPv6 global address, that's attached to a separate bridge interface, herewith an example:

zanjnb01-rr04# show interface brief
Interface       Status  VRF             Addresses
---------       ------  ---             ---------
br0             up      default         + 2001:db8:1:0:51:49:21:55/64    # IPv6 bridge
eth0            up      default
eth0.11         up      default         192.168.12.146/30    # Link to CR01
eth0.13         up      default         192.168.12.154/30    # Link to CR02
eth0.14         up      default         192.168.12.158/30    # Link to partner RR
eth0.15         up      default           # IPv6 over MPLS for non-l2vpn capable routers, connected to br0
lo              up      default         51.49.21.55/32
pim6reg         up      default

The other exceptions, listed above, rely on a route-maps setting the next-hop; we however wouldn't know what that should be as the ingress PE sets it's IPv6 global address as that before sending it to RRs which reflect it to other PEs.

Replacing the prefix's next hop with the route reflector's IPv4 encoded as IPv6 on iBGP route reflector sessions should IMHO be an option, to either disable or enable that behaviour, depending on the default.

@louis-6wind louis-6wind force-pushed the fix-6pe-address branch 2 times, most recently from b368471 to 678fc17 Compare April 8, 2024 14:15
@louis-6wind
Copy link
Contributor Author

louis-6wind commented Apr 9, 2024

The only CI error is about a BGP table version difference. #15711 needs to be merged before to fix that

bgpd/bgp_zebra.c Outdated Show resolved Hide resolved
bgpd/bgp_zebra.c Outdated Show resolved Hide resolved
bgpd/bgp_zebra.c Show resolved Hide resolved
This reverts commit 0325116.

It was causing an issue where a nexthop for IPv6 over an IPv4 session
was always rewritten to an IPv4-mapped IPv6 address even when a valid
IPv6 global address was existing.

Link: FRRouting#15610
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Move common checks outside of the loop.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Reduce bgp_interface_address_add indentation

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Log new IPv6 global address in bgp_interface_address_add

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
bgpd keeps on advertising IPv6 prefixes with a IPv6 link-local nexthop
after a valid IPv6 global appears.

At bgpd startup, the IPv6 global is announced by zebra after the
link-local. Only the link-local is advertised. Clearing the BGP sessions
make the global to to be announced.

Update the nexthops with the global IPv6 when available.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Add bgp_nexthop_mp_ipv4_6 topotest to test to nexhop value with
MP-BGP IPv4 and IPv6 on IPv4 peering. The test has route-reflector,
route-server, iBGP and eBGP peers.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Move common checks outside of the loop.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
When the IPv6 global is removed on an interface towards a peer, the
IPv6 nexthop global that is sent is a IPv4-mapped IPv6 address. It
should be the link-local.

At removal, replace the global by the next global address or the
link-local as last resort.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
When a peer has no IPv6 global address to send as nexthop, it sends the
IPv6 link-local instead as global. "show bgp ipv6 json" displays the
same address in global and link-local scopes.

> "nexthops": [
>   {
>     "ip": "fe80::a495:38ff:fea6:6ea3",
>     "afi": "ipv6",
>     "scope": "global",
>     "used": true
>   },
>   {
>     "ip": "fe80::a495:38ff:fea6:6ea3",
>     "afi": "ipv6",
>     "scope": "link-local"
>   }
> ]

However, "used" key is set on the global nexthop but not in link-local.
It is correct but it makes difficult to test JSON to expect the usage of
a link-local. The contrary is also correct.

Set "used" key on the link-local nexhop instead to facilitate the tests.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Test ipv6 global removal in bgp_nexthop_mp_ipv4_6

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
The code was expected that no IPv6 global address was present but the
previous commit was replacing nexthop.v6global by the link-local address
instead of un-setting it in case of removal of the IPv6 global.

Set also ipv4-mapped ipv6 address as nexthop when a link-local is found
and it is an ipv4 prefix over ipv6 nexthop.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
When a peer sends an IPv4-mapped IPv6 global and a IPv6 link-local
nexthop, prefer the link-local unless a route-map tells to use the
global.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Before the patch-set, ce1 was sending an IPv6 Link-local as global and
link-local nexthop to pe1.

Set bgp_vrf_leaking_5549_routes in accordance with the previous fixes.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
p->u.prefix6 =
pi->attr->mp_nexthop_global;
else
BGP_ATTR_NH_MP_PREFER_GLOBAL)) {
Copy link
Member

Choose a reason for hiding this comment

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

Does it work if we set attribute-unchanged next-hop?

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, waiting on @ton31337 's comments

@ton31337 ton31337 merged commit b3600d8 into FRRouting:master May 10, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants