Bird2 as FlowSpec Controller (Part 1)

The last days i spent several hours to try Bird2 as FlowSpec Controller and hopefully the post helps others to avoid some of my challenges.

First what means Client/Controller in an FlowSpec environment?

  • A FlowSpec Controller is able to create FlowSpec Rules and Actions and announce them via BGP to Clients.
  • A FlowSpec Client is an BGP Listener which receives the FlowSpec Rules and execute the corresponding actions. One of the advantages of proper FlowSpec Clients are, that the actions don't need more implementations on the Client side (don't need to write drop ACLs/Firewall Rules for an discard action).

Info: the following information belongs to Bird 2.0.2, 06/2018:

Bird2 is capable to announce FlowSpec Rules and receive them, 
currently there is no implementation to act on actions in the 
Rules (maybe on your own with scripts/cron/birdc).

So Bird2 acts best as Controller or reflecting FlowSpec Rules.

Implementing Bird2 as FlowSpec Controller is very easy, you need some flowspec tables, a static protocol and some configuration on the BGP Peering. The following example will discard all packets from 198.51.100.10 to 203.0.113.53:

flow4 table flowtab4;

# RFC 5575 flow specification
protocol static flowstat4 {
    flow4;

    route flow4 {
            src 198.51.100.10/32;
            dst 203.0.113.53/32;
    } {
            bgp_ext_community.add( (generic, 0x80060000, 0x0 ) );
    };
}

And in the Peering Configuration you need to add a FlowSpec Channel:

protocol bgp XYZ {

    # IPv4 Flowspec (1/133)
    flow4 {
            # connects to flowtab4 table by default
            import all;
            export all;
    };

}

On an cisco ASR-1002 with IOS-XE 3.16 the config snippets are really, really simple, the first one will ensure, that the flowspec actions will be executed on every interface of the router:

!
flowspec
 address-family ipv4
  local-install interface-all
!

Additional add flowspec afi to your bgp config:

!
router bgp 65000
[...]
 !
 address-family ipv4 flowspec
  neighbor <bird2-neighbor-ip> activate
 exit-address-family
 !    
[...]
!

You can see the flowspec rules and action with the following command on the ASR:

ASR-1002#show flowspec ipv4 detail
AFI: IPv4
  Flow           :Dest:203.0.113.53/32,Source:198.51.100.10/32
    Actions      :Traffic-rate: 0 bps  (bgp.1)
    Statistics                        (packets/bytes)
      Matched             :                   0/0                  
      Dropped             :                   0/0

That was the easy part, now we want change the above rule to do rate-limiting on the flow to 50 mbit/s. And there the struggling begins, how should the rate limit be encoded in the community?

After several tries and a second brain, it comes to the following:

50 / 8 == 6.25 MByte/s
6.25 * 1024 * 1024 == 6553600 Bytes/s

Convert them to Float IEEE754 ( use some online tools, e.g.: http://www.binaryconvert.com/convert_float.html or python2 see below):

FloatIEEE754(6250000) == 0x4ac80000

You can also use a python one liner to do the calculation/conversion:

python2 -c 'import struct; print "%#x" % struct.unpack("I", struct.pack("f", (((50.0 / 8) *1024) *1024) ))'.

After this conversion the static protocol entry would look like:

flow4 table flowtab4;

# RFC 5575 flow specification
protocol static flowstat4 {
    flow4;

    route flow4 {
            src 198.51.100.10/32;
            dst 203.0.113.53/32;
    } {
            bgp_ext_community.add( (generic, 0x80060000, 0x4ac80000 ) );
    };

}

On the cisco side you will see the following now:

ASR-1002#sh flowspec ipv4 detail 
AFI: IPv4
  Flow           :Dest:203.0.113.53/32,Source:198.51.100.10/32
    Actions      :Traffic-rate: 52428800 bps  (bgp.1)
    Statistics                        (packets/bytes)
      Matched             :                   0/0                  
      Dropped             :                   0/0

The traffic rate should be equivalent for: 52428800 / 1024 / 1024 == 50 mbit/s.

The next part will be explaining other actions which can be used with FlowSpec. Stay tuned!