Skip to content

refactor: move mandatory attribute validation after NLRI parsing (RFC 4760)#280

Closed
digizeph wants to merge 7 commits intomainfrom
dev/rfc4760-next-hop-validation
Closed

refactor: move mandatory attribute validation after NLRI parsing (RFC 4760)#280
digizeph wants to merge 7 commits intomainfrom
dev/rfc4760-next-hop-validation

Conversation

@digizeph
Copy link
Copy Markdown
Member

@digizeph digizeph commented Apr 15, 2026

Summary

Complete refactoring of BGP mandatory attribute validation to properly handle RFC 4760 (MP-BGP) "conditionally mandatory" semantics. The validation now occurs after NLRI parsing, enabling context-aware checks that eliminate false positives without introducing false negatives.

Breaking Change

parse_attributes() signature change: The function now returns a tuple (Attributes, [bool; 256]) where the second element tracks which attribute types were seen during parsing. This enables proper mandatory attribute validation after NLRI context is known.

RFC Compliance

RFC 4271 (BGP-4)

  • ORIGIN and AS_PATH: required for any announcement
  • NEXT_HOP: required when IPv4 NLRI is present

RFC 4760 (Multiprotocol Extensions)

  • Section 3: MP_REACH_NLRI carries embedded next hop; no separate NEXT_HOP attribute needed when only MP prefixes are announced
  • Section 4: Withdrawal-only messages (MP_UNREACH_NLRI only) require no attributes

Changes

Core Changes

  • parse_attributes(): Now returns (Attributes, seen_attributes) tuple; removed inline mandatory validation
  • validate_mandatory_attributes(): New public function that performs context-aware validation after NLRI parsing
  • parse_bgp_update_message(): Calls validation after NLRI parsing with full context (has_ipv4_nlri, has_mp_reach_nlri, has_mp_unreach_nlri)

Test Updates

  • Updated all test functions to handle new tuple return
  • Renamed test_rfc7606_missing_mandatory_attribute to test_mandatory_attributes_validation with comprehensive NLRI context scenarios
  • Updated RFC 4760 tests to use validation function directly

MRT Parsers

  • Updated MRT RIB and table dump parsers to handle new tuple return (no validation performed for MRT dumps, as expected)

Validation Logic

// After NLRI parsing, we now know:
let has_announcements = has_ipv4_nlri || has_mp_reach_nlri;

if !has_announcements {
    // Withdrawals only - no mandatory attributes (RFC 4760 Section 4)
    return;
}

// ORIGIN and AS_PATH always required for announcements
if !has_origin { warn!(); }
if !has_as_path { warn!(); }

// NEXT_HOP only required for IPv4 NLRI (RFC 4271)
if has_ipv4_nlri && !has_next_hop { warn!(); }
// Note: RFC 4760 Section 3 - MP_REACH_NLRI has embedded next hop

Testing

All existing tests pass. Validation now correctly handles:

  • ✅ IPv4-only announcements: requires ORIGIN, AS_PATH, NEXT_HOP
  • ✅ MP-only announcements: requires ORIGIN, AS_PATH (no NEXT_HOP)
  • ✅ Mixed IPv4+MP announcements: requires all three
  • ✅ Withdrawals only: no mandatory attributes required

Files Changed

  • src/parser/bgp/attributes/mod.rs - Core validation logic
  • src/parser/bgp/messages.rs - UPDATE parsing with post-NLRI validation
  • src/parser/mrt/messages/table_dump_v2/rib_afi_entries.rs - Handle tuple return
  • src/parser/mrt/messages/table_dump.rs - Handle tuple return
  • CHANGELOG.md - Document breaking change and fix

Per RFC 4760 Section 3, UPDATE messages carrying no NLRI other than what's
encoded in MP_REACH_NLRI should not carry a separate NEXT_HOP attribute,
as the next hop is embedded within MP_REACH_NLRI itself.

