[PATCH] filter: Add bgp_next_hop_global and bgp_next_hop_ll for independent IPv6 next hop access

KSKB SHI kusakabeshi at hotmail.com
Wed Apr 22 10:50:25 CEST 2026


Hi,
 
The current bgp_next_hop filter attribute only accesses nh[0] (the global address) of the BA_NEXT_HOP eattr.
The link-local address stored in nh[1] is completely invisible to filters.

see this image:
https://upload.cc/i1/2026/04/22/0Nj4E8.png

Worse, set bgp_next_hop allocates a new 16-byte adata, silently discarding any existing link-local next hop.
 
This makes it impossible to:
- Inspect the link-local next hop in a filter
- Modify only the global next hop while preserving the link-local
- Set a link-local next hop independently
 
This patch adds two new filter attributes, bgp_next_hop_global and bgp_next_hop_ll, which provide independent read/write access to nh[0] and nh[1] of the BGP next hop. Setting one does not affect other.
 
The existing bgp_next_hop behavior is completely unchanged.
 
Implementation:
 
Both new attributes map to the same BA_NEXT_HOP ea_code, differentiated by the bit field of struct f_dynamic_attr (which was previously unused for EAF_TYPE_IP_ADDRESS):
 
- bgp_next_hop — bit=0, original behavior (default from zero-init)
- bgp_next_hop_global — bit=1, reads/writes nh[0]
- bgp_next_hop_ll — bit=2, reads/writes nh[1]
 
GET (FI_EA_GET):
- bit=2: returns nh[1] if adata->length >= 32, otherwise IPA_NONE
- bit=0,1: returns nh[0] (same as before)
 
SET (FI_EA_SET):
- bit=0: allocates new 16-byte adata with only the assigned IP (original behavior, nh[1] is lost)
- bit=1,2: read-modify-write — reads the existing BA_NEXT_HOP from eattrs, updates only the target slot, preserves the other. If nh[1] is zero after the update, length is set to 16; otherwise 32.
 
Usage example:
 
# Read
print bgp_next_hop_global;   # 2404:f4c0:f70e:1980::202:881
print bgp_next_hop_ll;       # fe80::ff:fe20:2881
 
# Modify global only, link-local preserved
bgp_next_hop_global = 2001:db8::1;
 
# Modify link-local only, global preserved
bgp_next_hop_ll = fe80::99;
 
Files changed:
https://github.com/KusakabeShi/bird/commit/b5af9bc2eefbcc9e6f96432dd43fc6422f5f33c8
 
- proto/bgp/config.Y — new keywords and dynamic_attr rules
- filter/f-inst.c — GET/SET handling for partial next hop access
 
The patch applies against the v2.18 release branch. Feedback welcome.
 
Thanks,
KusakabeShi


More information about the Bird-users mailing list