Partial

RFC 4271 - A Border Gateway Protocol 4 (BGP-4)

Every requirement this repository extracted from RFC 4271, the tests bound to it, and what a reader has verified about them. This summary is enrolled and gated by ./le rfc check.

Overview

Positive

what Ze has

Tested both ways80.6%75 of 93 binding obligations

a positive test proves Ze does what the requirement demands and a negative one proves it refuses what the requirement forbids

One polarity plus reason3.2%3 of 93 binding obligations

the requirement admits no counter-case, so one polarity plus a recorded reason is the whole proof available for it

One polarity, unexcused0.0%0 of 93 binding obligations

one direction is tested, the other is neither tested nor excused, and nothing states which

Proven by a recorded break0.0%0 of 230 tagged units

a red was observed once under a recorded procedure, and the unit, the claim and the producer it rested on still hash to what was recorded. The break is not re-run. A test pair is not a proof until one has been observed

Neutral

measures that are neither good news nor bad

Gated MUSTs100of 134 this summary declares

MUST-level requirements the gate HOLDS. A population, not a result: the shares beside it are what says how Ze stands

Out of scope7of 100 gated MUSTs

a {not-applicable} annotation says the obligation does not bind Ze. Scope, not coverage: it is in no share below

Negative

what Ze owes

No test at all16.1%15 of 93 binding obligations

no test carries the requirement id, whether or not a gap states why

The 4 shares marked as a part above are the whole of the 93 obligations that bind Ze: they add to 100%. Proven by a recorded break is a share of TAGGED UNITS, a different population, so it is not one of them.

How to read the colors

A color names what the measure MEANS, not how well Ze scores on it. Green is a good outcome at any value, red is a bad one, and neither a population nor a scope count is an outcome, so both take no color. The number under the label is what says how far Ze has got.

CardTone hereWhy that color
Gated MUSTs neutral no color: a population is a scale, and a larger one is neither good news nor bad. It is the accounting total
Out of scope neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Tested both ways ok green at every value: a test pair is the outcome this gate exists to produce, and the share under the label is what says how far Ze has got
One polarity plus reason ok green at every value: where no counter-case exists, one polarity IS the complete answer, and a recorded reason is what the gate demands beside it
One polarity, unexcused ok green at zero, RED above it: half a proof with no reason for the other half
No test at all bad green at zero, RED above it: a binding obligation nothing exercises is a claim with nothing behind it, whether or not a reason is stated
Proven by a recorded break ok green at every value: an observed break is the outcome the discrimination gate exists to produce. The denominator is TAGGED UNITS, not obligations, so this share is not one of the parts above
Audit verdicts warn RED on the first weak, wrong or unimplemented verdict, amber while a verdict is no longer current or a gated MUST is unjudged, green when every one is judged sound and current

At a glance

FieldValue
Public status Partial
Enrolment Enrolled
Requirements 134
Gated MUST-level 100
Obligations that bind Ze 93
Not applicable, so out of scope 7
Declared gaps 15
Gated with no test 0
Nightly-only evidence 0
Test tags 230
Tagged units 230
Recorded audit verdicts 0
Discrimination records 0
Summary rfc/short/rfc4271.md
Requirement shard rfc/requirements/rfc4271.md
RFC text rfc/full/rfc4271.txt

Enrolment

Enrolled: A Border Gateway Protocol 4 (BGP-4): Section 5.1.4 requires a local-configuration mechanism that removes MULTI_EXIT_DISC from a route. Ze exposes the full obligation as `modify NAME { del { med; } }` on an import chain, before Decision Process phases 1 and 2.

What the public ledger says

Status: Partial

What the ledger says is covered
  • FSM, OPEN/UPDATE/NOTIFICATION/KEEPALIVE encode and decode, message-header and hold-time validation, well-known attribute recognition and flag rules, connection collision resolution, per-peer FSM and hold timer, the complete Section 8.2.2 Event 10 action list on a hold-timer expiry, which is the Hold Timer Expired NOTIFICATION sent before the connection is dropped (RFC4271-8.2.2-1), the ConnectRetryTimer zeroed (RFC4271-8.2.2-2), the BGP resources released (RFC4271-8.2.2-3), the TCP connection dropped (RFC4271-8.2.2-4) and the state changed to Idle (RFC4271-8.2.2-5), all on the FIRST expiry with no reprieve
  • the Section 8.2.2 ManualStop (Event 2) action list, which is the Cease NOTIFICATION sent before the connection is dropped, with RFC 4486 subcode 2 Administrative Shutdown, on every peer an administrative stop of the daemon ends a connection with, from OpenSent and OpenConfirm as well as Established (RFC4271-8.2.2-18, internal/component/bgp/reactor/reactor.go Stop)
  • prefix-limit Cease, TCP MD5, the Adj-RIB-In, the RFC 4271 Section 9.1.2.2 decision process and the Loc-RIB install
  • the Section 5.1.4 propagation rule, which keeps a MULTI_EXIT_DISC received from one neighboring AS off every session toward another (RFC4271-5.1.4-1, applyFactsMED, internal/component/bgp/reactor/forward_med.go) while a metric ze or an egress filter originates still reaches the peer, and while an RS client keeps the value RFC 7947 Section 2.2.3 exempts
  • the Section 5.1.4 configured removal, which is the mechanism a speaker MUST implement (RFC4271-5.1.4-4): the del { med; } directive of a modify policy, on a policy attached to a peer's IMPORT chain drops MULTI_EXIT_DISC from the route, and it drops it before Decision Process phases 1 and 2 as RFC4271-5.1.4-2 requires, because the import chain's rewritten payload replaces the WireUpdate before the UPDATE is dispatched (ExtractMEDRemoveOps, internal/component/bgp/reactor/filter_delta.go; appendMEDRemove, internal/component/bgp/plugins/filter_modify/filter_modify.go, which refuses the directive on an export chain)
  • the Section 5 and Section 9 pass-along rule for an attribute ze does not recognize, which sets the Partial bit to 1 on an unrecognized transitive optional attribute at receipt, on the bytes ze retains and relays (RFC4271-5-3, publishBase, internal/component/bgp/reactor/session_validation.go, and SetPartialOnUnrecognizedTransitive, internal/core/bgp/attribute/partial.go), while a well-known attribute, an optional non-transitive one and an attribute ze does recognize keep the bit the sender chose, and a bit an earlier AS set is never cleared
  • the Section 5.1.3 NEXT_HOP loop rules, which are the two halves of one hazard: on egress a route is withheld from the peer whose OWN address the NEXT_HOP names, whether ze RELAYS that route or ORIGINATES it (RFC4271-5.1.3-1). A relayed route is answered on both forward rails by egressNextHopIsPeerOwn (internal/component/bgp/reactor/forward_next_hop.go), where the address arrives as the third-party next hop Section 5.1.3 case 2 permits. An originated route is answered by originatedNextHopIsPeerOwn in the same file, asked at the two writers that put such a route on the wire, writeUpdateGated and SendAnnounce (internal/component/bgp/reactor/session_write.go), rather than at each of the five rails that produce one: configured static routes and default-originate, the RIB op-queue drain, the announce batch and the RFC 9494 stale re-advertise. On both sides the withdrawals travelling in the same UPDATE still reach that peer, a third-party next hop naming anyone else is still advertised, and the route is WITHHELD rather than rewritten, because the section states a prohibition on advertising and a rewrite would invent a next hop the operator never configured
  • and on install a route naming one of ze's OWN session addresses is excluded from the decision process rather than installed (RFC4271-5.1.3-2, gatherCandidatesLocked, internal/component/bgp/plugins/rib/rib_commands.go), so a sound alternative path to the same prefix still wins
  • requirements bound per line in rfc/short/rfc4271.md.
What the ledger says remains

Fifteen MUST/SHALL-level gaps, each annotated in rfc/short/rfc4271.md.

Header error reporting: RFC4271-6.1-1, 6.1-2 and 6.1-3 (a bad marker or a sub-19 length is detected but no NOTIFICATION is sent, internal/component/bgp/message/header.go and internal/component/bgp/reactor/session_read.go; the per-type minima and the ceiling do send a conformant Bad Message Length, session_read.go) and 6.1-4 (an unknown message type is reported with subcode 0 and a text string, not Bad Message Type with the erroneous Type octet, internal/component/bgp/reactor/session_handlers.go).

OPEN error reporting: RFC4271-6.2-3 (an OPEN body that fails to decode returns from handleOpen with no NOTIFICATION and without closing the connection, internal/component/bgp/reactor/session_handlers.go; every other OPEN error rail does send Error Code 2).

Next-hop resolvability: RFC4271-3.1-2, 9.1.2-1, 9.1.2-4 and 9.1.2.1-2 (the decision process neither excludes an unresolvable NEXT_HOP nor re-runs on an IGP-cost change, and the Loc-RIB is not purged of unresolvable routes, internal/component/bgp/plugins/rib/rib_commands.go).

Adj-RIB-Out: RFC4271-9.2-2 (no forwardability gate) and 9.2-3 (a route excluded by an egress filter is skipped without withdrawing the previous advertisement, internal/component/bgp/reactor/forward_rs.go).

Timers: RFC4271-9.2.1.1-2 and 9.2.1.1-3 (no MinRouteAdvertisementIntervalTimer, internal/component/bgp/fsm/timer.go).

