Skip to content

feat: Add SR-Policy (SAFI 73) support#1393

Merged
thomas-mangin merged 1 commit into
Exa-Networks:mainfrom
manoharan-nexthop:srpolicy-safi
Jun 15, 2026
Merged

feat: Add SR-Policy (SAFI 73) support#1393
thomas-mangin merged 1 commit into
Exa-Networks:mainfrom
manoharan-nexthop:srpolicy-safi

Conversation

@manoharan-nexthop

Copy link
Copy Markdown
Contributor

Addresses #1204

SR-Policy NLRI (SAFI 73):

  • Full encode/decode for IPv4 and IPv6 SR-Policy NLRI
  • Distinguisher, color, endpoint fields per RFC 9256
  • Family negotiation via 'family { ipv4 sr-policy; ipv6 sr-policy; }'
  • SAFI.sr_policy = 73 registered in protocol/family.py

SR-Policy Tunnel Encapsulation Path Attribute (RFC 9830, RFC 9831):

  • SR Preference, Priority, Binding SID (MPLS), SRv6 Binding SID
  • SR Policy Name, SR Candidate Path Name
  • SR Segment List with all segment types per RFC 9831: Type A (1) MPLS label Type B (13) SRv6 SID [+ Endpoint Behavior] Type C (3) IPv4 Node + SR Algorithm [+ MPLS SID] Type D (4) IPv6 Node + SR Algorithm [+ MPLS SID] Type E (5) IPv4 Node + Local Interface ID [+ MPLS SID] Type F (6) IPv4 Adjacency [+ MPLS SID] Type G (7) IPv6 Link-local Adjacency + Interface IDs [+ MPLS SID] Type H (8) IPv6 Adjacency [+ MPLS SID] Type I (14) IPv6 Node + SR Algorithm [+ SRv6 SID [+ EB]] Type J (15) IPv6 Link-local Adjacency + Interface IDs + Algorithm [+ SRv6 SID [+ EB]] Type K (16) IPv6 Adjacency + SR Algorithm [+ SRv6 SID [+ EB]]

Configuration:

  • 'announce ipv4/ipv6 sr-policy' inline syntax via ParseAnnounce.register_family
  • 'static { sr-policy ... }' inline syntax via ParseStatic.register_command
  • conf-sr-policy.conf: functional test config (127.0.0.1, AS 65533)
  • conf-sr-policy-simple.conf: minimal working example
  • conf-sr-policy-static.conf: static section inline examples
  • conf-sr-policy-all-types.conf: all segment types A-K in one file

Fixes included:

  • configuration/core/parser.py: fix backslash line continuation (strip trailing \ before concatenating continued lines)
  • reactor/api/command/rib.py: fix to_json for non-prefix NLRIs (use str(nlri) fallback when .cidr attribute absent)
  • IP.create() -> IP.from_string() for main branch API

QA:

  • qa/encoding/conf-sr-policy.ci: functional encoding test (6 messages)
  • qa/decoding/bgp-sr-policy-1, bgp-sr-policy-2: decoding test fixtures

Unit tests (tests/unit/test_sr_policy.py, 105 tests):

  • SAFI value, name, implemented_safi registration
  • SRPolicyNLRI: create, pack/unpack, str, eq (IPv4 and IPv6)
  • All sub-TLVs: pack/unpack, json, str, exact-byte encode verification, and decode from hardcoded wire bytes
  • All segment types A-K: pack/unpack with and without optional fields
  • Combined: all sub-TLVs in one tunnel; multiple segment lists (ECMP)
  • RFC 9012 compliance: 1-byte length for type<128, 2-byte for type>=128

Assisted By: Claude Sonnet 4.6

@manoharan-nexthop

Copy link
Copy Markdown
Contributor Author

@thomas-mangin, Request for a review of the changes

**SR-Policy NLRI (SAFI 73)**:
- Full encode/decode for IPv4 and IPv6 SR-Policy NLRI
- Distinguisher, color, endpoint fields per RFC 9256
- Family negotiation via 'family { ipv4 sr-policy; ipv6 sr-policy; }'
- SAFI.sr_policy = 73 registered in protocol/family.py

**SR-Policy Tunnel Encapsulation Path Attribute (RFC 9830, RFC 9831)**:
- SR Preference, Priority, Binding SID (MPLS), SRv6 Binding SID
- SR Policy Name, SR Candidate Path Name
- SR Segment List with all segment types per RFC 9831:
  Type A  (1)  MPLS label
  Type B  (13) SRv6 SID [+ Endpoint Behavior]
  Type C  (3)  IPv4 Node + SR Algorithm [+ MPLS SID]
  Type D  (4)  IPv6 Node + SR Algorithm [+ MPLS SID]
  Type E  (5)  IPv4 Node + Local Interface ID [+ MPLS SID]
  Type F  (6)  IPv4 Adjacency [+ MPLS SID]
  Type G  (7)  IPv6 Link-local Adjacency + Interface IDs [+ MPLS SID]
  Type H  (8)  IPv6 Adjacency [+ MPLS SID]
  Type I  (14) IPv6 Node + SR Algorithm [+ SRv6 SID [+ EB]]
  Type J  (15) IPv6 Link-local Adjacency + Interface IDs + Algorithm [+ SRv6 SID [+ EB]]
  Type K  (16) IPv6 Adjacency + SR Algorithm [+ SRv6 SID [+ EB]]

**Configuration**:
- 'announce ipv4/ipv6 sr-policy' inline syntax via ParseAnnounce.register_family
- 'static { sr-policy ... }' inline syntax via ParseStatic.register_command
- conf-sr-policy.conf: functional test config (127.0.0.1, AS 65533)
- conf-sr-policy-simple.conf: minimal working example
- conf-sr-policy-static.conf: static section inline examples
- conf-sr-policy-all-types.conf: all segment types A-K in one file

**Fixes included**:
- configuration/core/parser.py: fix backslash line continuation
  (strip trailing \ before concatenating continued lines)
- reactor/api/command/rib.py: fix to_json for non-prefix NLRIs
  (use str(nlri) fallback when .cidr attribute absent)
- IP.create() -> IP.from_string() for main branch API

**QA**:
- qa/encoding/conf-sr-policy.ci: functional encoding test (6 messages)
- qa/decoding/bgp-sr-policy-1, bgp-sr-policy-2: decoding test fixtures

**Unit tests** (tests/unit/test_sr_policy.py, 105 tests):
- SAFI value, name, implemented_safi registration
- SRPolicyNLRI: create, pack/unpack, str, eq (IPv4 and IPv6)
- All sub-TLVs: pack/unpack, json, str, exact-byte encode verification,
  and decode from hardcoded wire bytes
- All segment types A-K: pack/unpack with and without optional fields
- Combined: all sub-TLVs in one tunnel; multiple segment lists (ECMP)
- RFC 9012 compliance: 1-byte length for type<128, 2-byte for type>=128

Assisted By: Claude Sonnet 4.6
@thomas-mangin

Copy link
Copy Markdown
Member

I am not ignoring this PR - I will get to it

@thomas-mangin thomas-mangin merged commit 362c6fe into Exa-Networks:main Jun 15, 2026
6 of 10 checks passed
@thomas-mangin

Copy link
Copy Markdown
Member

Hi @manoharan-nexthop - thank you for this work, it is now merged.

@manoharan-nexthop

Copy link
Copy Markdown
Contributor Author

Hi @manoharan-nexthop - thank you for this work, it is now merged.

Thank you @thomas-mangin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants