Skip to content

Actions Reference

Thomas Mangin edited this page Nov 15, 2025 · 7 revisions

FlowSpec Actions Reference

Complete reference for all FlowSpec actions

RFC 5575 (IPv4) / RFC 8955 (IPv6) - Extended Community-based actions


Table of Contents


Overview

FlowSpec actions define what to do with matched traffic.

Basic structure:

announce flow route {
    match {
        <conditions>
    }
    then {
        <action>;
    }
}

Actions are implemented as BGP Extended Communities sent with the FlowSpec route.

Available actions:

Action Extended Community Type Purpose
discard traffic-action (0x8006) Drop packets
rate-limit traffic-rate (0x8006) Limit bandwidth
redirect redirect (0x8008) Redirect to VRF
mark traffic-marking (0x8009) Remark DSCP
community Standard/Extended Tag traffic

Discard

Drop matching packets completely

Syntax

then {
    discard;
}

Extended Community

Traffic-action: terminal-action

Description

Matching packets are immediately dropped at the router.

Characteristics:

  • βœ… Most common action for DDoS mitigation
  • βœ… Hardware-based (wire-speed performance)
  • βœ… Zero bandwidth consumption for dropped packets
  • ⚠️ No logging of dropped packets (router-dependent)
  • ⚠️ Legitimate traffic may be affected if rule too broad

Examples

Block SYN Flood

announce flow route {
    match {
        destination 100.10.0.100/32;
        destination-port =80;
        protocol =tcp;
        tcp-flags [ syn ];
    }
    then {
        discard;
    }
}

Result: All TCP SYN packets to 100.10.0.100:80 are dropped.


Block DNS Amplification

announce flow route {
    match {
        source-port =53;
        protocol =udp;
        packet-length >512;
    }
    then {
        discard;
    }
}

Result: Large DNS responses (likely amplification) are dropped.


Block All ICMP

announce flow route {
    match {
        protocol =icmp;
    }
    then {
        discard;
    }
}

Result: All ICMP packets dropped (use during ICMP flood).


Use Cases

  • DDoS mitigation - Block attack traffic completely
  • Security blocking - Block known malicious sources
  • Protocol blocking - Block entire protocols during attacks
  • Emergency response - Stop attack immediately

Best Practices

  1. Be specific - Avoid blocking legitimate traffic
  2. Monitor impact - Check if rule affects real users
  3. Auto-expire - Withdraw rule when attack ends
  4. Log announcements - Track what you're blocking

Example with logging:

import logging
logging.info(f"[DISCARD] Blocking {source_ip} to port {port}")

sys.stdout.write(f"announce flow route {{ match {{ source {source_ip}/32; }} then {{ discard; }} }}\n")
sys.stdout.flush()

Rate-Limit

Limit bandwidth for matching traffic

Syntax

then {
    rate-limit <bytes-per-second>;
}

Extended Community

Traffic-rate: <rate-in-bytes-per-second>

Description

Matching packets are rate-limited to specified bandwidth.

⚠️ Implementation-Specific Behavior

RFC 5575/8955 do NOT specify whether rate-limit applies per-flow or as aggregate across all matching traffic. This is router implementation-specific:

  • Some vendors apply rate-limit per individual flow (per source IP)
  • Some vendors apply rate-limit as aggregate across all matching traffic
  • Consult your router vendor's documentation for exact behavior

ExaBGP signals the rate-limit value to the router via BGP - the router enforces it according to its own implementation.

Characteristics:

  • βœ… Throttle traffic instead of dropping completely
  • βœ… Allows some legitimate traffic through
  • βœ… Hardware-based policing
  • ⚠️ Excess traffic is dropped
  • ⚠️ Behavior (per-flow vs aggregate) depends on router vendor

Rate Calculation

⚠️ IMPORTANT: Vendor Implementation Differences

RFC 5575 specifies rate-limit values in bytes per second.

However, router vendors implement this differently:

  • Juniper: Converts bytes/sec to bits/sec internally (multiplies by 8)
  • Cisco: May interpret values differently depending on platform
  • Other vendors: Vary in implementation

ExaBGP follows RFC 5575 and sends values as bytes per second. Your router interprets these values according to its vendor-specific implementation.

Critical: Always test rate-limit behavior on your specific router platform. The same ExaBGP value may result in different actual rates on different vendor equipment.

RFC 5575 Compliant (Bytes per Second):

# 1 MB/sec (8 Mbps) = 1,000,000 bytes/sec
rate-limit 1000000

# 10 MB/sec (80 Mbps) = 10,000,000 bytes/sec
rate-limit 10000000

