bgpd: fix ipv4-mapped ipv6 for ipv6 over ipv4 peer

When IPv6 prefixes are sent over an IPv4 session, the UPDATE is sent
with a link-local nexthop as global nexthop instead of a IPv4-mapped
IPv6 address. If the peer interface has no IPv6 address, routes are
not installed.

Seen with bgp_nexthop_mp_ipv4_6 topotests on step2:

> root@r2:/# vtysh -c 'show bgp ipv6 fd00💯:/64 json' | jq .
> {
>   "prefix": "fd00💯:/64",
>   "paths": [
>     {
>       "nexthops": [
>         {
>           "ip": "fe80::449a:f8ff:fe67:1f93",
>           "hostname": "r1",
>           "afi": "ipv6",
>           "scope": "global",
>           "metric": 0,
>           "accessible": true
>         },
>         {
>           "ip": "fe80::449a:f8ff:fe67:1f93",
>           "hostname": "r1",
>           "afi": "ipv6",
>           "scope": "link-local",
>           "accessible": true,
>           "used": true
>         }
>       ],
>     }
>   ]
> }

Now:

> root@r2:/# vtysh -c 'show bgp ipv6 fd00💯:/64 json' | jq .
> {
>   "prefix": "fd00💯:/64",
>   "paths": [
>       "nexthops": [
>         {
>           "ip": "::ffff:172.16.0.1",
>           "hostname": "r1",
>           "afi": "ipv6",
>           "scope": "global",
>           "metric": 0,
>           "accessible": true
>         },
>         {
>           "ip": "fe80::3842:28ff:fe90:f815",
>           "hostname": "r1",
>           "afi": "ipv6",
>           "scope": "link-local",
>           "accessible": true,
>           "used": true
>         }
>       ],
>     }
>   ]
> }

Note that the link-local is still preferred over the global address.

Fixes: 25995695f5 ("bgpd: set ipv4-mapped ipv6 for ipv4 with ipv6 nexthop")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Louis Scalbert 2024-07-22 10:57:21 +02:00
parent aa9d66e922
commit 15fb7209ee

View File

@ -526,8 +526,10 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
if (peer->nexthop.v4.s_addr != INADDR_ANY &&
(IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg) ||
(IN6_IS_ADDR_LINKLOCAL(mod_v6nhg) &&
peer->connection->su.sa.sa_family == AF_INET6 &&
paf->afi == AFI_IP))) {
((peer->connection->su.sa.sa_family == AF_INET6 &&
paf->afi == AFI_IP) ||
(peer->connection->su.sa.sa_family == AF_INET &&
paf->afi == AFI_IP6))))) {
ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, peer->nexthop.v4);
gnh_modified = 1;
}