Skip to content
LinkState
Go back

The regex route-map that matched the whole customer table

Incident Overview

On 2024‑09‑12 at 09:14 UTC, the BGP routing table on the edge routers of AS 65001 swelled to ≈ 1.2 M customer prefixes—a 40× increase over the expected ≈ 30 k. The surge caused:

The root cause was an overly permissive regular expression in a route‑map that matched far more AS‑PATH strings than intended, causing the router to accept and re‑advertise every prefix learned from the upstream peer (AS 65000).


Incident Timeline

Time (UTC)Event
09:00Change‑control window opens; network‑automation pipeline pushes updated route‑map RM-CUST-IN to all edge routers (cRPD‑based FRR 8.4).
09:02Automated CI job reports PASS for unit tests (see Weak Test Coverage).
09:05Route‑map activated on routers via route-map RM-CUST-IN permit 10.
09:07First BGP UPDATE burst observed on rtr‑edge01; BGP table jumps from 28 k to 112 k prefixes.
09:09Monitoring (Prometheus + Alertmanager) fires BgpPrefixCountHigh warning (threshold 100 k).
09:12NOC engineer acknowledges alert, runs show ip bgp summary; sees abnormal prefix growth.
09:14Senior engineer suspects the route‑map regex; enables debug bgp updates and inspects show route-map RM-CUST-IN.
09:18Temporary workaround: no route-map RM-CUST-IN applied on all edge routers; BGP table begins to shrink.
09:30Prefix count returns to baseline (≈ 30 k).
09:45Post‑mortem meeting convened; incident logged in JIRA NET‑2024‑0912.
10:00Change‑control window closes; rollback of faulty route‑map completed.

Root Cause Analysis

Intended Route‑Map Logic

The route‑map was meant to accept only customer‑originated prefixes whose AS‑PATH ends with the customer AS number and contains the peer AS 65000 exactly once:

match as-path regex "^_65000_[0-9]+$"

Deployed (Incorrect) Regex

The version pushed to production was:

match as-path regex "^_65000_.*"

Examples of Unintended Matches

AS‑PATHReason it matched (incorrect)
65000 65010 65020customer‑customer transit
65000 65010 65020 65030multiple customer ASes
65000 65010 65000 65020peer AS appears twice
65000 (no customer AS)still matches because .* can be empty
… 65000 … (peer anywhere)any occurrence triggers a match

Impact of the Incorrect Regex

Results


Weak Review Gates

Code Review Process

Approval and Validation Procedures

Inadequate Peer Review


Weak Test Coverage

Test Environment and Methodology

Inadequate Test Scenarios

Positive test (only case covered):

assert test_aspath("65000 65010") == True   # expected match

Missing negative tests:

The CI pipeline marked the build green because the sole assertion passed; the lack of negative assertions meant the faulty regex was never detected.


Slow Detection and Response

Monitoring and Alerting Mechanisms

Anomaly Detection and Response Times

Contributing factors

Communication Breakdowns


Troubleshooting and Debugging

Initial Troubleshooting Steps

  1. Verify BGP table size

    show ip bgp summary | include Prefix

    Output: 1,215,432 prefixes (expected ~30 k).

  2. Check route‑map hit counters

    show route-map RM-CUST-IN

    Output: policy routing matches: 1,198,742 packets.

  3. Examine a sample UPDATE

    debug bgp updates in   # filtered to a single neighbor

    Showed every UPDATE from the peer being accepted.

  4. Test the regex directly

    show route-map RM-CUST-IN test as-path 65000 65010
    show route-map RM-CUST-IN test as-path 65000 65010 65020

    Both returned match, confirming the over‑broad pattern.

Debugging Techniques and Tools

Example CLI Commands for Debugging

# 1. Confirm prefix explosion
show ip bgp summary | awk '/Prefix/ {print $2}'

# 2. Show route-map statistics
show route-map RM-CUST-IN

# 3. Test specific AS-paths
show route-map RM-CUST-IN test as-path 65000 65010
show route-map RM-CUST-IN test as-path 65000 65010 65020
show route-map RM-CUST-IN test as-path 65000
show route-map RM-CUST-IN test as-path 65010 65000

End of review.


Share this post on:

Previous Post
CLI Grep Structured Query or LLM Triage
Next Post
Retry Budgets, Hysteresis, and Kill Switches for Self-Healing