# 100 MB/sec (800 Mbps) = 100,000,000 bytes/sec
rate-limit 100000000

# 1 GB/sec (8 Gbps) = 1,000,000,000 bytes/sec
rate-limit 1000000000

Understanding the Values:

ExaBGP value (bytes/sec) β†’ Router interprets per vendor implementation

RFC 5575: bytes per second
Juniper:  converts to bits per second (Γ—8)
Cisco:    depends on platform

Conversion Reference:

  • 1 Mbps (megabit/sec) = 125,000 bytes/sec
  • 10 Mbps = 1,250,000 bytes/sec
  • 100 Mbps = 12,500,000 bytes/sec
  • 1 Gbps = 125,000,000 bytes/sec

Examples

Rate-Limit DNS Queries

announce flow route {
    match {
        destination-port =53;
        protocol =udp;
    }
    then {
        rate-limit 10000000;  # 10 Mbps
    }
}

Result: DNS traffic limited to 10 Mbps.


Rate-Limit SYN Flood

announce flow route {
    match {
        destination-port =80;
        protocol =tcp;
        tcp-flags [ syn ];
    }
    then {
        rate-limit 5000000;  # 5 Mbps
    }
}

Result: TCP SYN packets to port 80 limited to 5 Mbps.


Rate-Limit ICMP

announce flow route {
    match {
        protocol =icmp;
        icmp-type =8;  # Echo request
    }
    then {
        rate-limit 1000000;  # 1 Mbps
    }
}

Result: ICMP echo requests limited to 1 Mbps.


Rate-Limit Attack Source

announce flow route {
    match {
        source 203.0.113.0/24;  # Attacker network
    }
    then {
        rate-limit 1000000;  # 1 Mbps
    }
}

Result: All traffic from 203.0.113.0/24 limited to 1 Mbps.


Graduated Response

Start with rate-limiting, escalate to discard if needed:

# Step 1: Detect attack, rate-limit
announce flow route {
    match { source 10.0.0.0/8; destination-port =80; }
    then { rate-limit 10000000; }  # 10 Mbps
}

# Step 2: If still too much traffic, tighten rate
announce flow route {
    match { source 10.0.0.0/8; destination-port =80; }
    then { rate-limit 1000000; }  # 1 Mbps
}

# Step 3: If attack continues, block completely
announce flow route {
    match { source 10.0.0.0/8; destination-port =80; }
    then { discard; }
}

Use Cases

  • Proportional response - Limit before blocking
  • Soft mitigation - Allow some legitimate traffic
  • Protocol throttling - Slow down entire protocols
  • Testing - Validate rule before full block

Best Practices

  1. Start conservative - Higher rate first, lower if needed
  2. Monitor bandwidth - Check actual traffic reduction
  3. Per-service rates - Different limits for different services
  4. Combine with discard - Escalate if rate-limit insufficient

Vendor-Specific Notes

Extreme Networks:

  • Rate values must be multiples of 22 Kbps (22,000 bytes/sec)
  • Invalid rates may be rounded or rejected

Example for Extreme:

# Bad: Not a multiple of 22 Kbps
rate-limit 1000000  # May be rejected

# Good: Multiple of 22 Kbps
rate-limit 1100000  # 8.8 Mbps (50 Γ— 22 Kbps)

Redirect to VRF

Redirect matching traffic to a VRF (Virtual Routing and Forwarding instance)

Syntax

then {
    redirect <route-target>;
}

Extended Community

Redirect: <route-target>

Description

Matching packets are redirected to specified VRF instead of normal routing.

Characteristics:

  • βœ… Traffic sent to separate routing instance
  • βœ… Enables scrubbing center analysis
  • βœ… Allows inspection without blocking
  • ⚠️ Requires VRF configuration on router
  • ⚠️ Complexity increases

Route Target Format

# ASN:Value format
redirect 65001:100

# IP:Value format
redirect 192.168.1.1:100

Examples

Redirect to Scrubbing VRF

announce flow route {
    match {
        destination 100.10.0.0/24;  # Attacked network
    }
    then {
        redirect 65001:999;  # Scrubbing VRF route-target
    }
}

Workflow:

  1. Suspicious traffic matched
  2. Redirected to VRF with route-target 65001:999
  3. VRF routes traffic to scrubbing appliance
  4. Clean traffic returned to production network

Redirect Suspicious Sources

announce flow route {
    match {
        source 203.0.113.0/24;  # Suspicious network
    }
    then {
        redirect 65001:100;  # Inspection VRF
    }
}

Use case: Send traffic from suspicious sources to IDS/IPS for deep inspection.


