diff options
| author | Ryoga Saito <ryoga.saito@linecorp.com> | 2022-11-12 17:45:19 +0900 |
|---|---|---|
| committer | Mergify <37929162+mergify[bot]@users.noreply.github.com> | 2022-11-17 15:05:49 +0000 |
| commit | 8dff1be53318034b88a8bc1308d2f5eae985db7b (patch) | |
| tree | 3ced5dbd311353e91f044a1785294fe7c3d298fb | |
| parent | daa21266dc5f4318d3e0fa6db9f401ff9619f48a (diff) | |
bgpd: fix invalid ipv4-vpn nexthop for IPv6 peer
Given that two routers are connected each other and they have IPv6
addresses and they establish BGP peer with extended-nexthop capability
and one router tries to advertise locally-generated IPv4-VPN routes to
other router.
In this situation, bgpd on the router that tries to advertise IPv4-VPN
routes will be crashed with "invalid MP nexthop length (AFI IP6)".
This issue is happened because MP_REACH_NLRI path attribute is not
generated correctly when ipv4-vpn routes are advertised to IPv6 peer.
When IPv4 routes are leaked from VRF RIB, the nexthop of these routes
are also IPv4 address (0.0.0.0/0 or specific addresses). However,
bgp_packet_mpattr_start only covers the case of IPv6 nexthop (for IPv6
peer).
ipv4-unicast routes were not affected by this issue because the case of
IPv4 nexthop is covered in `else` block.
Signed-off-by: Ryoga Saito <ryoga.saito@linecorp.com>
(cherry picked from commit 63e7ddb509435d9e178cf51a9a288273fb91bf7e)
| -rw-r--r-- | bgpd/bgp_attr.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index b7d0958bac..d441fa886d 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -3736,13 +3736,6 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, } break; case SAFI_MPLS_VPN: { if (attr->mp_nexthop_len - == BGP_ATTR_NHLEN_IPV6_GLOBAL) { - stream_putc(s, 24); - stream_putl(s, 0); /* RD = 0, per RFC */ - stream_putl(s, 0); - stream_put(s, &attr->mp_nexthop_global, - IPV6_MAX_BYTELEN); - } else if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { stream_putc(s, 48); stream_putl(s, 0); /* RD = 0, per RFC */ @@ -3753,6 +3746,12 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, stream_putl(s, 0); stream_put(s, &attr->mp_nexthop_local, IPV6_MAX_BYTELEN); + } else { + stream_putc(s, 24); + stream_putl(s, 0); /* RD = 0, per RFC */ + stream_putl(s, 0); + stream_put(s, &attr->mp_nexthop_global, + IPV6_MAX_BYTELEN); } } break; case SAFI_ENCAP: |