Connections: RFC4271-8.2.1-3 (an inbound connection reuses the peer's session rather than getting its own FSM, internal/component/bgp/reactor/reactor_connection.go). Seven further requirements are recorded {not-applicable}: ze performs no route aggregation and never disaggregates a received route.

Coverage

BucketCountWhat it counts
Positive and negative tests 75 one part of the gated population
Annotated instead of tested 25 one part of the gated population
One polarity only 0 one part of the gated population
No test and no annotation 0 one part of the gated population
Evidence that runs nightly only 0 an overlay: each of these is also counted by the part it falls in
Gated MUST-level requirements100every gated MUST falls in exactly one bucket above

Positive and negative tests (75): RFC4271-4.1-1, RFC4271-4.1-2, RFC4271-4.1-3, RFC4271-4.3-1, RFC4271-4.3-2, RFC4271-4.3-4, RFC4271-4.4-1, RFC4271-4.4-2, RFC4271-6-1, RFC4271-4.2-1, RFC4271-4.2-2, RFC4271-6.2-1, RFC4271-6.2-2, RFC4271-5-1, RFC4271-5-2, RFC4271-5-3, RFC4271-5-4, RFC4271-5-5, RFC4271-5-6, RFC4271-5.1.3-1, RFC4271-5.1.3-2, RFC4271-5.1.3-3, RFC4271-5.1.4-1, RFC4271-5.1.4-4, RFC4271-5.1.4-2, RFC4271-5.1.5-1, RFC4271-5.1.5-2, RFC4271-5.1.5-3, RFC4271-5.1.5-4, RFC4271-6.3-1, RFC4271-6.7-1, RFC4271-8.2.1-1, RFC4271-8.2.1-2, RFC4271-8.2.2-1, RFC4271-8.2.2-2, RFC4271-8.2.2-3, RFC4271-8.2.2-4, RFC4271-8.2.2-5, RFC4271-8.2.2-7, RFC4271-8.2.2-8, RFC4271-8.2.2-9, RFC4271-8.2.2-10, RFC4271-8.2.2-11, RFC4271-8.2.2-12, RFC4271-8.2.2-13, RFC4271-8.2.2-14, RFC4271-8.2.2-15, RFC4271-8.2.2-16, RFC4271-8.2.2-17, RFC4271-8.2.2-18, RFC4271-10-1, RFC4271-5.1.2-2, RFC4271-5.1.2-3, RFC4271-5.1.5-5, RFC4271-6.7-4, RFC4271-6.8-1, RFC4271-6.8-2, RFC4271-9-1, RFC4271-9-2, RFC4271-9-3, RFC4271-9.1.1-1, RFC4271-9.1.1-2, RFC4271-9.1.2-2, RFC4271-9.1.2-3, RFC4271-9.1.2.1-1, RFC4271-9.1.2.2-1, RFC4271-9.1.2.2-3, RFC4271-9.2-4, RFC4271-9.2-5, RFC4271-Security-1, RFC4271-9.2-6, RFC4271-9.2-7, RFC4271-9.2-8, RFC4271-9.2-9, RFC4271-9.2-10

Annotated instead of tested (25): RFC4271-4.3-3, RFC4271-4.3-5, RFC4271-5.1.6-1, RFC4271-6.1-1, RFC4271-6.1-2, RFC4271-6.1-3, RFC4271-6.1-4, RFC4271-6.2-3, RFC4271-8.2.1-3, RFC4271-3.1-2, RFC4271-5.1.4-3, RFC4271-5.1.7-1, RFC4271-9.1.2-1, RFC4271-9.1.2-4, RFC4271-9.1.2.1-2, RFC4271-9.1.2.2-2, RFC4271-9.2-2, RFC4271-9.2-3, RFC4271-9.2.1.1-2, RFC4271-9.2.2.2-1, RFC4271-9.2.2.2-2, RFC4271-9.2.2.2-3, RFC4271-9.2.2.2-4, RFC4271-9.2.2.2-5, RFC4271-9.2.1.1-3

Requirements

RequirementLevelSectionTests
RFC4271-4.1-1Marker field MUST be set to all ones (16 bytes of 0xFF) (§4.1)
MUST 4.1
RFC4271-4.1-2Length field MUST have the smallest value required given the rest of the message (§4.1)
MUST 4.1
RFC4271-4.1-3Message Length MUST be between 19 and 4096 octets (§4.1)
MUST 4.1
RFC4271-4.3-1For well-known attributes, the Transitive bit MUST be set to 1 (§4.3)
MUST 4.3
RFC4271-4.3-2Partial bit MUST be set to 0 for well-known and optional non-transitive attributes (§4.3)
MUST 4.3
RFC4271-4.3-3Lower-order four bits of attribute flags MUST be zero when sent (§4.3)
MUST 4.3
negativeno testno negative test

{single-polarity}: the obligation is on the sender -- the flags octet ze writes must have its low-order four bits zero -- so there is no non-conformant input to reject. The receive-side mirror of the same rule ("MUST be ignored when received") is RFC4271-4.3-4 and is proven both ways there

RFC4271-4.3-4Lower-order four bits of attribute flags MUST be ignored when received (§4.3)
MUST 4.3
RFC4271-4.4-1KEEPALIVE messages MUST NOT be sent more frequently than one per second (§4.4)
MUST NOT 4.4
RFC4271-4.4-2If the negotiated Hold Time is zero, periodic KEEPALIVE messages MUST NOT be sent (§4.4)
MUST NOT 4.4
positiveunit/verifyTestTimersKeepaliveTimer
RFC4271-6-1If no Error Subcode is specified, a zero MUST be used (§6)
MUST 6
RFC4271-4.2-1Hold Time MUST be either zero or at least three seconds (§4.2)
MUST 4.2
positiveunit/verifyTestOpenValidateHoldTime
negativeunit/verifyTestOpenValidateHoldTime
RFC4271-4.2-2BGP speaker MUST calculate Hold Timer by using the smaller of its configured Hold Time and the received Hold Time (§4.2)
MUST 4.2
RFC4271-6.2-1An implementation MUST reject Hold Time values of one or two seconds (§6.2)
MUST 6.2
positiveunit/verifyTestOpenValidateHoldTime
negativeunit/verifyTestOpenValidateHoldTime
RFC4271-6.2-2An implementation that accepts a Hold Time MUST use the negotiated value (§6.2)
MUST 6.2
RFC4271-5-1BGP implementations MUST recognize all well-known attributes (§5)
MUST 5
RFC4271-5-2Well-known mandatory attributes MUST be included in every UPDATE containing NLRI (§5)
MUST 5
RFC4271-5-3Unrecognized transitive optional attributes MUST be passed along with the Partial bit set to 1 (§5)
MUST 5
RFC4271-5-4Partial bit set to 1 by a previous AS MUST NOT be set back to 0 (§5)
MUST NOT 5
RFC4271-5-5Unrecognized non-transitive optional attributes MUST be quietly ignored (§5)
MUST 5
RFC4271-5-6Receiver of an UPDATE MUST be prepared to handle path attributes that are out of order (§5)
MUST 5
RFC4271-4.3-5A BGP speaker MUST be able to process UPDATE messages with the same prefix in both WITHDRAWN and NLRI (§4.3)
MUST 4.3

{single-polarity}: the obligation is to ACCEPT a message shape, so there is no non-conformant input to reject -- every UPDATE of this form must be processed, and a negative case would have to assert the absence of an error, which proves nothing (ai/rules/testing.md). The consequence the same paragraph asks for, treating the UPDATE as though WITHDRAWN did not contain the prefix, is RFC4271-4.3-7 and is proven by the same test

RFC4271-5.1.3-1A route originated by a BGP speaker SHALL NOT be advertised to a peer using that peer's address as NEXT_HOP (§5.1.3)
SHALL NOT 5.1.3
RFC4271-5.1.3-2A BGP speaker SHALL NOT install a route with itself as the next hop (§5.1.3)
SHALL NOT 5.1.3
RFC4271-5.1.3-3A BGP speaker MUST be able to support disabling advertisement of third-party NEXT_HOP attributes (§5.1.3)
MUST 5.1.3
RFC4271-5.1.4-1MULTI_EXIT_DISC received from a neighboring AS MUST NOT be propagated to other neighboring ASes (§5.1.4)
MUST NOT 5.1.4
negativeunit/verifyTestForwardKeepsFilterSetMED
negativeunit/verifyTestMEDPropagationAllowedTo
positivefunctional/verifymed-not-propagated-across-as.ci
negativefunctional/verifymed-locally-set-reaches-peer.ci
negativefunctional/verifymed-not-propagated-across-as.ci
positiveinterop/nightlycheckMEDAcrossAS
negativeinterop/nightlycheckMEDAcrossAS
RFC4271-5.1.4-4A BGP speaker MUST implement a mechanism (based on local configuration) that allows the MULTI_EXIT_DISC attribute to be removed from a route (§5.1.4)
MUST 5.1.4
positiveunit/verifyTestParseModifyDefsMEDRemove
negativeunit/verifyTestParseModifyDefsMEDRemove
positivefunctional/verifymed-removal-configured.ci
positiveinterop/nightlycheckMEDRemovalConfiguration
negativeinterop/nightlycheckMEDRemovalConfiguration
RFC4271-5.1.4-2MULTI_EXIT_DISC removal from routes MUST be done before the route is used in Phase 2 of the decision process (§5.1.4)
MUST 5.1.4
positivefunctional/verifymed-removal-before-decision.ci
positivefunctional/verifymed-removal-configured.ci
negativefunctional/verifymed-removal-before-decision.ci
negativefunctional/verifymed-removal-export-refused.ci
RFC4271-5.1.5-1LOCAL_PREF SHALL be included in all UPDATE messages sent to internal peers (§5.1.5)
SHALL 5.1.5
RFC4271-5.1.5-2A BGP speaker MUST NOT include LOCAL_PREF in UPDATE messages sent to external peers (§5.1.5)
MUST NOT 5.1.5
RFC4271-5.1.5-3If LOCAL_PREF is received over EBGP, it MUST be ignored (§5.1.5)
MUST 5.1.5
RFC4271-5.1.5-4The higher degree of preference (LOCAL_PREF) MUST be preferred (§5.1.5)
MUST 5.1.5
positiveunit/verifyTestBestPath_LocalPref
negativeunit/verifyTestBestPath_LocalPref
RFC4271-5.1.6-1A BGP speaker that receives a route with the ATOMIC_AGGREGATE attribute MUST NOT make any NLRI of that route more specific when advertising this route to other BGP speakers (§5.1.6)
MUST NOT 5.1.6
positiveno testno positive test
negativeno testno negative test

{not-applicable}: the obligation binds the RECEIVER/re-advertiser, and ze is one -- it stores a received ATOMIC_AGGREGATE and copies it through on readvertisement (internal/component/bgp/reactor/peer_rib_routes.go:141) -- but the prohibited act has no producer. `grep -rniE "more specific|deaggregat|de-aggregat|disaggregat" --include=*.go internal/component/bgp/ | grep -v _test` returns only substring hits inside `encodeAggregatorValue` and `attrCodeAggregator` (internal/component/bgp/reactor/filter_delta.go:294,396, internal/component/bgp/message/rfc7606.go:64,421); no code path splits a prefix. Both readvertisement encoders write the stored route's own prefix verbatim through nlri.WriteNLRI (internal/component/bgp/reactor/peer_rib_routes.go:103-104), so the advertised NLRI is byte-identical to what was received and can be neither more nor less specific. With no length-altering producer there is no behavior to exercise in either polarity

RFC4271-6.1-1All header errors MUST be indicated by sending NOTIFICATION with Error Code Message Header Error (§6.1)
MUST 6.1
positiveno testno positive test
negativeno testno negative test

{gap}: one class of header error is detected but never reported. A bad marker or a Length below 19 makes ParseHeader return a bare sentinel (internal/component/bgp/message/header.go:96-108), and the read loop turns that into an FSM event and a returned error with no NOTIFICATION sent (internal/component/bgp/reactor/session_read.go:98-102). The per-type and over-maximum length errors on the following lines do send Message Header Error (session_read.go:105-117)

RFC4271-6.1-2Marker not all ones: Error Subcode MUST be Connection Not Synchronized (§6.1)
MUST 6.1
positiveno testno positive test
negativeno testno negative test

{gap}: NotifyHeaderConnectionNotSync is declared (internal/component/bgp/message/notification.go:52) but no producer ever sends it. ParseHeader returns ErrInvalidMarker, a plain sentinel carrying no NOTIFICATION (internal/component/bgp/message/header.go:96-99), and the read loop's marker-error branch sends nothing before returning (internal/component/bgp/reactor/session_read.go:98-102)

RFC4271-6.1-3Invalid length: Error Subcode MUST be Bad Message Length; Data field MUST contain the erroneous Length field (§6.1)
MUST 6.1
positiveno testno positive test
negativeno testno negative test

{gap}: RFC 4271 §6.1 lists five length conditions and ze reports only four of them. The per-type minima and the 4096/65535 ceiling do produce a conformant Notification -- ValidateLength and ValidateLengthWithMax return a *Notification carrying NotifyHeaderBadLength and the two big-endian octets of the offending Length (internal/component/bgp/message/header.go:155-171 and :207-213), which the read loop sends before closing (internal/component/bgp/reactor/session_read.go:105-117). The first listed condition, "Length field of the message header is less than 19", does not: ParseHeader returns the bare sentinel ErrInvalidLength with no Notification and no Data (internal/component/bgp/message/header.go:106-108), and the read loop logs an FSM event and returns without writing anything (internal/component/bgp/reactor/session_read.go:98-102). The same code fact is recorded as the NOTIFICATION-absence gap on RFC4271-6.1-1. Disclosed in docs/features/rfc-status.md RFC 4271 row

RFC4271-6.1-4Invalid type: Error Subcode MUST be Bad Message Type; Data field MUST contain the erroneous Type field (§6.1)
MUST 6.1
positiveno testno positive test
negativeno testno negative test

{gap}: an unknown message type is reported with the wrong subcode and the wrong Data. handleUnknownType sends Message Header Error with subcode 0 and a human-readable text string rather than subcode 3 (Bad Message Type) with the erroneous Type octet (internal/component/bgp/reactor/session_handlers.go:20-36); NotifyHeaderBadType is declared at internal/component/bgp/message/notification.go:54 and has no producer

RFC4271-6.2-3All OPEN errors MUST be indicated by NOTIFICATION with Error Code OPEN Message Error (§6.2)
MUST 6.2
positiveno testno positive test
negativeno testno negative test

{gap}: one class of OPEN error is detected and never reported. UnpackOpen returns the bare sentinel ErrShortRead when the body is under 10 octets or when the Optional Parameters Length (standard or RFC 9072 extended) overruns the body (internal/component/bgp/message/open.go:167-168, :193-194, :199-200, :209-210), and handleOpen turns that into an FSM event and a returned error, writing no NOTIFICATION and not even closing the connection (internal/component/bgp/reactor/session_handlers.go:43-47); session_read.go:264 only propagates it. Every other OPEN error path does send Error Code 2 -- unsupported version (session_handlers.go:54-60), unacceptable Hold Time (:70-77) and a malformed capability (rejectOpenCapabilityError, :185-199) -- so the obligation holds everywhere except the decode failure. Disclosed in docs/features/rfc-status.md RFC 4271 row

RFC4271-6.3-1All UPDATE errors MUST be indicated by NOTIFICATION with Error Code UPDATE Message Error (§6.3)
MUST 6.3
RFC4271-6.7-1Cease NOTIFICATION MUST NOT be used when a fatal error does exist (§6.7)
MUST NOT 6.7
RFC4271-8.2.1-1BGP MUST maintain a separate FSM for each configured peer (§8.2.1)
MUST 8.2.1
RFC4271-8.2.1-2A BGP implementation MUST connect to and listen on TCP port 179 (§8.2.1)
MUST 8.2.1
RFC4271-8.2.1-3For each incoming connection, a state machine MUST be instantiated (§8.2.1)
MUST 8.2.1
positiveno testno positive test
negativeno testno negative test

{gap}: an incoming connection does not get its own state machine. acceptOrReject hands the accepted connection to the peer's existing session (internal/component/bgp/reactor/reactor_connection.go:117-163), and a connection queued for collision resolution is read raw by handlePendingCollision with no FSM behind it (internal/component/bgp/reactor/reactor_connection.go:196-249). An FSM is created per session, i.e. per connection attempt of a configured peer (internal/component/bgp/reactor/session.go:396), not per inbound connection

RFC4271-8.2.2-1Event 10 (HoldTimer_Expires) lists "sends a NOTIFICATION message with the error code Hold Timer Expired" before "drops the TCP connection", in OpenSent, OpenConfirm and Established alike; a peer whose connection is dropped without it is told nothing. §8 states the FSM description is conceptual but binds "the same externally visible behavior", and the NOTIFICATION is the externally visible part, so the level is MUST (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-2Event 10 (HoldTimer_Expires) lists "sets the ConnectRetryTimer to zero", in OpenSent, OpenConfirm and Established alike. A ConnectRetryTimer left running past the teardown fires against a connection that no longer exists, and the retry it schedules is externally visible as an unexpected connection attempt, so the level is MUST on the same §8 "same externally visible behavior" ground as -1 (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-3Event 10 (HoldTimer_Expires) lists "releases all BGP resources", in OpenSent, OpenConfirm and Established alike. The externally visible part is the KeepaliveTimer: a session torn down for silence that keeps its keepalive chain running writes KEEPALIVEs after the teardown, so the level is MUST (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-4Event 10 (HoldTimer_Expires) lists "drops the TCP connection", in OpenSent, OpenConfirm and Established alike. The peer must see the connection go away and not merely stop receiving; a half-open socket is externally visible, so the level is MUST (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-5Event 10 (HoldTimer_Expires) lists "changes its state to Idle", in OpenSent, OpenConfirm and Established alike. The Established->Idle transition is what deletes the routes learned over the connection, which is externally visible to every other peer, so the level is MUST (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-6Event 10 (HoldTimer_Expires) lists "(optionally) performs peer oscillation damping if the DampPeerOscillations attribute is set to TRUE" (§8.2.2)
MAY 8.2.2
positiveno testno positive test
negativeno testno negative test
RFC4271-8.2.2-7ManualStart (Event 1) in Idle lists "sets ConnectRetryCounter to zero", once for the Connect branch (Events 1 and 3) and again, in the same words, for the passive Active branch (Events 4 and 5). §8 makes ConnectRetryCounter a mandatory session attribute and defines it as "the number of times a BGP peer has tried to establish a peer session", so an operator start that left a stale retry history behind would misreport that number; the level is MUST (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-8ManualStop (Event 2) lists "sets the ConnectRetryCounter to zero", in Connect, Active, OpenSent, OpenConfirm and Established alike. Same §8 mandatory-attribute ground as -7: the operator stopping the peer ends the run of attempts the counter was counting (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-9HoldTimer_Expires (Event 10) lists "increments the ConnectRetryCounter", in OpenSent, OpenConfirm and Established alike (OpenSent omits the words "by 1" that the other two carry; the counter is an integer count, so the step is one). A session lost to silence is an attempt that failed, and §8 makes the count mandatory (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-10BGPHeaderErr (Event 21) and BGPOpenMsgErr (Event 22) list "increments the ConnectRetryCounter by 1" in Connect, Active, OpenSent and OpenConfirm, and in Established through "In response to any other event (Events 9, 12-13, 20-22)", which names both (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-11NotifMsg (Event 25) leads to "increments the ConnectRetryCounter by 1" in every state that can see it: explicitly in OpenConfirm ("a TcpConnectionFails event (Event 18) [...] or a NOTIFICATION message (Event 25)") and Established ("a NOTIFICATION message (Event 24 or Event 25)"), and through the "any other event" list that names Event 25 in Connect, Active and OpenSent (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-12NotifMsgVerErr (Event 24) increments the ConnectRetryCounter in Connect, Active and Established, and MUST NOT in OpenSent or OpenConfirm. In Connect and Active the clause sits in the DelayOpenTimer-is-not-running branch, which is the only branch a speaker without a DelayOpenTimer can take, and Established groups Event 24 with Events 25 and 18; in OpenSent and OpenConfirm the Event 24 action list is four items long and has no ConnectRetryCounter line at all (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-13TcpConnectionFails (Event 18) increments the ConnectRetryCounter in Active, OpenConfirm and Established, and MUST NOT in Connect or OpenSent. Connect's Event 18 has two branches and neither carries the clause, and OpenSent's Event 18 leaves for Active rather than tearing the peering down (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-14UpdateMsgErr (Event 28) in Established lists "increments the ConnectRetryCounter by 1". An UPDATE error ends the session, which makes it a failed attempt by the §8 definition of the attribute (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-15The "any other event" action list lists "increments the ConnectRetryCounter by 1" ("by one" in Active) in all five non-Idle states: Connect and Active (Events 8, 10-11, 13, 19, 23, 25-28), OpenSent (Events 9, 11-13, 20, 25-28), OpenConfirm (Events 9, 12-13, 20, 27-28) and Established (Events 9, 12-13, 20-22). Idle is excluded on purpose: its own "any other event" clause says the event "does not cause change in the state of the local system" and lists no actions (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-16AutomaticStop (Event 8) lists "increments the ConnectRetryCounter by 1" in OpenSent, OpenConfirm and Established, and Connect and Active name Event 8 in their "any other events" list, which carries the same line. Its action list differs from ManualStop's by that one line, and the difference is the point: §8 defines the attribute as "the number of times a BGP peer has tried to establish a peer session", so a stop the local system chose records a failed attempt where an operator stop ends the count (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-17OpenCollisionDump (Event 23) lists "increments the ConnectRetryCounter by 1" in OpenSent, OpenConfirm and Established, and Connect and Active name Event 23 in their "any other events" list, which carries the same line. A connection closed by §6.8 collision resolution is an attempt that did not become a session (§8.2.2)
MUST 8.2.2
RFC4271-8.2.2-18ManualStop (Event 2) lists the Cease NOTIFICATION FIRST in its action list, in every state that has a connection to send it on: OpenSent writes "sends the NOTIFICATION with a Cease", OpenConfirm and Established write "sends the NOTIFICATION message with a Cease", and all three list it before "drops the TCP connection". The level is MUST on the same §8 ground as -1: the FSM description is conceptual, but an implementation "MUST support the described functionality and exhibit the same externally visible behavior", and the NOTIFICATION is the externally visible part -- it is the ONLY signal that says the operator stopped this speaker rather than the network dropping it. §6.7's MAY governs a different act, a speaker CHOOSING to Cease "at any given time" of its own accord; once the operator has issued Event 2 the action list is what the FSM owes. Connect and Active list no Cease clause and are excluded: neither state holds a BGP connection (§8.2.2)
MUST 8.2.2
RFC4271-10-1An implementation MUST allow the HoldTimer to be configurable on a per-peer basis (§10)
MUST 10
RFC4271-3-1A BGP speaker SHOULD retain current routes from all peers or use Route Refresh (RFC 2918) (§3)
SHOULD 3
positiveno testno positive test
negativeno testno negative test
RFC4271-5-7Path attributes SHOULD be ordered in ascending order of attribute type (§5)
SHOULD 5
RFC4271-5.1.6-2A BGP speaker SHOULD include ATOMIC_AGGREGATE when an aggregate excludes AS numbers (§5.1.6)
SHOULD 5.1.6
positiveno testno positive test
negativeno testno negative test
RFC4271-5.1.6-3A BGP speaker SHOULD NOT remove ATOMIC_AGGREGATE when propagating the route (§5.1.6)
SHOULD NOT 5.1.6
positiveno testno positive test
negativeno testno negative test
RFC4271-6.3-2Semantically incorrect NEXT_HOP SHOULD be logged and the route SHOULD be ignored (§6.3)
SHOULD 6.3
negativeno testno negative test
RFC4271-6.3-3For semantically incorrect NEXT_HOP, a NOTIFICATION SHOULD NOT be sent (§6.3)
SHOULD NOT 6.3
positiveno testno positive test
negativeno testno negative test
RFC4271-9.2-1A BGP speaker SHOULD NOT advertise a feasible route if it would produce a duplicate UPDATE (§9.2)
SHOULD NOT 9.2
positiveno testno positive test
negativeno testno negative test
RFC4271-9.2.1.1-1MinRouteAdvertisementIntervalTimer SHOULD NOT apply to routes sent to internal peers (§9.2.1.1)
SHOULD NOT 9.2.1.1
positiveno testno positive test
negativeno testno negative test
RFC4271-10-2Jitter SHOULD be applied to timers (§10)
SHOULD 10
positiveno testno positive test
negativeno testno negative test
RFC4271-5.1.1-1ORIGIN value SHOULD NOT be changed by any other speaker (§5.1.1)
SHOULD 5.1.1
positiveno testno positive test
negativeno testno negative test
RFC4271-4.2-3A BGP speaker MAY reject connections on the basis of the Hold Time (§4.2)
MAY 4.2
positiveno testno positive test
negativeno testno negative test
RFC4271-3.1-1A BGP speaker MAY add to or modify path attributes before advertising (§3.1)
MAY 3.1
positiveno testno positive test
negativeno testno negative test
RFC4271-5.1.2-1A BGP speaker MAY include/prepend more than one instance of its own AS number in AS_PATH (§5.1.2)
MAY 5.1.2
positiveno testno positive test
negativeno testno negative test
RFC4271-6.7-2A BGP speaker MAY support imposing a locally-configured upper bound on address prefixes (§6.7)
MAY 6.7
positiveno testno positive test
negativeno testno negative test
RFC4271-10-3An implementation MAY allow other timers to be configurable (§10)
MAY 10
positiveno testno positive test
negativeno testno negative test
RFC4271-6.2-4An implementation MAY reject any proposed Hold Time (§6.2)
MAY 6.2
positiveno testno positive test
negativeno testno negative test
RFC4271-6.7-3The speaker MAY also log a Cease locally (§6.7)
MAY 6.7
positiveno testno positive test
negativeno testno negative test
RFC4271-3.1-2Next hop for routes in Loc-RIB MUST be resolvable via the local BGP speaker's Routing Table (§3.1)
MUST 3.1
positiveno testno positive test
negativeno testno negative test

{gap}: the BGP Loc-RIB install performs no reachability check on the route's next hop. mirrorToLocRIB inserts the winning path with whatever next-hop address the attribute carried (internal/component/bgp/plugins/rib/rib_bestchange.go:797-830), and the candidate gather step filters only on SRv6 ineligibility (internal/component/bgp/plugins/rib/rib_commands.go:1039-1057). Resolvability is enforced downstream at FIB-install time, which removes the route from the routing table but leaves it in the Loc-RIB

RFC4271-5.1.2-2When advertising a route to an internal peer, the speaker SHALL NOT modify the AS_PATH attribute (§5.1.2)
SHALL NOT 5.1.2
RFC4271-5.1.2-3When advertising a route to an external peer, the speaker prepends its own AS number to the leading AS_SEQUENCE of AS_PATH (creating one when the path is empty or led by an AS_SET) (§5.1.2)
SHALL 5.1.2
RFC4271-5.1.4-3If altering MULTI_EXIT_DISC received over EBGP, alteration MUST be done prior to decision process phases 1 and 2 (§5.1.4)
MUST 5.1.4
negativeno testno negative test

{single-polarity}: the requirement constrains only the ORDER of an alteration that a speaker chooses to make, so there is no non-conformant input a receiver could reject. ze's only place to alter a received MULTI_EXIT_DISC is the ingress filter chain, whose rewritten payload replaces the WireUpdate before the UPDATE is dispatched to the RIB plugin that runs phases 1 and 2 (internal/component/bgp/reactor/reactor_notify.go:427-466)

RFC4271-5.1.5-5A BGP speaker SHALL calculate the degree of preference for each external route based on locally-configured policy (§5.1.5)
SHALL 5.1.5
RFC4271-5.1.7-1A BGP speaker that performs aggregation and adds AGGREGATOR SHALL include its own AS number and IP address (§5.1.7)
SHALL 5.1.7
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze never performs aggregation, so it never adds an AGGREGATOR of its own. The same grep as RFC4271-5.1.6-1 finds no aggregation producer; AGGREGATOR is only interned from the wire (internal/component/bgp/plugins/rib/storage/attrparse.go:96-102), replayed on readvertise (internal/component/bgp/plugins/rib/storage/familyrib.go:817-819) or emitted from operator configuration (internal/component/bgp/message/update_build_grouped.go:141-148)

RFC4271-6.7-4When terminating due to prefix limit, speaker MUST send NOTIFICATION with Error Code Cease (§6.7)
MUST 6.7
positiveunit/verifyTestPrefixExceedTeardown
negativeunit/verifyTestPrefixExceedDrop
RFC4271-6.8-1In the event of connection collision, one of the connections MUST be closed (§6.8)
MUST 6.8
RFC4271-6.8-2Upon receipt of an OPEN message, the local system MUST examine all connections in OpenConfirm state for collision (§6.8)
MUST 6.8
RFC4271-9-1Withdrawn routes SHALL be removed from the Adj-RIB-In and the Decision Process SHALL be run (§9)
SHALL 9
RFC4271-9-2A new route with identical NLRI to an existing route SHALL replace the older route in Adj-RIB-In (§9)
SHALL 9
RFC4271-9-3Once the Adj-RIB-In is updated, the speaker SHALL run its Decision Process (§9)
SHALL 9
positiveunit/verifyTestRIBBestChangeWithdraw
RFC4271-9.1.1-1The degree of preference function SHALL NOT use the existence or attributes of other routes as inputs (§9.1.1)
SHALL NOT 9.1.1
RFC4271-9.1.1-2For external routes, the computed degree of preference MUST be used as the LOCAL_PREF value in IBGP readvertisement (§9.1.1)
MUST 9.1.1
RFC4271-9.1.2-1If NEXT_HOP is not resolvable, the BGP route MUST be excluded from Phase 2 decision function (§9.1.2)
MUST 9.1.2
positiveno testno positive test
negativeno testno negative test

{gap}: an unresolvable NEXT_HOP does not exclude the route from Phase 2. gatherCandidatesLocked skips only SRv6-ineligible entries (internal/component/bgp/plugins/rib/rib_commands.go:1039-1057), and extractCandidate uses the next hop solely to look up an IGP cost (internal/component/bgp/plugins/rib/rib_commands.go:1123-1131), so an unreachable next hop yields a cost of zero and the route competes normally

RFC4271-9.1.2-2The local speaker SHALL install the best route in the Loc-RIB (§9.1.2)
SHALL 9.1.2
positiveunit/verifyTestLocRIBMirror
negativeunit/verifyTestRIBBestChangeWithdraw
RFC4271-9.1.2-3The local speaker MUST determine the immediate next-hop address from the NEXT_HOP attribute (§9.1.2)
MUST 9.1.2
RFC4271-9.1.2-4If immediate next-hop or IGP cost to NEXT_HOP changes, Phase 2 Route Selection MUST be performed again (§9.1.2)
MUST 9.1.2
positiveno testno positive test
negativeno testno negative test

{gap}: nothing re-runs Phase 2 when the immediate next-hop or the IGP cost to the NEXT_HOP changes. The only entry points to checkBestPathChange are the UPDATE ingest path and the peer-state paths (internal/component/bgp/plugins/rib/rib_structured.go:271-286), and the IGP cost function is a passive lookup registered once with no invalidation callback (internal/component/bgp/plugins/rib/bestpath.go:30-43)

RFC4271-9.1.2.1-1When installing a BGP route in the Routing Table, implementations MUST recalculate and take into account next-hops (§9.1.2.1)
MUST 9.1.2.1
RFC4271-9.1.2.1-2Unresolvable routes SHALL be removed from the Loc-RIB and the routing table (§9.1.2.1)
SHALL 9.1.2.1
positiveno testno positive test
negativeno testno negative test

{gap}: an unresolvable route is not removed from the Loc-RIB. The only Loc-RIB removal in the BGP plugin is the no-candidate-remains branch of checkBestPathChange (internal/component/bgp/plugins/rib/rib_bestchange.go:766-782), which is driven by the Adj-RIB-In losing its last path and never by next-hop resolvability; nothing in the plugin consults a resolver

RFC4271-9.1.2.2-1The tie-breaking criteria MUST be applied in the order specified (§9.1.2.2)
MUST 9.1.2.2
RFC4271-9.1.2.2-2If MULTI_EXIT_DISC is removed before IBGP readvertisement, the optional MED comparison MUST be performed only among EBGP-learned routes (§9.1.2.2)
MUST 9.1.2.2
positiveno testno positive test
negativeno testno negative test

{gap}: the common egress guard is implemented, but normal BGP selected-route readvertisement has no runnable producer and no discriminating proof. `bgp-rib` records selected Loc-RIB state (internal/component/bgp/plugins/rib/rib_bestchange.go:738-790), route-server and route-reflector plugins forward cached UPDATEs instead (internal/component/bgp/plugins/rs/server.go:433-434 and internal/component/bgp/plugins/rr/rr.go:188-195), and BGP-to-BGP redistribution is rejected as same-protocol redistribution (internal/core/redistevents/registry.go:144-146)

RFC4271-9.1.2.2-3For IBGP-learned routes, MULTI_EXIT_DISC MUST be used in comparisons that reach the MED step (§9.1.2.2)
MUST 9.1.2.2
RFC4271-9.2-2A route SHALL NOT be installed in Adj-RIB-Out unless its destination and NEXT_HOP may be forwarded by the Routing Table (§9.2)
SHALL NOT 9.2
positiveno testno positive test
negativeno testno negative test

{gap}: nothing gates Adj-RIB-Out installation on the destination and NEXT_HOP being forwardable. QueueAnnounce records the route unconditionally (internal/component/bgp/rib/outgoing.go:65-101), and the forwarding rails decide only on filters, family negotiation and the route-reflection rules (internal/component/bgp/reactor/forward_rs.go:295-333)

RFC4271-9.2-3If a route in Loc-RIB is excluded from a particular Adj-RIB-Out, the previously advertised route MUST be withdrawn (§9.2)
MUST 9.2
positiveno testno positive test
negativeno testno negative test

{gap}: a route excluded from a peer's Adj-RIB-Out by an egress filter is skipped silently, leaving the peer's previous advertisement in place instead of withdrawing it. Both forwarding rails `continue` on suppression with no withdrawal built (internal/component/bgp/reactor/forward_rs.go:320-333 and internal/component/bgp/reactor/reactor_api_forward.go:496-506); the one announce-to-withdraw conversion is LLGR-specific and filter-requested, not exclusion-driven (internal/component/bgp/reactor/reactor_api_forward.go:588-601)

RFC4271-9.2-4The Decision Process MUST consider both overlapping routes based on acceptance policy (§9.2)
MUST 9.2
RFC4271-9.2-5If both less and more specific overlapping routes are accepted, the Decision Process MUST install both or an aggregate in Loc-RIB (§9.2)
MUST 9.2
RFC4271-9.2.1.1-2Two UPDATE messages advertising to common destinations MUST be separated by at least MinRouteAdvertisementIntervalTimer (§9.2.1.1)
MUST 9.2.1.1
positiveno testno positive test
negativeno testno negative test

{gap}: ze has no MinRouteAdvertisementIntervalTimer, so successive UPDATEs to a common set of destinations are not spaced. The timer set implements only ConnectRetry, Hold and Keepalive and records the omission in its own doc comment (internal/component/bgp/fsm/timer.go:34-42, "MinRouteAdvertisementIntervalTimer (Section 9.2.1.1) - not implemented here"); `grep -rniE 'minroute|mrai' --include=*.go internal/` finds no producer

RFC4271-9.2.2.2-1Routes with different MULTI_EXIT_DISC attributes SHALL NOT be aggregated (§9.2.2.2)
SHALL NOT 9.2.2.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze never aggregates routes, so no producer can aggregate two routes with different MULTI_EXIT_DISC values. `grep -rniE 'aggregate-address|AggregateRoute|route aggregation' --include=*.go .` returns no hit outside rfc/ and plan/, and no code path synthesizes an aggregate route from more-specifics

RFC4271-9.2.2.2-2If any aggregated route has ORIGIN INCOMPLETE, the aggregate MUST have ORIGIN INCOMPLETE; else if any has EGP, the aggregate MUST have ORIGIN EGP (§9.2.2.2)
MUST 9.2.2.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze never aggregates routes, so no producer computes an aggregate ORIGIN. ORIGIN is only parsed (internal/core/bgp/attribute/origin.go:146-160), interned (internal/component/bgp/plugins/rib/storage/attrparse.go) and re-emitted verbatim (internal/component/bgp/plugins/rib/storage/familyrib.go:799-801); the same aggregation grep returns nothing

RFC4271-9.2.2.2-3When aggregating routes with different NEXT_HOP, the aggregated NEXT_HOP SHALL identify an interface on the aggregating speaker (§9.2.2.2)
SHALL 9.2.2.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze never aggregates routes, so no producer chooses an aggregated NEXT_HOP. The only next-hop selection is per-route egress policy (internal/component/bgp/reactor/peer_forward_facts.go:153-193); the same aggregation grep returns nothing

RFC4271-9.2.2.2-4If at least one aggregated route has ATOMIC_AGGREGATE, the aggregate SHALL have it as well (§9.2.2.2)
SHALL 9.2.2.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze never aggregates routes, so no producer decides whether an aggregate carries ATOMIC_AGGREGATE. The attribute is only decoded, stored and replayed (internal/core/bgp/attribute/simple.go:175-195, internal/component/bgp/plugins/rib/storage/familyrib.go:815-817); the same aggregation grep returns nothing

RFC4271-9.2.2.2-5AGGREGATOR attributes from aggregated routes MUST NOT be included in the aggregated route (§9.2.2.2)
MUST NOT 9.2.2.2
positiveno testno positive test
negativeno testno negative test

{not-applicable}: ze never aggregates routes, so no producer builds an aggregated route from which a contributing AGGREGATOR would have to be excluded. AGGREGATOR is only interned from the wire or emitted from operator configuration (internal/component/bgp/plugins/rib/storage/attrparse.go:96-102, internal/component/bgp/message/update_build_grouped.go:141-148); the same aggregation grep returns nothing

RFC4271-Security-1A BGP implementation MUST support TCP MD5 authentication (RFC 2385) (§Security, Appendix E)
MUST Security
positiveunit/verifyTestMD5PeersForListener
negativeunit/verifyTestMD5PeersForListener
RFC4271-9.2.1.1-3The last route selected while awaiting MinRouteAdvertisementIntervalTimer SHALL be advertised at expiry (§9.2.1.1)
SHALL 9.2.1.1
positiveno testno positive test
negativeno testno negative test

{gap}: with no MinRouteAdvertisementIntervalTimer there is no expiry at which a last-selected route could be advertised. The timer is absent by design note (internal/component/bgp/fsm/timer.go:39) and no producer buffers a pending best-route advertisement against such a timer; best-path changes are published as they are computed (internal/component/bgp/plugins/rib/rib_bestchange.go:832-880)

RFC4271-9.2-6A BGP speaker SHALL NOT redistribute routing information from an internal peer to other internal peers (unless route reflector) (§9.2)
SHALL NOT 9.2
RFC4271-9.2-7Newly unfeasible routes for which there is no replacement SHALL be advertised via UPDATE (§9.2)
SHALL 9.2
positiveunit/verifyTestRIBBestChangeWithdraw
RFC4271-9.2-8Any routes in the Loc-RIB marked as unfeasible SHALL be removed (§9.2)
SHALL 9.2
positiveunit/verifyTestLocRIBMirror
RFC4271-9.2-9Changes to reachable destinations within the speaker's own AS SHALL be advertised in an UPDATE (§9.2)
SHALL 9.2
RFC4271-9.2-10If a single route does not fit in an UPDATE message, the speaker MUST NOT advertise it and MAY log an error (§9.2)
MUST 9.2
RFC4271-Appendix-1Each BGP message SHOULD be transmitted with the TCP PUSH flag set (§Appendix E)
SHOULD Appendix
positiveno testno positive test
negativeno testno negative test
RFC4271-Appendix-2The TCP connection used by BGP SHOULD be opened with DSCP bits 0-2 set to 110 (§Appendix E)
SHOULD Appendix
positiveno testno positive test
negativeno testno negative test
RFC4271-9.3-1An AS SHOULD avoid using unstable routes (§9.3)
SHOULD 9.3
positiveno testno positive test
negativeno testno negative test
RFC4271-9.3-2An AS SHOULD NOT make rapid, spontaneous changes to its choice of route (§9.3)
SHOULD NOT 9.3
positiveno testno positive test
negativeno testno negative test
RFC4271-9.4-1Distribution of non-BGP acquired routes within an AS via BGP SHOULD be controlled via configuration (§9.4)
SHOULD 9.4
positiveno testno positive test
negativeno testno negative test
RFC4271-9.1.2-5If the AS_PATH attribute of a BGP route contains an AS loop, the BGP route should be excluded from the Phase 2 decision function (§9.1.2). Detection scans the full AS path and checks that the local autonomous system number does not appear in it. RFC 4271 writes this keyword in lower case, so the level is a recommendation and not a capitalized RFC 2119 SHOULD. The same paragraph places a speaker configured to accept routes with its own autonomous system number in the AS path outside the scope of the document. That out-of-scope case is what the allow-own-as setting selects, so a non-zero allow-own-as is not a deviation from this line.
SHOULD 9.1.2
positiveunit/verifyTestDetectASLoop_NotPresent
negativeunit/verifyTestDetectASLoop
negativeunit/verifyTestDetectASLoop_ASSet
negativefunctional/verifyloop-as.ci
RFC4271-9.1.2.1-3Unresolvable routes SHOULD be kept in the Adj-RIB-In for future re-evaluation (§9.1.2.1)
SHOULD 9.1.2.1
positiveno testno positive test
negativeno testno negative test
RFC4271-9.1.2.1-4If only an aggregate is available, only the longest matching route SHOULD be announced (§9.1.2.1)
SHOULD 9.1.2.1
positiveno testno positive test
negativeno testno negative test
RFC4271-9.1.2.1-5Connection establishment failure SHOULD be logged (§9.1.2.1)
SHOULD 9.1.2.1
positiveno testno positive test
negativeno testno negative test
RFC4271-8.2.1.4-1Connection that is closed in collision SHOULD be disposed (§8.2.1.4)
SHOULD 8.2.1.4
positiveno testno positive test
negativeno testno negative test
RFC4271-4.3-6An UPDATE message SHOULD NOT include the same address prefix in both WITHDRAWN and NLRI (§4.3)
SHOULD 4.3
positiveno testno positive test
negativeno testno negative test
RFC4271-4.3-7An UPDATE containing the same prefix in WITHDRAWN and NLRI SHOULD be treated as if the prefix is not in WITHDRAWN (§4.3)
SHOULD 4.3
RFC4271-5.1.7-2AGGREGATOR IP address SHOULD be the same as the BGP Identifier of the speaker (§5.1.7)
SHOULD 5.1.7
positiveno testno positive test
negativeno testno negative test
RFC4271-9.2-11A BGP speaker that chooses to aggregate SHOULD either include all ASes in an AS_SET or add ATOMIC_AGGREGATE (§9.2)
SHOULD 9.2
positiveno testno positive test
negativeno testno negative test
RFC4271-9.2-12Routes SHOULD NOT be de-aggregated (§9.2)
SHOULD NOT 9.2
positiveno testno positive test
negativeno testno negative test
RFC4271-9.2.2.2-6If aggregated AS_PATH begins with AS_SET, the originator SHOULD NOT advertise MULTI_EXIT_DISC (§9.2.2.2)
SHOULD NOT 9.2.2.2
positiveno testno positive test
negativeno testno negative test

Gaps and untested MUSTs

RequirementStateReason
RFC4271-5.1.6-1 A BGP speaker that receives a route with the ATOMIC_AGGREGATE attribute MUST NOT make any NLRI of that route more specific when advertising this route to other BGP speakers (§5.1.6) no test no test carries this requirement id; annotated {not-applicable}: the obligation binds the RECEIVER/re-advertiser, and ze is one -- it stores a received ATOMIC_AGGREGATE and copies it through on readvertisement (internal/component/bgp/reactor/peer_rib_routes.go:141) -- but the prohibited act has no producer. `grep -rniE "more specific|deaggregat|de-aggregat|disaggregat" --include=*.go internal/component/bgp/ | grep -v _test` returns only substring hits inside `encodeAggregatorValue` and `attrCodeAggregator` (internal/component/bgp/reactor/filter_delta.go:294,396, internal/component/bgp/message/rfc7606.go:64,421); no code path splits a prefix. Both readvertisement encoders write the stored route's own prefix verbatim through nlri.WriteNLRI (internal/component/bgp/reactor/peer_rib_routes.go:103-104), so the advertised NLRI is byte-identical to what was received and can be neither more nor less specific. With no length-altering producer there is no behavior to exercise in either polarity
RFC4271-6.1-1 All header errors MUST be indicated by sending NOTIFICATION with Error Code Message Header Error (§6.1) {gap}, no test one class of header error is detected but never reported. A bad marker or a Length below 19 makes ParseHeader return a bare sentinel (internal/component/bgp/message/header.go:96-108), and the read loop turns that into an FSM event and a returned error with no NOTIFICATION sent (internal/component/bgp/reactor/session_read.go:98-102). The per-type and over-maximum length errors on the following lines do send Message Header Error (session_read.go:105-117)
RFC4271-6.1-2 Marker not all ones: Error Subcode MUST be Connection Not Synchronized (§6.1) {gap}, no test NotifyHeaderConnectionNotSync is declared (internal/component/bgp/message/notification.go:52) but no producer ever sends it. ParseHeader returns ErrInvalidMarker, a plain sentinel carrying no NOTIFICATION (internal/component/bgp/message/header.go:96-99), and the read loop's marker-error branch sends nothing before returning (internal/component/bgp/reactor/session_read.go:98-102)
RFC4271-6.1-3 Invalid length: Error Subcode MUST be Bad Message Length; Data field MUST contain the erroneous Length field (§6.1) {gap}, no test RFC 4271 §6.1 lists five length conditions and ze reports only four of them. The per-type minima and the 4096/65535 ceiling do produce a conformant Notification -- ValidateLength and ValidateLengthWithMax return a *Notification carrying NotifyHeaderBadLength and the two big-endian octets of the offending Length (internal/component/bgp/message/header.go:155-171 and :207-213), which the read loop sends before closing (internal/component/bgp/reactor/session_read.go:105-117). The first listed condition, "Length field of the message header is less than 19", does not: ParseHeader returns the bare sentinel ErrInvalidLength with no Notification and no Data (internal/component/bgp/message/header.go:106-108), and the read loop logs an FSM event and returns without writing anything (internal/component/bgp/reactor/session_read.go:98-102). The same code fact is recorded as the NOTIFICATION-absence gap on RFC4271-6.1-1. Disclosed in docs/features/rfc-status.md RFC 4271 row
RFC4271-6.1-4 Invalid type: Error Subcode MUST be Bad Message Type; Data field MUST contain the erroneous Type field (§6.1) {gap}, no test an unknown message type is reported with the wrong subcode and the wrong Data. handleUnknownType sends Message Header Error with subcode 0 and a human-readable text string rather than subcode 3 (Bad Message Type) with the erroneous Type octet (internal/component/bgp/reactor/session_handlers.go:20-36); NotifyHeaderBadType is declared at internal/component/bgp/message/notification.go:54 and has no producer
RFC4271-6.2-3 All OPEN errors MUST be indicated by NOTIFICATION with Error Code OPEN Message Error (§6.2) {gap}, no test one class of OPEN error is detected and never reported. UnpackOpen returns the bare sentinel ErrShortRead when the body is under 10 octets or when the Optional Parameters Length (standard or RFC 9072 extended) overruns the body (internal/component/bgp/message/open.go:167-168, :193-194, :199-200, :209-210), and handleOpen turns that into an FSM event and a returned error, writing no NOTIFICATION and not even closing the connection (internal/component/bgp/reactor/session_handlers.go:43-47); session_read.go:264 only propagates it. Every other OPEN error path does send Error Code 2 -- unsupported version (session_handlers.go:54-60), unacceptable Hold Time (:70-77) and a malformed capability (rejectOpenCapabilityError, :185-199) -- so the obligation holds everywhere except the decode failure. Disclosed in docs/features/rfc-status.md RFC 4271 row
RFC4271-8.2.1-3 For each incoming connection, a state machine MUST be instantiated (§8.2.1) {gap}, no test an incoming connection does not get its own state machine. acceptOrReject hands the accepted connection to the peer's existing session (internal/component/bgp/reactor/reactor_connection.go:117-163), and a connection queued for collision resolution is read raw by handlePendingCollision with no FSM behind it (internal/component/bgp/reactor/reactor_connection.go:196-249). An FSM is created per session, i.e. per connection attempt of a configured peer (internal/component/bgp/reactor/session.go:396), not per inbound connection
RFC4271-3.1-2 Next hop for routes in Loc-RIB MUST be resolvable via the local BGP speaker's Routing Table (§3.1) {gap}, no test the BGP Loc-RIB install performs no reachability check on the route's next hop. mirrorToLocRIB inserts the winning path with whatever next-hop address the attribute carried (internal/component/bgp/plugins/rib/rib_bestchange.go:797-830), and the candidate gather step filters only on SRv6 ineligibility (internal/component/bgp/plugins/rib/rib_commands.go:1039-1057). Resolvability is enforced downstream at FIB-install time, which removes the route from the routing table but leaves it in the Loc-RIB
RFC4271-5.1.7-1 A BGP speaker that performs aggregation and adds AGGREGATOR SHALL include its own AS number and IP address (§5.1.7) no test no test carries this requirement id; annotated {not-applicable}: ze never performs aggregation, so it never adds an AGGREGATOR of its own. The same grep as RFC4271-5.1.6-1 finds no aggregation producer; AGGREGATOR is only interned from the wire (internal/component/bgp/plugins/rib/storage/attrparse.go:96-102), replayed on readvertise (internal/component/bgp/plugins/rib/storage/familyrib.go:817-819) or emitted from operator configuration (internal/component/bgp/message/update_build_grouped.go:141-148)
RFC4271-9.1.2-1 If NEXT_HOP is not resolvable, the BGP route MUST be excluded from Phase 2 decision function (§9.1.2) {gap}, no test an unresolvable NEXT_HOP does not exclude the route from Phase 2. gatherCandidatesLocked skips only SRv6-ineligible entries (internal/component/bgp/plugins/rib/rib_commands.go:1039-1057), and extractCandidate uses the next hop solely to look up an IGP cost (internal/component/bgp/plugins/rib/rib_commands.go:1123-1131), so an unreachable next hop yields a cost of zero and the route competes normally
RFC4271-9.1.2-4 If immediate next-hop or IGP cost to NEXT_HOP changes, Phase 2 Route Selection MUST be performed again (§9.1.2) {gap}, no test nothing re-runs Phase 2 when the immediate next-hop or the IGP cost to the NEXT_HOP changes. The only entry points to checkBestPathChange are the UPDATE ingest path and the peer-state paths (internal/component/bgp/plugins/rib/rib_structured.go:271-286), and the IGP cost function is a passive lookup registered once with no invalidation callback (internal/component/bgp/plugins/rib/bestpath.go:30-43)
RFC4271-9.1.2.1-2 Unresolvable routes SHALL be removed from the Loc-RIB and the routing table (§9.1.2.1) {gap}, no test an unresolvable route is not removed from the Loc-RIB. The only Loc-RIB removal in the BGP plugin is the no-candidate-remains branch of checkBestPathChange (internal/component/bgp/plugins/rib/rib_bestchange.go:766-782), which is driven by the Adj-RIB-In losing its last path and never by next-hop resolvability; nothing in the plugin consults a resolver
RFC4271-9.1.2.2-2 If MULTI_EXIT_DISC is removed before IBGP readvertisement, the optional MED comparison MUST be performed only among EBGP-learned routes (§9.1.2.2) {gap}, no test the common egress guard is implemented, but normal BGP selected-route readvertisement has no runnable producer and no discriminating proof. `bgp-rib` records selected Loc-RIB state (internal/component/bgp/plugins/rib/rib_bestchange.go:738-790), route-server and route-reflector plugins forward cached UPDATEs instead (internal/component/bgp/plugins/rs/server.go:433-434 and internal/component/bgp/plugins/rr/rr.go:188-195), and BGP-to-BGP redistribution is rejected as same-protocol redistribution (internal/core/redistevents/registry.go:144-146)
RFC4271-9.2-2 A route SHALL NOT be installed in Adj-RIB-Out unless its destination and NEXT_HOP may be forwarded by the Routing Table (§9.2) {gap}, no test nothing gates Adj-RIB-Out installation on the destination and NEXT_HOP being forwardable. QueueAnnounce records the route unconditionally (internal/component/bgp/rib/outgoing.go:65-101), and the forwarding rails decide only on filters, family negotiation and the route-reflection rules (internal/component/bgp/reactor/forward_rs.go:295-333)
RFC4271-9.2-3 If a route in Loc-RIB is excluded from a particular Adj-RIB-Out, the previously advertised route MUST be withdrawn (§9.2) {gap}, no test a route excluded from a peer's Adj-RIB-Out by an egress filter is skipped silently, leaving the peer's previous advertisement in place instead of withdrawing it. Both forwarding rails `continue` on suppression with no withdrawal built (internal/component/bgp/reactor/forward_rs.go:320-333 and internal/component/bgp/reactor/reactor_api_forward.go:496-506); the one announce-to-withdraw conversion is LLGR-specific and filter-requested, not exclusion-driven (internal/component/bgp/reactor/reactor_api_forward.go:588-601)
RFC4271-9.2.1.1-2 Two UPDATE messages advertising to common destinations MUST be separated by at least MinRouteAdvertisementIntervalTimer (§9.2.1.1) {gap}, no test ze has no MinRouteAdvertisementIntervalTimer, so successive UPDATEs to a common set of destinations are not spaced. The timer set implements only ConnectRetry, Hold and Keepalive and records the omission in its own doc comment (internal/component/bgp/fsm/timer.go:34-42, "MinRouteAdvertisementIntervalTimer (Section 9.2.1.1) - not implemented here"); `grep -rniE 'minroute|mrai' --include=*.go internal/` finds no producer
RFC4271-9.2.2.2-1 Routes with different MULTI_EXIT_DISC attributes SHALL NOT be aggregated (§9.2.2.2) no test no test carries this requirement id; annotated {not-applicable}: ze never aggregates routes, so no producer can aggregate two routes with different MULTI_EXIT_DISC values. `grep -rniE 'aggregate-address|AggregateRoute|route aggregation' --include=*.go .` returns no hit outside rfc/ and plan/, and no code path synthesizes an aggregate route from more-specifics
RFC4271-9.2.2.2-2 If any aggregated route has ORIGIN INCOMPLETE, the aggregate MUST have ORIGIN INCOMPLETE; else if any has EGP, the aggregate MUST have ORIGIN EGP (§9.2.2.2) no test no test carries this requirement id; annotated {not-applicable}: ze never aggregates routes, so no producer computes an aggregate ORIGIN. ORIGIN is only parsed (internal/core/bgp/attribute/origin.go:146-160), interned (internal/component/bgp/plugins/rib/storage/attrparse.go) and re-emitted verbatim (internal/component/bgp/plugins/rib/storage/familyrib.go:799-801); the same aggregation grep returns nothing
RFC4271-9.2.2.2-3 When aggregating routes with different NEXT_HOP, the aggregated NEXT_HOP SHALL identify an interface on the aggregating speaker (§9.2.2.2) no test no test carries this requirement id; annotated {not-applicable}: ze never aggregates routes, so no producer chooses an aggregated NEXT_HOP. The only next-hop selection is per-route egress policy (internal/component/bgp/reactor/peer_forward_facts.go:153-193); the same aggregation grep returns nothing
RFC4271-9.2.2.2-4 If at least one aggregated route has ATOMIC_AGGREGATE, the aggregate SHALL have it as well (§9.2.2.2) no test no test carries this requirement id; annotated {not-applicable}: ze never aggregates routes, so no producer decides whether an aggregate carries ATOMIC_AGGREGATE. The attribute is only decoded, stored and replayed (internal/core/bgp/attribute/simple.go:175-195, internal/component/bgp/plugins/rib/storage/familyrib.go:815-817); the same aggregation grep returns nothing
RFC4271-9.2.2.2-5 AGGREGATOR attributes from aggregated routes MUST NOT be included in the aggregated route (§9.2.2.2) no test no test carries this requirement id; annotated {not-applicable}: ze never aggregates routes, so no producer builds an aggregated route from which a contributing AGGREGATOR would have to be excluded. AGGREGATOR is only interned from the wire or emitted from operator configuration (internal/component/bgp/plugins/rib/storage/attrparse.go:96-102, internal/component/bgp/message/update_build_grouped.go:141-148); the same aggregation grep returns nothing
RFC4271-9.2.1.1-3 The last route selected while awaiting MinRouteAdvertisementIntervalTimer SHALL be advertised at expiry (§9.2.1.1) {gap}, no test with no MinRouteAdvertisementIntervalTimer there is no expiry at which a last-selected route could be advertised. The timer is absent by design note (internal/component/bgp/fsm/timer.go:39) and no producer buffers a pending best-route advertisement against such a timer; best-path changes are published as they are computed (internal/component/bgp/plugins/rib/rib_bestchange.go:832-880)

Proof state

A tagged unit reads unproven where no discrimination record exists for it: nothing in this tree has been observed to break it, so the claim its tag makes is unproven.

RFC4271-4.1-1

Marker field MUST be set to all ones (16 bytes of 0xFF) (§4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271MarkerNotAllOnesRejected unit/verify unproven
positive TestRFC4271MarkerAllOnesOnSend unit/verify unproven

RFC4271-4.1-2

Length field MUST have the smallest value required given the rest of the message (§4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NonSmallestLengthRejected unit/verify unproven
positive TestRFC4271SmallestLengthOnSend unit/verify unproven

RFC4271-4.1-3

Message Length MUST be between 19 and 4096 octets (§4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271MessageLengthOutOfBounds unit/verify unproven
positive TestRFC4271MessageLengthWithinBounds unit/verify unproven

RFC4271-4.3-1

For well-known attributes, the Transitive bit MUST be set to 1 (§4.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271WellKnownAttributeErrorsAreCaught unit/verify unproven
positive TestRFC4271WellKnownAttributesAreTransitive unit/verify unproven

RFC4271-4.3-2

Partial bit MUST be set to 0 for well-known and optional non-transitive attributes (§4.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271PartialBitClearedOnReadvertisedWellKnown unit/verify unproven
negative TestRFC4271PartialNotStampedOnExcludedClasses unit/verify unproven
positive TestRFC4271PartialNotSetOnRecognizedOrNonTransitive unit/verify unproven
positive TestRFC4271PartialBitClearOnSend unit/verify unproven

RFC4271-4.3-3

Lower-order four bits of attribute flags MUST be zero when sent (§4.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestRFC4271AttributeFlagsLowNibbleZeroOnSend unit/verify unproven

RFC4271-4.3-4

Lower-order four bits of attribute flags MUST be ignored when received (§4.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271AttrFlagsHighBitsNotIgnored unit/verify unproven
positive TestRFC4271AttrFlagsLowNibbleIgnoredOnReceive unit/verify unproven

RFC4271-4.4-1

KEEPALIVE messages MUST NOT be sent more frequently than one per second (§4.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271KeepaliveIntervalNeverSubSecond unit/verify unproven
positive TestRFC4271KeepaliveNotFasterThanOnePerSecond unit/verify unproven

RFC4271-4.4-2

If the negotiated Hold Time is zero, periodic KEEPALIVE messages MUST NOT be sent (§4.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestKeepaliveWithZeroHoldTime unit/verify unproven
positive TestTimersKeepaliveTimer unit/verify unproven

RFC4271-6-1

If no Error Subcode is specified, a zero MUST be used (§6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NotificationSpecifiedSubcodePreserved unit/verify unproven
positive TestRFC4271NotificationUnspecifiedSubcodeIsZero unit/verify unproven

RFC4271-4.2-1

Hold Time MUST be either zero or at least three seconds (§4.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestOpenValidateHoldTime unit/verify unproven
positive TestOpenValidateHoldTime unit/verify unproven

RFC4271-4.2-2

BGP speaker MUST calculate Hold Timer by using the smaller of its configured Hold Time and the received Hold Time (§4.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNegotiateWith_HoldTimeZero unit/verify unproven
positive TestNegotiateWith_HoldTimeMinOfBoth unit/verify unproven

RFC4271-6.2-1

An implementation MUST reject Hold Time values of one or two seconds (§6.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestOpenValidateHoldTime unit/verify unproven
positive TestOpenValidateHoldTime unit/verify unproven

RFC4271-6.2-2

An implementation that accepts a Hold Time MUST use the negotiated value (§6.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271LocalHoldTimeNotUsedWhenPeerProposesSmaller unit/verify unproven
positive TestRFC4271NegotiatedHoldTimeDrivesTimers unit/verify unproven

RFC4271-5-1

BGP implementations MUST recognize all well-known attributes (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271WellKnownAttributeErrorsAreCaught unit/verify unproven
positive TestRFC4271WellKnownAttributesAreRecognized unit/verify unproven

RFC4271-5-2

Well-known mandatory attributes MUST be included in every UPDATE containing NLRI (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271WellKnownAttributeErrorsAreCaught unit/verify unproven
positive TestRFC4271WellKnownAttributesAreRecognized unit/verify unproven

RFC4271-5-3

Unrecognized transitive optional attributes MUST be passed along with the Partial bit set to 1 (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271PartialNotSetOnRecognizedOrNonTransitive unit/verify unproven
negative TestRFC4271PartialNotStampedOnExcludedClasses unit/verify unproven
positive TestRFC4271PartialSetOnUnrecognizedTransitiveOptional unit/verify unproven
positive TestRFC4271PartialStampedOnUnrecognizedTransitive unit/verify unproven
positive rfc4271-partial-unknown-transitive.ci functional/verify unproven

RFC4271-5-4

Partial bit set to 1 by a previous AS MUST NOT be set back to 0 (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271PartialBitSurvivesLengthReframing unit/verify unproven
negative TestRFC4271PartialFromPreviousASNotCleared unit/verify unproven
positive TestRFC4271PartialBitPreservedOnUnknownTransitive unit/verify unproven
positive TestRFC4271PartialFromPreviousASNeverCleared unit/verify unproven

RFC4271-5-5

Unrecognized non-transitive optional attributes MUST be quietly ignored (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271TheNonTransitiveDropSparesEveryOtherClass unit/verify unproven
positive TestRFC4271UnrecognizedNonTransitiveIsNotPassedAlong unit/verify unproven

RFC4271-5-6

Receiver of an UPDATE MUST be prepared to handle path attributes that are out of order (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271OutOfOrderDoesNotMaskMalformation unit/verify unproven
positive TestRFC4271AttributesOutOfOrderAccepted unit/verify unproven

RFC4271-4.3-5

A BGP speaker MUST be able to process UPDATE messages with the same prefix in both WITHDRAWN and NLRI (§4.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestRIBInjectSamePrefixInWithdrawnAndNLRIInstallsTheRoute unit/verify unproven
positive TestRIBPoolPathSamePrefixInWithdrawnAndNLRIInstallsTheRoute unit/verify unproven
positive TestRIBSamePrefixInWithdrawnAndNLRIInstallsTheRoute unit/verify unproven

RFC4271-5.1.3-1

A route originated by a BGP speaker SHALL NOT be advertised to a peer using that peer's address as NEXT_HOP (§5.1.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEgressNextHopIsPeerOwnReadsTheRewrittenAddress unit/verify unproven
negative TestForwardRSWithholdsRouteWhoseNextHopIsTheClientsOwnAddress unit/verify unproven
negative TestForwardWithholdsRouteWhoseNextHopIsTheDestinationsOwnAddress unit/verify unproven
negative TestSendAnnounceWithholdsRouteWithPeerOwnNextHop unit/verify unproven
negative TestSendUpdateWithholdsOriginatedRouteWithPeerOwnNextHop unit/verify unproven
negative checkSelfNextHopWithheld interop/nightly unproven
negative originated-nexthop-peer-own.ci functional/verify unproven
positive TestEgressNextHopIsPeerOwnReadsTheRewrittenAddress unit/verify unproven
positive TestForwardRSWithholdsRouteWhoseNextHopIsTheClientsOwnAddress unit/verify unproven
positive TestForwardWithdrawsFromDestinationWhoseNextHopIsItsOwnAddress unit/verify unproven
positive TestForwardWithholdsRouteWhoseNextHopIsTheDestinationsOwnAddress unit/verify unproven
positive TestSendAnnounceWithholdsRouteWithPeerOwnNextHop unit/verify unproven
positive TestSendUpdateWithholdsOriginatedRouteWithPeerOwnNextHop unit/verify unproven
positive checkSelfNextHopWithheld interop/nightly unproven
positive originated-nexthop-peer-own.ci functional/verify unproven

RFC4271-5.1.3-2

A BGP speaker SHALL NOT install a route with itself as the next hop (§5.1.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271SelfNextHopDoesNotShadowASoundAlternative unit/verify unproven
negative TestRFC4271SelfNextHopRouteIsNotInstalled unit/verify unproven
negative TestRFC4271SelfNextHopSetComesFromPeerEvents unit/verify unproven
positive TestRFC4271SelfNextHopRouteIsNotInstalled unit/verify unproven
positive TestRFC4271SelfNextHopSetComesFromPeerEvents unit/verify unproven

RFC4271-5.1.3-3

A BGP speaker MUST be able to support disabling advertisement of third-party NEXT_HOP attributes (§5.1.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ThirdPartyNextHopDisableFailsClosed unit/verify unproven
positive TestRFC4271ThirdPartyNextHopCanBeDisabled unit/verify unproven

RFC4271-5.1.4-1

MULTI_EXIT_DISC received from a neighboring AS MUST NOT be propagated to other neighboring ASes (§5.1.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestForwardKeepsFilterSetMED unit/verify unproven
negative TestForwardSuppressesReceivedMEDToAnotherAS unit/verify unproven
negative TestForwardWritesLocallySetMED unit/verify unproven
negative TestMEDPropagationAllowedTo unit/verify unproven
negative checkMEDAcrossAS interop/nightly unproven
negative med-locally-set-reaches-peer.ci functional/verify unproven
negative med-not-propagated-across-as.ci functional/verify unproven
positive TestForwardSuppressesReceivedMEDToAnotherAS unit/verify unproven
positive checkMEDAcrossAS interop/nightly unproven
positive med-not-propagated-across-as.ci functional/verify unproven

RFC4271-5.1.4-4

A BGP speaker MUST implement a mechanism (based on local configuration) that allows the MULTI_EXIT_DISC attribute to be removed from a route (§5.1.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestParseModifyDefsMEDRemove unit/verify unproven
negative TestMEDRemovalMechanismIsConfigurable unit/verify unproven
negative TestMEDRemoveDirectiveIsValueless unit/verify unproven
negative checkMEDRemovalConfiguration interop/nightly unproven
positive TestParseModifyDefsMEDRemove unit/verify unproven
positive TestMEDRemovalMechanismIsConfigurable unit/verify unproven
positive checkMEDRemovalConfiguration interop/nightly unproven
positive med-removal-configured.ci functional/verify unproven

RFC4271-5.1.4-2

MULTI_EXIT_DISC removal from routes MUST be done before the route is used in Phase 2 of the decision process (§5.1.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestHandleFilterUpdateMEDRemoveIsImportOnly unit/verify unproven
negative TestMEDRemovalMechanismIsConfigurable unit/verify unproven
negative med-removal-before-decision.ci functional/verify unproven
negative med-removal-export-refused.ci functional/verify unproven
positive TestHandleFilterUpdateMEDRemoveIsImportOnly unit/verify unproven
positive TestMEDRemovalMechanismIsConfigurable unit/verify unproven
positive med-removal-before-decision.ci functional/verify unproven
positive med-removal-configured.ci functional/verify unproven

RFC4271-5.1.5-1

LOCAL_PREF SHALL be included in all UPDATE messages sent to internal peers (§5.1.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestForwardLocalPrefStrippedToExternalPeer unit/verify unproven
negative TestAnnounceStripsLocalPrefTowardExternalPeer unit/verify unproven
negative TestRFC4271LocalPrefOmittedForExternalPeers unit/verify unproven
positive TestRFC4271LocalPrefIncludedForInternalPeers unit/verify unproven

RFC4271-5.1.5-2

A BGP speaker MUST NOT include LOCAL_PREF in UPDATE messages sent to external peers (§5.1.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLocalPrefAllowedToIsTheOnlyAnswer unit/verify unproven
negative TestRFC4271LocalPrefIncludedForInternalPeers unit/verify unproven
negative local-pref-strip-ebgp.ci functional/verify unproven
positive TestForwardLocalPrefStripBeatsAFilterSet unit/verify unproven
positive TestForwardLocalPrefStrippedToExternalPeer unit/verify unproven
positive TestAnnounceStripsLocalPrefTowardExternalPeer unit/verify unproven
positive TestRFC4271LocalPrefOmittedForExternalPeers unit/verify unproven
positive checkLocalPrefStrip interop/nightly unproven
positive local-pref-strip-ebgp.ci functional/verify unproven

RFC4271-5.1.5-3

If LOCAL_PREF is received over EBGP, it MUST be ignored (§5.1.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271LocalPrefIgnoredOnExternalSession unit/verify unproven
positive TestRFC4271LocalPrefKeptOnInternalSession unit/verify unproven

RFC4271-5.1.5-4

The higher degree of preference (LOCAL_PREF) MUST be preferred (§5.1.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestBestPath_LocalPref unit/verify unproven
positive TestBestPath_LocalPref unit/verify unproven

RFC4271-5.1.6-1

A BGP speaker that receives a route with the ATOMIC_AGGREGATE attribute MUST NOT make any NLRI of that route more specific when advertising this route to other BGP speakers (§5.1.6)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-5.1.6-1, so no unit is bound to it.

RFC4271-6.1-1

All header errors MUST be indicated by sending NOTIFICATION with Error Code Message Header Error (§6.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-6.1-1, so no unit is bound to it.

RFC4271-6.1-2

Marker not all ones: Error Subcode MUST be Connection Not Synchronized (§6.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-6.1-2, so no unit is bound to it.

RFC4271-6.1-3

Invalid length: Error Subcode MUST be Bad Message Length; Data field MUST contain the erroneous Length field (§6.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-6.1-3, so no unit is bound to it.

RFC4271-6.1-4

Invalid type: Error Subcode MUST be Bad Message Type; Data field MUST contain the erroneous Type field (§6.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-6.1-4, so no unit is bound to it.

RFC4271-6.2-3

All OPEN errors MUST be indicated by NOTIFICATION with Error Code OPEN Message Error (§6.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-6.2-3, so no unit is bound to it.

RFC4271-6.3-1

All UPDATE errors MUST be indicated by NOTIFICATION with Error Code UPDATE Message Error (§6.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConformantUpdateSendsNoUpdateError unit/verify unproven
positive TestRFC4271UpdateErrorReportedAsUpdateMessageError unit/verify unproven

RFC4271-6.7-1

Cease NOTIFICATION MUST NOT be used when a fatal error does exist (§6.7)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271UpdateErrorReportedAsUpdateMessageError unit/verify unproven
positive TestPrefixExceedTeardown unit/verify unproven

RFC4271-8.2.1-1

BGP MUST maintain a separate FSM for each configured peer (§8.2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271PerPeerFSMDoesNotShareTimers unit/verify unproven
positive TestRFC4271SeparateFSMPerPeer unit/verify unproven

RFC4271-8.2.1-2

A BGP implementation MUST connect to and listen on TCP port 179 (§8.2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ExplicitPortOverridesDefault unit/verify unproven
positive TestRFC4271DefaultBGPPortIs179 unit/verify unproven

RFC4271-8.2.1-3

For each incoming connection, a state machine MUST be instantiated (§8.2.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-8.2.1-3, so no unit is bound to it.

RFC4271-8.2.2-1

Event 10 (HoldTimer_Expires) lists "sends a NOTIFICATION message with the error code Hold Timer Expired" before "drops the TCP connection", in OpenSent, OpenConfirm and Established alike; a peer whose connection is dropped without it is told nothing. §8 states the FSM description is conceptual but binds "the same externally visible behavior", and the NOTIFICATION is the externally visible part, so the level is MUST (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271HoldTimerNotYetExpiredSendsNoNotification unit/verify unproven
positive TestRFC4271HoldTimerExpirySendsNotification unit/verify unproven
positive deadpeer-holddown.ci functional/verify unproven

RFC4271-8.2.2-2

Event 10 (HoldTimer_Expires) lists "sets the ConnectRetryTimer to zero", in OpenSent, OpenConfirm and Established alike. A ConnectRetryTimer left running past the teardown fires against a connection that no longer exists, and the retry it schedules is externally visible as an unexpected connection attempt, so the level is MUST on the same §8 "same externally visible behavior" ground as -1 (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NoHoldExpiryLeavesTheSessionIntact unit/verify unproven
positive TestRFC4271HoldExpiryRunsTheEvent10ActionList unit/verify unproven

RFC4271-8.2.2-3

Event 10 (HoldTimer_Expires) lists "releases all BGP resources", in OpenSent, OpenConfirm and Established alike. The externally visible part is the KeepaliveTimer: a session torn down for silence that keeps its keepalive chain running writes KEEPALIVEs after the teardown, so the level is MUST (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NoHoldExpiryLeavesTheSessionIntact unit/verify unproven
positive TestRFC4271HoldExpiryRunsTheEvent10ActionList unit/verify unproven

RFC4271-8.2.2-4

Event 10 (HoldTimer_Expires) lists "drops the TCP connection", in OpenSent, OpenConfirm and Established alike. The peer must see the connection go away and not merely stop receiving; a half-open socket is externally visible, so the level is MUST (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NoHoldExpiryLeavesTheSessionIntact unit/verify unproven
positive TestRFC4271HoldExpiryRunsTheEvent10ActionList unit/verify unproven

RFC4271-8.2.2-5

Event 10 (HoldTimer_Expires) lists "changes its state to Idle", in OpenSent, OpenConfirm and Established alike. The Established->Idle transition is what deletes the routes learned over the connection, which is externally visible to every other peer, so the level is MUST (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NoHoldExpiryLeavesTheSessionIntact unit/verify unproven
positive TestRFC4271HoldExpiryRunsTheEvent10ActionList unit/verify unproven

RFC4271-8.2.2-7

ManualStart (Event 1) in Idle lists "sets ConnectRetryCounter to zero", once for the Connect branch (Events 1 and 3) and again, in the same words, for the passive Active branch (Events 4 and 5). §8 makes ConnectRetryCounter a mandatory session attribute and defines it as "the number of times a BGP peer has tried to establish a peer session", so an operator start that left a stale retry history behind would misreport that number; the level is MUST (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterSurvivesDampedStart unit/verify unproven
positive TestRFC4271ConnectRetryCounterZeroedOnManualStart unit/verify unproven

RFC4271-8.2.2-8

ManualStop (Event 2) lists "sets the ConnectRetryCounter to zero", in Connect, Active, OpenSent, OpenConfirm and Established alike. Same §8 mandatory-attribute ground as -7: the operator stopping the peer ends the run of attempts the counter was counting (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterNotZeroedByIdleManualStop unit/verify unproven
positive TestRFC4271ConnectRetryCounterZeroedOnManualStop unit/verify unproven

RFC4271-8.2.2-9

HoldTimer_Expires (Event 10) lists "increments the ConnectRetryCounter", in OpenSent, OpenConfirm and Established alike (OpenSent omits the words "by 1" that the other two carry; the counter is an integer count, so the step is one). A session lost to silence is an attempt that failed, and §8 makes the count mandatory (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterQuietOnHealthyEstablishedTraffic unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnHoldTimerExpiry unit/verify unproven

RFC4271-8.2.2-10

BGPHeaderErr (Event 21) and BGPOpenMsgErr (Event 22) list "increments the ConnectRetryCounter by 1" in Connect, Active, OpenSent and OpenConfirm, and in Established through "In response to any other event (Events 9, 12-13, 20-22)", which names both (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterNotIncrementedByIdleErrors unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnHeaderAndOpenErrors unit/verify unproven

RFC4271-8.2.2-11

NotifMsg (Event 25) leads to "increments the ConnectRetryCounter by 1" in every state that can see it: explicitly in OpenConfirm ("a TcpConnectionFails event (Event 18) [...] or a NOTIFICATION message (Event 25)") and Established ("a NOTIFICATION message (Event 24 or Event 25)"), and through the "any other event" list that names Event 25 in Connect, Active and OpenSent (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterStepsByExactlyOnePerNotification unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnNotification unit/verify unproven

RFC4271-8.2.2-12

NotifMsgVerErr (Event 24) increments the ConnectRetryCounter in Connect, Active and Established, and MUST NOT in OpenSent or OpenConfirm. In Connect and Active the clause sits in the DelayOpenTimer-is-not-running branch, which is the only branch a speaker without a DelayOpenTimer can take, and Established groups Event 24 with Events 25 and 18; in OpenSent and OpenConfirm the Event 24 action list is four items long and has no ConnectRetryCounter line at all (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterQuietOnVersionErrorInOpenStates unit/verify unproven
positive TestRFC4271ConnectRetryCounterOnVersionErrorPerState unit/verify unproven

RFC4271-8.2.2-13

TcpConnectionFails (Event 18) increments the ConnectRetryCounter in Active, OpenConfirm and Established, and MUST NOT in Connect or OpenSent. Connect's Event 18 has two branches and neither carries the clause, and OpenSent's Event 18 leaves for Active rather than tearing the peering down (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterQuietOnTCPFailureInConnectAndOpenSent unit/verify unproven
positive TestRFC4271ConnectRetryCounterOnTCPFailurePerState unit/verify unproven

RFC4271-8.2.2-14

UpdateMsgErr (Event 28) in Established lists "increments the ConnectRetryCounter by 1". An UPDATE error ends the session, which makes it a failed attempt by the §8 definition of the attribute (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterQuietOnGoodUpdate unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnUpdateError unit/verify unproven

RFC4271-8.2.2-15

The "any other event" action list lists "increments the ConnectRetryCounter by 1" ("by one" in Active) in all five non-Idle states: Connect and Active (Events 8, 10-11, 13, 19, 23, 25-28), OpenSent (Events 9, 11-13, 20, 25-28), OpenConfirm (Events 9, 12-13, 20, 27-28) and Established (Events 9, 12-13, 20-22). Idle is excluded on purpose: its own "any other event" clause says the event "does not cause change in the state of the local system" and lists no actions (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterIdleDefaultArmCountsNothing unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnAnyOtherEvent unit/verify unproven

RFC4271-8.2.2-16

AutomaticStop (Event 8) lists "increments the ConnectRetryCounter by 1" in OpenSent, OpenConfirm and Established, and Connect and Active name Event 8 in their "any other events" list, which carries the same line. Its action list differs from ManualStop's by that one line, and the difference is the point: §8 defines the attribute as "the number of times a BGP peer has tried to establish a peer session", so a stop the local system chose records a failed attempt where an operator stop ends the count (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterAutomaticStopIsNotAManualStop unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnAutomaticStop unit/verify unproven

RFC4271-8.2.2-17

OpenCollisionDump (Event 23) lists "increments the ConnectRetryCounter by 1" in OpenSent, OpenConfirm and Established, and Connect and Active name Event 23 in their "any other events" list, which carries the same line. A connection closed by §6.8 collision resolution is an attempt that did not become a session (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ConnectRetryCounterCollisionDumpIsQuietInIdle unit/verify unproven
positive TestRFC4271ConnectRetryCounterIncrementsOnOpenCollisionDump unit/verify unproven

RFC4271-8.2.2-18

ManualStop (Event 2) lists the Cease NOTIFICATION FIRST in its action list, in every state that has a connection to send it on: OpenSent writes "sends the NOTIFICATION with a Cease", OpenConfirm and Established write "sends the NOTIFICATION message with a Cease", and all three list it before "drops the TCP connection". The level is MUST on the same §8 ground as -1: the FSM description is conceptual, but an implementation "MUST support the described functionality and exhibit the same externally visible behavior", and the NOTIFICATION is the externally visible part -- it is the ONLY signal that says the operator stopped this speaker rather than the network dropping it. §6.7's MAY governs a different act, a speaker CHOOSING to Cease "at any given time" of its own accord; once the operator has issued Event 2 the action list is what the FSM owes. Connect and Active list no Cease clause and are excluded: neither state holds a BGP connection (§8.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271NoCeaseWithoutAManualStop unit/verify unproven
positive TestShutdownNotifySendsCeaseFromEveryConnectedState unit/verify unproven
positive signal-stop-cease.ci functional/verify unproven

RFC4271-10-1

An implementation MUST allow the HoldTimer to be configurable on a per-peer basis (§10)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271PerPeerHoldTimeSurvivesNegotiation unit/verify unproven
positive TestRFC4271HoldTimeConfigurablePerPeer unit/verify unproven

RFC4271-5-7

Path attributes SHOULD be ordered in ascending order of attribute type (§5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestSplitMP_PreservesAscendingAttributeOrder unit/verify unproven
positive TestAnnounceBatchRail_AS4PathOrderedAgainstLargeCommunity unit/verify unproven
positive TestAnnounceBatchRail_AscendingTypeCodeOrder unit/verify unproven
positive TestAnnounceQueuedRail_AscendingTypeCodeOrder unit/verify unproven

RFC4271-6.3-2

Semantically incorrect NEXT_HOP SHOULD be logged and the route SHOULD be ignored (§6.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestRFC4271SelfNextHopRouteIsNotInstalled unit/verify unproven

RFC4271-3.1-2

Next hop for routes in Loc-RIB MUST be resolvable via the local BGP speaker's Routing Table (§3.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-3.1-2, so no unit is bound to it.

RFC4271-5.1.2-2

When advertising a route to an internal peer, the speaker SHALL NOT modify the AS_PATH attribute (§5.1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271ASPathPrependedTowardExternalPeer unit/verify unproven
positive TestEstablishedAnnounce_ExplicitASPath_IBGPVerbatim unit/verify unproven
positive TestRFC4271ASPathUnmodifiedTowardInternalPeer unit/verify unproven

RFC4271-5.1.2-3

When advertising a route to an external peer, the speaker prepends its own AS number to the leading AS_SEQUENCE of AS_PATH (creating one when the path is empty or led by an AS_SET) (§5.1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEstablishedAnnounce_ExplicitASPath_IBGPVerbatim unit/verify unproven
negative TestASPathSlotPrependOnlyWhenAdvertising unit/verify unproven
negative checkRelayWithdrawalShape interop/nightly unproven
positive TestEstablishedAnnounce_ExplicitASPath_PrependsLocalAS unit/verify unproven
positive TestASPathSlotPrependOnlyWhenAdvertising unit/verify unproven
positive checkRelayWithdrawalShape interop/nightly unproven

RFC4271-5.1.4-3

If altering MULTI_EXIT_DISC received over EBGP, alteration MUST be done prior to decision process phases 1 and 2 (§5.1.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestRFC4271MEDAlterationHappensAtIngress unit/verify unproven

RFC4271-5.1.5-5

A BGP speaker SHALL calculate the degree of preference for each external route based on locally-configured policy (§5.1.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271DegreeOfPreferenceNotAHardcodedConstant unit/verify unproven
positive TestRFC4271ExternalRouteDegreeOfPreferenceFromLocalPolicy unit/verify unproven

RFC4271-5.1.7-1

A BGP speaker that performs aggregation and adds AGGREGATOR SHALL include its own AS number and IP address (§5.1.7)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-5.1.7-1, so no unit is bound to it.

RFC4271-6.7-4

When terminating due to prefix limit, speaker MUST send NOTIFICATION with Error Code Cease (§6.7)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPrefixExceedDrop unit/verify unproven
positive TestPrefixExceedTeardown unit/verify unproven

RFC4271-6.8-1

In the event of connection collision, one of the connections MUST be closed (§6.8)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCollisionOpenSentNoCollision unit/verify unproven
positive TestCollisionOpenConfirmLocalWins unit/verify unproven

RFC4271-6.8-2

Upon receipt of an OPEN message, the local system MUST examine all connections in OpenConfirm state for collision (§6.8)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCollisionNonCollisionStates unit/verify unproven
positive TestCollisionOpenConfirmLocalWins unit/verify unproven

RFC4271-9-1

Withdrawn routes SHALL be removed from the Adj-RIB-In and the Decision Process SHALL be run (§9)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271WithdrawRemovesFromAdjRIBIn unit/verify unproven
positive TestRFC4271WithdrawRemovesFromAdjRIBIn unit/verify unproven

RFC4271-9-2

A new route with identical NLRI to an existing route SHALL replace the older route in Adj-RIB-In (§9)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271WithdrawRemovesFromAdjRIBIn unit/verify unproven
positive TestRFC4271SamePrefixReplacesRatherThanAccumulates unit/verify unproven

RFC4271-9-3

Once the Adj-RIB-In is updated, the speaker SHALL run its Decision Process (§9)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRIBBestChangeNoPublishSameBest unit/verify unproven
positive TestRIBBestChangeWithdraw unit/verify unproven

RFC4271-9.1.1-1

The degree of preference function SHALL NOT use the existence or attributes of other routes as inputs (§9.1.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271DegreeOfPreferenceFollowsOwnAttributes unit/verify unproven
positive TestRFC4271DegreeOfPreferenceIgnoresOtherRoutes unit/verify unproven

RFC4271-9.1.1-2

For external routes, the computed degree of preference MUST be used as the LOCAL_PREF value in IBGP readvertisement (§9.1.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271LocalPrefOmittedForExternalPeers unit/verify unproven
positive TestRFC4271LocalPrefIncludedForInternalPeers unit/verify unproven

RFC4271-9.1.2-1

If NEXT_HOP is not resolvable, the BGP route MUST be excluded from Phase 2 decision function (§9.1.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.1.2-1, so no unit is bound to it.

RFC4271-9.1.2-2

The local speaker SHALL install the best route in the Loc-RIB (§9.1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRIBBestChangeWithdraw unit/verify unproven
positive TestLocRIBMirror unit/verify unproven

RFC4271-9.1.2-3

The local speaker MUST determine the immediate next-hop address from the NEXT_HOP attribute (§9.1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271LocRIBNextHopComesFromNextHopAttribute unit/verify unproven
positive TestLocRIBMirror unit/verify unproven

RFC4271-9.1.2-4

If immediate next-hop or IGP cost to NEXT_HOP changes, Phase 2 Route Selection MUST be performed again (§9.1.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.1.2-4, so no unit is bound to it.

RFC4271-9.1.2.1-1

When installing a BGP route in the Routing Table, implementations MUST recalculate and take into account next-hops (§9.1.2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271LocRIBNextHopComesFromNextHopAttribute unit/verify unproven
positive TestLocRIBMirror unit/verify unproven

RFC4271-9.1.2.1-2

Unresolvable routes SHALL be removed from the Loc-RIB and the routing table (§9.1.2.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.1.2.1-2, so no unit is bound to it.

RFC4271-9.1.2.2-1

The tie-breaking criteria MUST be applied in the order specified (§9.1.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestBestPath_MED_SameNeighborAS unit/verify unproven
negative TestBestPathEqualBGPIdentifiersOnTheJSONRailFallThroughToPeerAddress unit/verify unproven
negative TestBestPathEqualBGPIdentifiersFallThroughToPeerAddress unit/verify unproven
positive TestBestPath_FullTiebreak unit/verify unproven
positive TestBestPathStepFComparesThePeerBGPIdentifierOnTheJSONRail unit/verify unproven
positive TestBestPathStepFComparesThePeerBGPIdentifier unit/verify unproven

RFC4271-9.1.2.2-2

If MULTI_EXIT_DISC is removed before IBGP readvertisement, the optional MED comparison MUST be performed only among EBGP-learned routes (§9.1.2.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.1.2.2-2, so no unit is bound to it.

RFC4271-9.1.2.2-3

For IBGP-learned routes, MULTI_EXIT_DISC MUST be used in comparisons that reach the MED step (§9.1.2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestBestPath_MED_SameNeighborAS unit/verify unproven
positive TestBestPath_MED_SameNeighborAS unit/verify unproven

RFC4271-9.2-2

A route SHALL NOT be installed in Adj-RIB-Out unless its destination and NEXT_HOP may be forwarded by the Routing Table (§9.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2-2, so no unit is bound to it.

RFC4271-9.2-3

If a route in Loc-RIB is excluded from a particular Adj-RIB-Out, the previously advertised route MUST be withdrawn (§9.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2-3, so no unit is bound to it.

RFC4271-9.2-4

The Decision Process MUST consider both overlapping routes based on acceptance policy (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271SamePrefixReplacesRatherThanAccumulates unit/verify unproven
positive TestRFC4271OverlappingRoutesBothInstalled unit/verify unproven

RFC4271-9.2-5

If both less and more specific overlapping routes are accepted, the Decision Process MUST install both or an aggregate in Loc-RIB (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271SamePrefixReplacesRatherThanAccumulates unit/verify unproven
positive TestRFC4271OverlappingRoutesBothInstalled unit/verify unproven

RFC4271-9.2.1.1-2

Two UPDATE messages advertising to common destinations MUST be separated by at least MinRouteAdvertisementIntervalTimer (§9.2.1.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.1.1-2, so no unit is bound to it.

RFC4271-9.2.2.2-1

Routes with different MULTI_EXIT_DISC attributes SHALL NOT be aggregated (§9.2.2.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.2.2-1, so no unit is bound to it.

RFC4271-9.2.2.2-2

If any aggregated route has ORIGIN INCOMPLETE, the aggregate MUST have ORIGIN INCOMPLETE; else if any has EGP, the aggregate MUST have ORIGIN EGP (§9.2.2.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.2.2-2, so no unit is bound to it.

RFC4271-9.2.2.2-3

When aggregating routes with different NEXT_HOP, the aggregated NEXT_HOP SHALL identify an interface on the aggregating speaker (§9.2.2.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.2.2-3, so no unit is bound to it.

RFC4271-9.2.2.2-4

If at least one aggregated route has ATOMIC_AGGREGATE, the aggregate SHALL have it as well (§9.2.2.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.2.2-4, so no unit is bound to it.

RFC4271-9.2.2.2-5

AGGREGATOR attributes from aggregated routes MUST NOT be included in the aggregated route (§9.2.2.2)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.2.2-5, so no unit is bound to it.

RFC4271-Security-1

A BGP implementation MUST support TCP MD5 authentication (RFC 2385) (§Security, Appendix E)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestMD5PeersForListener unit/verify unproven
positive TestMD5PeersForListener unit/verify unproven

RFC4271-9.2.1.1-3

The last route selected while awaiting MinRouteAdvertisementIntervalTimer SHALL be advertised at expiry (§9.2.1.1)

Audit verdict: not audited: no reader has judged these tests

No test carries RFC4271-9.2.1.1-3, so no unit is bound to it.

RFC4271-9.2-6

A BGP speaker SHALL NOT redistribute routing information from an internal peer to other internal peers (unless route reflector) (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271IBGPRedistributionAllowedForReflectorClient unit/verify unproven
positive TestRFC4271NoIBGPToIBGPRedistribution unit/verify unproven

RFC4271-9.2-7

Newly unfeasible routes for which there is no replacement SHALL be advertised via UPDATE (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRIBBestChangeNoPublishSameBest unit/verify unproven
positive TestRIBBestChangeWithdraw unit/verify unproven

RFC4271-9.2-8

Any routes in the Loc-RIB marked as unfeasible SHALL be removed (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRIBBestChangeNoPublishSameBest unit/verify unproven
positive TestLocRIBMirror unit/verify unproven

RFC4271-9.2-9

Changes to reachable destinations within the speaker's own AS SHALL be advertised in an UPDATE (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271OwnASUnreachabilityChangeAdvertised unit/verify unproven
positive TestRFC4271OwnASReachabilityChangeAdvertised unit/verify unproven

RFC4271-9.2-10

If a single route does not fit in an UPDATE message, the speaker MUST NOT advertise it and MAY log an error (§9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC4271FittingRouteIsAdvertised unit/verify unproven
positive TestRFC4271OversizeSingleRouteNotAdvertised unit/verify unproven

RFC4271-9.1.2-5

If the AS_PATH attribute of a BGP route contains an AS loop, the BGP route should be excluded from the Phase 2 decision function (§9.1.2). Detection scans the full AS path and checks that the local autonomous system number does not appear in it. RFC 4271 writes this keyword in lower case, so the level is a recommendation and not a capitalized RFC 2119 SHOULD. The same paragraph places a speaker configured to accept routes with its own autonomous system number in the AS path outside the scope of the document. That out-of-scope case is what the allow-own-as setting selects, so a non-zero allow-own-as is not a deviation from this line.

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDetectASLoop unit/verify unproven
negative TestDetectASLoop_ASSet unit/verify unproven
negative loop-as.ci functional/verify unproven
positive TestDetectASLoop_NotPresent unit/verify unproven

RFC4271-4.3-7

An UPDATE containing the same prefix in WITHDRAWN and NLRI SHOULD be treated as if the prefix is not in WITHDRAWN (§4.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
positive TestRIBInjectSamePrefixInWithdrawnAndNLRIInstallsTheRoute unit/verify unproven
positive TestRIBPoolPathSamePrefixInWithdrawnAndNLRIInstallsTheRoute unit/verify unproven
positive TestRIBSamePrefixInWithdrawnAndNLRIInstallsTheRoute unit/verify unproven

Extraction sign-off

No extraction sign-off exists for RFC 4271, so no reviewer has walked its text sentence by sentence.

Superseded

No document obsoletes RFC 4271, so its obligations are stated where they were written.