Architecture Pattern

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Attack Traffic β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Edge Router    β”‚  FlowSpec: redirect 65001:999
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Scrubbing VRF   β”‚  Route-target 65001:999
β”‚  (VRF 999)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Scrubbing       β”‚  Analyze & clean
β”‚ Appliance       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Clean Traffic   β”‚  Return to production
β”‚ Back to Network β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Use Cases

  • Scrubbing centers - Send attack traffic for cleaning
  • IDS/IPS inspection - Deep packet inspection
  • Quarantine networks - Isolate suspicious traffic
  • Logging/analysis - Capture attack packets

Best Practices

  1. Pre-configure VRFs - VRF must exist before redirect
  2. Test redirect path - Verify traffic reaches scrubbing
  3. Return path - Ensure clean traffic gets back
  4. Monitor VRF - Check scrubbing VRF capacity

Mark (DSCP)

Remark DSCP field for QoS processing

Syntax

then {
    mark <dscp-value>;
}

Extended Community

Traffic-marking: <dscp-value>

Description

Matching packets have their DSCP field remarked to specified value.

Characteristics:

  • βœ… Packets marked for downstream QoS
  • βœ… Can be combined with other policies
  • ⚠️ Doesn't drop or rate-limit traffic
  • ⚠️ Requires downstream QoS config

DSCP Values

DSCP Name Typical Use
0 BE (Best Effort) Default
8 CS1 Low priority
10 AF11 Bulk data
12 AF12 Bulk data
14 AF13 Bulk data
26 AF31 Signaling
34 AF41 Video
46 EF Voice

Examples

Mark Attack Traffic as Low Priority

announce flow route {
    match {
        source 10.0.0.0/8;  # Attack source
    }
    then {
        mark 8;  # CS1 (low priority)
    }
}

Result: Traffic from 10.0.0.0/8 marked as low priority for QoS.


Mark Suspicious Traffic

announce flow route {
    match {
        destination-port =80;
        protocol =tcp;
        tcp-flags [ syn ];
        packet-length >1000;  # Large SYN packets (suspicious)
    }
    then {
        mark 0;  # Best effort (lowest priority)
    }
}

Result: Large SYN packets deprioritized by downstream QoS.


Use Cases

  • QoS integration - Mark for downstream handling
  • Prioritization - Deprioritize attack traffic
  • Traffic classification - Identify specific flows
  • Policy enforcement - Apply downstream policies

Best Practices

  1. Downstream QoS required - Marking alone doesn't rate-limit
  2. Consistent DSCP values - Align with existing QoS policy
  3. Combine with rate-limit - Mark + rate-limit for best control
  4. Monitor effectiveness - Verify QoS policies work

Community Tagging

Tag FlowSpec routes with BGP communities

Syntax

then {
    community [ <community> ];
}

Description

FlowSpec route itself is tagged with communities for downstream policy decisions.

Characteristics:

  • βœ… Allows policy-based filtering
  • βœ… Enables selective route acceptance
  • ⚠️ Doesn't affect matched traffic directly
  • ⚠️ Requires community-based policies

Examples

Tag FlowSpec Rule for Filtering

announce flow route {
    match {
        source 10.0.0.0/8;
    }
    then {
        discard;
        community [ 65001:666 ];  # Mark as DDoS mitigation
    }
}

Downstream routers can:

  • Accept FlowSpec routes with community 65001:666
  • Reject FlowSpec routes without this community
  • Apply different policies based on community

Tag by Attack Type

# SYN flood
announce flow route {
    match { tcp-flags [ syn ]; }
    then {
        discard;
        community [ 65001:100 ];  # SYN flood tag
    }
}

# UDP flood
announce flow route {
    match { protocol =udp; packet-length >1000; }
    then {
        discard;
        community [ 65001:200 ];  # UDP flood tag
    }
}

Use case: Track/filter FlowSpec rules by attack type.


Use Cases

  • Route filtering - Control FlowSpec propagation
  • Policy decisions - Apply different handling
  • Tracking - Identify rule types
  • Logging - Categorize mitigation actions

Combining Actions

Multiple actions can be combined in a single rule.

Example 1: Rate-Limit + Mark

announce flow route {
    match {
        source 10.0.0.0/8;
        destination-port =80;
    }
    then {
        rate-limit 10000000;  # 10 Mbps
        mark 8;               # Mark as low priority
    }
}

Result: Traffic rate-limited AND marked for downstream QoS.


Example 2: Discard + Community

announce flow route {
    match {
        source 203.0.113.0/24;
    }
    then {
        discard;
        community [ 65001:666 ];  # Tag rule
    }
}

Result: Traffic discarded, FlowSpec route tagged.