This eliminates false positive warnings for valid MP-BGP messages.

Caveat: may produce false negatives for rare edge cases where an UPDATE
contains both regular NLRI and MP_REACH_NLRI but lacks NEXT_HOP.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.55%. Comparing base (632bbe7) to head (aa37708).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #280      +/-   ##
==========================================
+ Coverage   90.53%   90.55%   +0.01%     
==========================================
  Files          84       84              
  Lines       15835    15847      +12     
==========================================
+ Hits        14336    14350      +14     
+ Misses       1499     1497       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Complete refactoring of BGP mandatory attribute validation to handle
RFC 4760 (MP-BGP) semantics correctly:

**Breaking change:**
- parse_attributes() now returns (Attributes, [bool; 256]) tuple to track
  seen attribute types for post-parsing validation

**New validation logic:**
- ORIGIN and AS_PATH: required for any announcement (IPv4 or MP_REACH_NLRI)
- NEXT_HOP: required only when IPv4 NLRI is present (RFC 4271)
- No mandatory attributes for withdrawal-only messages (RFC 4760 Section 4)
- MP_REACH_NLRI carries embedded next hop, no separate NEXT_HOP needed

**Validation moved from parse_attributes() to parse_bgp_update_message()**
after NLRI parsing, enabling proper context-aware checks.

**Files changed:**
- src/parser/bgp/attributes/mod.rs: return tuple, add validate_mandatory_attributes()
- src/parser/bgp/messages.rs: call validation after NLRI parsing
- src/parser/mrt/messages/table_dump*.rs: handle tuple return
- CHANGELOG.md: document breaking change and bug fix
Include verbatim RFC excerpts to help readers understand the actual
validation rules and their RFC provenance:

- RFC 4271 Section 6.3: ORIGIN, AS_PATH, NEXT_HOP as well-known mandatory
- RFC 4760 Section 3: MP_REACH_NLRI requirements, NEXT_HOP omission
- RFC 4760 Section 4: MP_UNREACH_NLRI requires no other attributes
Place RFC 4271 and RFC 4760 excerpts directly next to each check
inside validate_mandatory_attributes() for better readability:

- RFC 4760 Section 4 comment at withdrawals check
- RFC 4271/4760 Section 3 comments at ORIGIN check
- RFC 4271/4760 Section 3 comments at AS_PATH check
- RFC 4271 Section 6.3 + RFC 4760 Section 3 comments at NEXT_HOP check
Update RFC comments to clarify that:
- RFC 4271 Section 6.3 is the primary source (well-known mandatory)
- RFC 4760 Section 3 clarifies this applies to MP_REACH_NLRI too
- Therefore the check applies to ANY announcement (IPv4 or MP)
Explain why ORIGIN and AS_PATH are required for MP_REACH_NLRI using
the actual RFC 4760 text: 'An UPDATE message that carries the
MP_REACH_NLRI MUST also carry the ORIGIN and the AS_PATH attributes...'

This clarifies that RFC 4271's mandatory requirement extends to
multiprotocol announcements as well.
Follow RFC 4760 Section 3 logic flow more naturally:

1. First quote RFC 4760 on when NEXT_HOP should NOT be present
   (when only MP_REACH_NLRI carries the NLRI)

2. Explain in plain English what this means for validation

3. Place RFC 4271 quote inside the check block, showing this is
   where we enforce the mandatory requirement for IPv4 NLRI

This avoids the double-negative confusion and makes the
RFC-to-code mapping clearer.
@digizeph digizeph changed the title fix: suppress NEXT_HOP warning when MP_REACH_NLRI is present (RFC 4760) refactor: move mandatory attribute validation after NLRI parsing (RFC 4760) Apr 15, 2026
@digizeph
Copy link
Copy Markdown
Member Author

prefer #281 implementation.

@digizeph digizeph closed this Apr 15, 2026
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.

1 participant