Description
When a route reflector (RR) learns a prefix over an ipv4 labeled-unicast (SAFI 4) session and reflects it to a client activated only for ipv4 unicast (SAFI 1). The resulting UPDATE is encoded as a plain IPv4 unicast NLRI with the mandatory NEXT_HOP path attribute (type 3) missing entirely. The receiving unicast-only peer discards the update. A unicast NLRI without NEXT_HOP is malformed per RFC 4271, so the prefix never installs.
Additionally, the next-hop is present and correct in the RR's own Adj-RIB-Out (show ip bgp neighbors X advertised-routes.) It is only lost during UPDATE serialization.
The label→unicast translation already runs but has a serialization defect specific to the labeled-unicast-origin → unicast-egress path.
Cisco IOS-XE performs the same translation and sets the next hop correctly in the same topology, which is the behavior we expected.
Topology
Three iBGP routers, single AS, RR design:
TEST-LU (10.0.0.13) --- ipv4 labeled-unicast ---> RR1 (10.0.0.10) --- ipv4 unicast ---> TEST-unicast (10.0.0.12)
originates 10.0.0.13/32 route reflector unicast-only RR client
into labeled-unicast (LU client + unicast client)
- TEST-LU is an RR client activated for
ipv4 labeled-unicast only, originating its loopback 10.0.0.13/32.
- TEST-unicast is an RR client activated for
ipv4 unicast only.
- RR1 reflects between them. This is two separate neighbors, each with a single SAFI.
Loopback reachability is via OSPF; all sessions establish normally.
Version
FRRouting 10.5.2 (RR1) on Linux(6.6.128-vyos).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
configured with:
'--build=x86_64-linux-gnu' '--prefix=/usr' '--includedir=${prefix}/include' '--mandir=${prefix}/share/man' '--infodir=${prefix}/share/info' '--sysconfdir=/etc' '--localstatedir=/var' '--disable-option-checking' '--disable-silent-rules' '--libdir=${prefix}/lib/x86_64-linux-gnu' '--libexecdir=${prefix}/lib/x86_64-linux-gnu' '--disable-maintainer-mode' '--sbindir=/usr/lib/frr' '--with-vtysh-pager=/usr/bin/pager' '--libdir=/usr/lib/x86_64-linux-gnu/frr' '--with-moduledir=/usr/lib/x86_64-linux-gnu/frr/modules' '--disable-dependency-tracking' '--enable-rpki' '--enable-scripting' '--enable-pim6d' '--disable-grpc' '--disable-address-sanitizer' '--with-libpam' '--enable-doc' '--enable-doc-html' '--enable-snmp' '--enable-fpm' '--disable-protobuf' '--disable-zeromq' '--enable-ospfapi' '--enable-bgp-vnc' '--enable-multipath=256' '--enable-user=frr' '--enable-group=frr' '--enable-vty-group=frrvty' '--enable-configfile-mask=0640' '--enable-logfile-mask=0640' '--enable-pcre2posix' 'build_alias=x86_64-linux-gnu' 'PYTHON=python3'
Also with:
FRRouting 10.6.1 (RR1) on Linux(6.17.0-1016-oracle).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
configured with:
'--build=x86_64-linux-gnu' '--prefix=/usr' '--includedir=${prefix}/include' '--mandir=${prefix}/share/man' '--infodir=${prefix}/share/info' '--sysconfdir=/etc' '--localstatedir=/var' '--disable-option-checking' '--disable-silent-rules' '--libdir=${prefix}/lib/x86_64-linux-gnu' '--libexecdir=${prefix}/lib/x86_64-linux-gnu' '--disable-maintainer-mode' '--sbindir=/usr/lib/frr' '--with-vtysh-pager=/usr/bin/pager' '--libdir=/usr/lib/x86_64-linux-gnu/frr' '--with-moduledir=/usr/lib/x86_64-linux-gnu/frr/modules' '--disable-dependency-tracking' '--enable-rpki' '--disable-scripting' '--enable-pim6d' '--disable-grpc' '--disable-address-sanitizer' '--with-libpam' '--enable-doc' '--enable-doc-html' '--enable-snmp' '--enable-fpm' '--disable-protobuf' '--disable-zeromq' '--enable-ospfapi' '--enable-bgp-vnc' '--enable-multipath=256' '--enable-pcre2posix' '--enable-user=frr' '--enable-group=frr' '--enable-vty-group=frrvty' '--enable-configfile-mask=0640' '--enable-logfile-mask=0640' 'build_alias=x86_64-linux-gnu' 'PYTHON=python3'
How to reproduce
TEST-LU:
!
ip prefix-list RTR-LO seq 10 permit 10.0.0.13/32
!
router bgp 65001
no bgp ebgp-requires-policy
no bgp reject-as-sets
no bgp default ipv4-unicast
no bgp network import-check
neighbor RR peer-group
neighbor RR remote-as 65001
no neighbor RR enforce-first-as
neighbor RR update-source lo
neighbor 10.0.0.10 peer-group RR
no neighbor 10.0.0.10 enforce-first-as
!
address-family ipv4 labeled-unicast
network 10.0.0.13/32
neighbor RR activate
neighbor RR prefix-list RTR-LO out
exit-address-family
exit
RR1:
router bgp 65001
bgp log-neighbor-changes
no bgp ebgp-requires-policy
no bgp reject-as-sets
no bgp default ipv4-unicast
bgp route-reflector allow-outbound-policy
no bgp network import-check
neighbor Internet peer-group
neighbor Internet remote-as 65001
no neighbor Internet enforce-first-as
neighbor Internet update-source lo
neighbor MPLS peer-group
neighbor MPLS remote-as 65001
no neighbor MPLS enforce-first-as
neighbor MPLS update-source lo
neighbor 10.0.0.12 peer-group Internet
no neighbor 10.0.0.12 enforce-first-as
neighbor 10.0.0.13 peer-group MPLS
no neighbor 10.0.0.13 enforce-first-as
!
address-family ipv4 unicast
neighbor Internet activate
neighbor Internet route-reflector-client
exit-address-family
!
address-family ipv4 labeled-unicast
neighbor MPLS activate
neighbor MPLS route-reflector-client
exit-address-family
exit
TEST-unicast:
router bgp 65001
bgp log-neighbor-changes
no bgp ebgp-requires-policy
no bgp reject-as-sets
no bgp default ipv4-unicast
no bgp network import-check
neighbor RR peer-group
neighbor RR remote-as 65001
no neighbor RR enforce-first-as
neighbor RR update-source lo
neighbor 10.0.0.10 peer-group RR
no neighbor 10.0.0.10 enforce-first-as
!
address-family ipv4 unicast
redistribute connected
neighbor RR activate
neighbor RR soft-reconfiguration inbound
exit-address-family
exit
Expected behavior
RR1 reflects 10.0.0.13/32 to TEST-unicast as a plain IPv4 unicast route, deriving the NEXT_HOP from the inbound labeled path. The next hop was carried in the MP_REACH_NLRI of the labeled UPDATE and written into the NEXT_HOP path attribute. This is the label-removal direction described in commit 9bedbb1.
Actual behavior
RR1 has the route as a single labeled path in the shared unicast/LU table
RR1# sh ip bgp ipv4 10.0.0.13/32
BGP routing table entry for 10.0.0.13/32, version 6
Local label: 3
Paths: (1 available, best #1, table default)
Advertised to peers:
10.0.0.12 10.0.0.13
Local
10.0.0.13 (metric 1) from 10.0.0.13 (10.0.0.13)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Remote labels: 3
Last update: Mon Jul 6 10:06:04 2026
RR1's UNICAST Adj-RIB-Out for the client HAS the next-hop populated
RR1# sh ip bgp neighbors 10.0.0.12 advertised-routes
BGP table version is 7, local router ID is 10.0.0.10, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, u unsorted, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*>i 10.0.0.12/32 10.0.0.12 0 100 0 ?
*>i 10.0.0.13/32 10.0.0.13 0 100 0 ?
*>i 10.1.1.0/24 10.0.0.12 0 100 0 ?
Total number of prefixes 3
Packet Capture of UPDATE, RR1 (10.0.0.10) → TEST-unicast (10.0.0.12):
UPDATE
NLRI (legacy IPv4 unicast): 10.0.0.13/32
Path attributes present (type codes): 1 (ORIGIN), 2 (AS_PATH), 4 (MED),
5 (LOCAL_PREF), 9 (ORIGINATOR_ID), 10 (CLUSTER_LIST)
NEXT_HOP (type 3): ABSENT
MP_REACH_NLRI (type 14): ABSENT
Client rejects / never installs
TEST-unicast# sh ip bgp 10.0.0.13/32
% Network not in table
Jul 06 10:17:53 TEST-unicast bgpd[1335]: [EC 33554482] 10.0.0.10 Missing well-known attribute NEXT_HOP.
Jul 06 10:17:53 TEST-unicast bgpd[1335]: [EC 33554455] 10.0.0.10(RR1) rcvd UPDATE with errors in attr(s)!! Withdrawing route.
Additional context
No response
Checklist
Description
When a route reflector (RR) learns a prefix over an
ipv4 labeled-unicast(SAFI 4) session and reflects it to a client activated only foripv4 unicast(SAFI 1). The resulting UPDATE is encoded as a plain IPv4 unicast NLRI with the mandatory NEXT_HOP path attribute (type 3) missing entirely. The receiving unicast-only peer discards the update. A unicast NLRI without NEXT_HOP is malformed per RFC 4271, so the prefix never installs.Additionally, the next-hop is present and correct in the RR's own Adj-RIB-Out (
show ip bgp neighbors X advertised-routes.) It is only lost during UPDATE serialization.The label→unicast translation already runs but has a serialization defect specific to the labeled-unicast-origin → unicast-egress path.
Cisco IOS-XE performs the same translation and sets the next hop correctly in the same topology, which is the behavior we expected.
Topology
Three iBGP routers, single AS, RR design:
ipv4 labeled-unicastonly, originating its loopback10.0.0.13/32.ipv4 unicastonly.Loopback reachability is via OSPF; all sessions establish normally.
Version
How to reproduce
TEST-LU:
RR1:
TEST-unicast:
Expected behavior
RR1 reflects
10.0.0.13/32to TEST-unicast as a plain IPv4 unicast route, deriving the NEXT_HOP from the inbound labeled path. The next hop was carried in the MP_REACH_NLRI of the labeled UPDATE and written into the NEXT_HOP path attribute. This is the label-removal direction described in commit 9bedbb1.Actual behavior
RR1 has the route as a single labeled path in the shared unicast/LU table
RR1's UNICAST Adj-RIB-Out for the client HAS the next-hop populated
Packet Capture of UPDATE, RR1 (10.0.0.10) → TEST-unicast (10.0.0.12):
Client rejects / never installs
Additional context
No response
Checklist