Example 3: Redirect + Community

announce flow route {
    match {
        destination 100.10.0.0/24;
    }
    then {
        redirect 65001:999;       # Send to scrubbing VRF
        community [ 65001:100 ];  # Tag as scrubbed traffic
    }
}

Result: Traffic redirected to scrubbing, rule tagged for tracking.


Extended Community Format

FlowSpec actions are BGP Extended Communities in the FlowSpec route.

Traffic-Rate (Rate-Limit)

Type: 0x8006 (traffic-rate)
Value: <rate-in-bytes-per-second>

Traffic-Action (Discard)

Type: 0x8006 (traffic-action)
Value: 0x01 (terminal-action / discard)

Redirect

Type: 0x8008 (redirect)
Value: <route-target>

Traffic-Marking (Mark DSCP)

Type: 0x8009 (traffic-marking)
Value: <dscp-value>

Router Support

Action support varies by router vendor/model.

Cisco

  • βœ… Discard
  • βœ… Rate-limit
  • βœ… Redirect
  • ⚠️ Mark (model-dependent)

Juniper

  • βœ… Discard
  • βœ… Rate-limit
  • βœ… Redirect
  • βœ… Mark

Arista

  • βœ… Discard
  • βœ… Rate-limit
  • ⚠️ Redirect (limited)
  • ⚠️ Mark (limited)

FRRouting (Open Source)

  • βœ… Discard
  • βœ… Rate-limit
  • βœ… Redirect
  • βœ… Mark

Check router documentation for specific action support.


Best Practices

1. Choose Appropriate Action

Situation Recommended Action
Known attack, high confidence discard
Suspected attack, testing rate-limit
Need analysis redirect
QoS integration mark
Gradual escalation rate-limit β†’ discard

2. Log All Actions

import logging

def announce_with_logging(rule, action):
    logging.info(f"[FLOWSPEC] Action={action} Rule={rule}")
    sys.stdout.write(rule + "\n")
    sys.stdout.flush()

rule = "announce flow route { match { source 10.0.0.0/8; } then { discard; } }"
announce_with_logging(rule, "discard")

3. Auto-Expire Rules

import threading
import time

def auto_withdraw(rule, timeout=300):
    time.sleep(timeout)
    withdraw = rule.replace('announce', 'withdraw').replace('then { discard; }', '')
    sys.stdout.write(withdraw + "\n")
    sys.stdout.flush()
    logging.info(f"[FLOWSPEC] Auto-withdrew rule after {timeout}s")

# Announce with auto-expiry
rule = "announce flow route { match { source 10.0.0.0/8; } then { discard; } }"
sys.stdout.write(rule + "\n")
sys.stdout.flush()

threading.Thread(target=auto_withdraw, args=(rule, 300)).start()

4. Monitor Impact

Track:

  • Bandwidth before/after rule
  • Number of packets matched
  • False positives (legitimate traffic blocked)
  • Attack duration

Tools:

  • Router packet counters
  • NetFlow/sFlow analysis
  • SNMP monitoring

5. Graduated Response

Escalation ladder:

# Level 1: Rate-limit (warning)
rate-limit 50000000  # 50 Mbps

# Level 2: Tighter rate-limit
rate-limit 10000000  # 10 Mbps

# Level 3: Very tight rate-limit
rate-limit 1000000   # 1 Mbps

# Level 4: Block completely
discard

Common Patterns

DDoS Mitigation - Discard

announce flow route {
    match {
        source 10.0.0.0/8;
        destination-port =80;
        tcp-flags [ syn ];
    }
    then {
        discard;
    }
}

DDoS Mitigation - Rate-Limit

announce flow route {
    match {
        destination 100.10.0.100/32;
        destination-port =53;
        protocol =udp;
    }
    then {
        rate-limit 10000000;  # 10 Mbps
    }
}

Traffic Scrubbing - Redirect

announce flow route {
    match {
        destination 100.10.0.0/24;
    }
    then {
        redirect 65001:999;  # Scrubbing VRF
    }
}

QoS Integration - Mark

announce flow route {
    match {
        source 10.0.0.0/8;
    }
    then {
        mark 8;  # Low priority
    }
}

Combined: Rate-Limit + Mark

announce flow route {
    match {
        protocol =udp;
        packet-length >1000;
    }
    then {
        rate-limit 10000000;
        mark 0;  # Best effort
    }
}

Next Steps

Learn More

API Reference

Examples


Ready to implement DDoS mitigation? See DDoS Mitigation Guide β†’


πŸ‘» Ghost written by Claude (Anthropic AI)

Clone this wiki locally