1.. _flowspec: 2 3Flowspec 4======== 5 6.. _features-of-the-current-implementation-flowspec: 7 8Overview 9--------- 10 11Flowspec introduces a new :abbr:`NLRI (Network Layer Reachability Information)` 12encoding format that is used to distribute traffic rule flow specifications. 13Basically, instead of simply relying on destination IP address for IP prefixes, 14the IP prefix is replaced by a n-tuple consisting of a rule. That rule can be a 15more or less complex combination of the following: 16 17 18- Network source/destination (can be one or the other, or both). 19- Layer 4 information for UDP/TCP: source port, destination port, or any port. 20- Layer 4 information for ICMP type and ICMP code. 21- Layer 4 information for TCP Flags. 22- Layer 3 information: DSCP value, Protocol type, packet length, fragmentation. 23- Misc layer 4 TCP flags. 24 25Note that if originally Flowspec defined IPv4 rules, this is also possible to use 26IPv6 address-family. The same set of combinations as defined for IPv4 can be used. 27 28A combination of the above rules is applied for traffic filtering. This is 29encoded as part of specific BGP extended communities and the action can range 30from the obvious rerouting (to nexthop or to separate VRF) to shaping, or 31discard. 32 33The following IETF drafts and RFCs have been used to implement FRR Flowspec: 34 35- :rfc:`5575` 36- [Draft-IETF-IDR-Flowspec-redirect-IP]_ 37- [Draft-IETF-IDR-Flow-Spec-V6]_ 38 39.. _design-principles-flowspec: 40 41Design Principles 42----------------- 43 44FRR implements the Flowspec client side, that is to say that BGP is able to 45receive Flowspec entries, but is not able to act as manager and send Flowspec 46entries. 47 48Linux provides the following mechanisms to implement policy based routing: 49 50- Filtering the traffic with ``Netfilter``. 51 ``Netfilter`` provides a set of tools like ``ipset`` and ``iptables`` that are 52 powerful enough to be able to filter such Flowspec filter rule. 53 54- using non standard routing tables via ``iproute2`` (via the ``ip rule`` 55 command provided by ``iproute2``). 56 ``iproute2`` is already used by FRR's :ref:`pbr` daemon which provides basic 57 policy based routing based on IP source and destination criterion. 58 59Below example is an illustration of what Flowspec will inject in the underlying 60system: 61 62.. code-block:: shell 63 64 # linux shell 65 ipset create match0x102 hash:net,net counters 66 ipset add match0x102 32.0.0.0/16,40.0.0.0/16 67 iptables -N match0x102 -t mangle 68 iptables -A match0x102 -t mangle -j MARK --set-mark 102 69 iptables -A match0x102 -t mangle -j ACCEPT 70 iptables -i ntfp3 -t mangle -I PREROUTING -m set --match-set match0x102 71 src,dst -g match0x102 72 ip rule add fwmark 102 lookup 102 73 ip route add 40.0.0.0/16 via 44.0.0.2 table 102 74 75For handling an incoming Flowspec entry, the following workflow is applied: 76 77- Incoming Flowspec entries are handled by *bgpd*, stored in the BGP RIB. 78- Flowspec entry is installed according to its complexity. 79 80It will be installed if one of the following filtering action is seen on the 81BGP extended community: either redirect IP, or redirect VRF, in conjunction 82with rate option, for redirecting traffic. Or rate option set to 0, for 83discarding traffic. 84 85According to the degree of complexity of the Flowspec entry, it will be 86installed in *zebra* RIB. For more information about what is supported in the 87FRR implementation as rule, see :ref:`flowspec-known-issues` chapter. Flowspec 88entry is split in several parts before being sent to *zebra*. 89 90- *zebra* daemon receives the policy routing configuration 91 92Policy Based Routing entities necessary to policy route the traffic in the 93underlying system, are received by *zebra*. Two filtering contexts will be 94created or appended in ``Netfilter``: ``ipset`` and ``iptable`` context. The 95former is used to define an IP filter based on multiple criterium. For 96instance, an ipset ``net:net`` is based on two ip addresses, while 97``net,port,net`` is based on two ip addresses and one port (for ICMP, UDP, or 98TCP). The way the filtering is used (for example, is src port or dst port 99used?) is defined by the latter filtering context. ``iptable`` command will 100reference the ``ipset`` context and will tell how to filter and what to do. In 101our case, a marker will be set to indicate ``iproute2`` where to forward the 102traffic to. Sometimes, for dropping action, there is no need to add a marker; 103the ``iptable`` will tell to drop all packets matching the ``ipset`` entry. 104 105Configuration Guide 106------------------- 107 108In order to configure an IPv4 Flowspec engine, use the following configuration. 109As of today, it is only possible to configure Flowspec on the default VRF. 110 111.. code-block:: frr 112 113 router bgp <AS> 114 neighbor <A.B.C.D> remote-as <remoteAS> 115 neighbor <A:B::C:D> remote-as <remoteAS2> 116 address-family ipv4 flowspec 117 neighbor <A.B.C.D> activate 118 exit 119 address-family ipv6 flowspec 120 neighbor <A:B::C:D> activate 121 exit 122 exit 123 124You can see Flowspec entries, by using one of the following show commands: 125 126.. index:: show bgp ipv4 flowspec [detail | A.B.C.D] 127.. clicmd:: show bgp ipv4 flowspec [detail | A.B.C.D] 128 129.. index:: show bgp ipv6 flowspec [detail | A:B::C:D] 130.. clicmd:: show bgp ipv6 flowspec [detail | A:B::C:D] 131 132Per-interface configuration 133^^^^^^^^^^^^^^^^^^^^^^^^^^^ 134 135One nice feature to use is the ability to apply Flowspec to a specific 136interface, instead of applying it to the whole machine. Despite the following 137IETF draft [Draft-IETF-IDR-Flowspec-Interface-Set]_ is not implemented, it is 138possible to manually limit Flowspec application to some incoming interfaces. 139Actually, not using it can result to some unexpected behaviour like accounting 140twice the traffic, or slow down the traffic (filtering costs). To limit 141Flowspec to one specific interface, use the following command, under 142`flowspec address-family` node. 143 144.. index:: [no] local-install <IFNAME | any> 145.. clicmd:: [no] local-install <IFNAME | any> 146 147By default, Flowspec is activated on all interfaces. Installing it to a named 148interface will result in allowing only this interface. Conversely, enabling any 149interface will flush all previously configured interfaces. 150 151VRF redirection 152^^^^^^^^^^^^^^^ 153 154Another nice feature to configure is the ability to redirect traffic to a 155separate VRF. This feature does not go against the ability to configure 156Flowspec only on default VRF. Actually, when you receive incoming BGP flowspec 157entries on that default VRF, you can redirect traffic to an other VRF. 158 159As a reminder, BGP flowspec entries have a BGP extended community that contains 160a Route Target. Finding out a local VRF based on Route Target consists in the 161following: 162 163- A configuration of each VRF must be done, with its Route Target set 164 Each VRF is being configured within a BGP VRF instance with its own Route 165 Target list. Route Target accepted format matches the following: 166 ``A.B.C.D:U16``, or ``U16:U32``, ``U32:U16``. 167 168- The first VRF with the matching Route Target will be selected to route traffic 169 to. Use the following command under ipv4 unicast address-family node 170 171.. index:: [no] rt redirect import RTLIST... 172.. clicmd:: [no] rt redirect import RTLIST... 173 174In order to illustrate, if the Route Target configured in the Flowspec entry is 175``E.F.G.H:II``, then a BGP VRF instance with the same Route Target will be set 176set. That VRF will then be selected. The below full configuration example 177depicts how Route Targets are configured and how VRFs and cross VRF 178configuration is done. Note that the VRF are mapped on Linux Network 179Namespaces. For data traffic to cross VRF boundaries, virtual ethernet 180interfaces are created with private IP addressing scheme. 181 182.. code-block:: frr 183 184 router bgp <ASx> 185 neighbor <A.B.C.D> remote-as <ASz> 186 address-family ipv4 flowspec 187 neighbor A.B.C.D activate 188 exit 189 exit 190 router bgp <ASy> vrf vrf2 191 address-family ipv4 unicast 192 rt redirect import <E.F.G.H:II> 193 exit 194 exit 195 196Similarly, it is possible to do the same for IPv6 flowspec rules, by using 197an IPv6 extended community. The format is defined on :rfc:`5701`, and that 198community contains an IPv6 address encoded in the attribute, and matches the 199locally configured imported route target IPv6 defined under the appropriate 200BGP VRF instance. Below example defines an IPv6 extended community containing 201`E:F::G:H` address followed by 2 bytes chosen by admin ( here `JJ`). 202 203.. code-block:: frr 204 205 router bgp <ASx> 206 neighbor <A:B::C:D> remote-as <ASz> 207 address-family ipv6 flowspec 208 neighbor A:B::C:D activate 209 exit 210 exit 211 router bgp <ASy> vrf vrf2 212 address-family ipv6 unicast 213 rt6 redirect import <E:F::G:H:JJ> 214 exit 215 exit 216 217 218Flowspec monitoring & troubleshooting 219^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 220 221You can monitor policy-routing objects by using one of the following commands. 222Those command rely on the filtering contexts configured from BGP, and get the 223statistics information retrieved from the underlying system. In other words, 224those statistics are retrieved from ``Netfilter``. 225 226.. index:: show pbr ipset IPSETNAME | iptable 227.. clicmd:: show pbr ipset IPSETNAME | iptable 228 229``IPSETNAME`` is the policy routing object name created by ``ipset``. About 230rule contexts, it is possible to know which rule has been configured to 231policy-route some specific traffic. The :clicmd:`show pbr iptable` command 232displays for forwarded traffic, which table is used. Then it is easy to use 233that table identifier to dump the routing table that the forwarded traffic will 234match. 235 236.. code-block:: frr 237 238.. index:: show ip route table TABLEID 239.. clicmd:: show ip route table TABLEID 240 241 ``TABLEID`` is the table number identifier referencing the non standard 242 routing table used in this example. 243 244.. index:: [no] debug bgp flowspec 245.. clicmd:: [no] debug bgp flowspec 246 247 You can troubleshoot Flowspec, or BGP policy based routing. For instance, if 248 you encounter some issues when decoding a Flowspec entry, you should enable 249 :clicmd:`debug bgp flowspec`. 250 251.. index:: [no] debug bgp pbr [error] 252.. clicmd:: [no] debug bgp pbr [error] 253 254 If you fail to apply the flowspec entry into *zebra*, there should be some 255 relationship with policy routing mechanism. Here, 256 :clicmd:`debug bgp pbr error` could help. 257 258 To get information about policy routing contexts created/removed, only use 259 :clicmd:`debug bgp pbr` command. 260 261Ensuring that a Flowspec entry has been correctly installed and that incoming 262traffic is policy-routed correctly can be checked as demonstrated below. First 263of all, you must check whether the Flowspec entry has been installed or not. 264 265.. code-block:: frr 266 267 CLI# show bgp ipv4 flowspec 5.5.5.2/32 268 BGP flowspec entry: (flags 0x418) 269 Destination Address 5.5.5.2/32 270 IP Protocol = 17 271 Destination Port >= 50 , <= 90 272 FS:redirect VRF RT:255.255.255.255:255 273 received for 18:41:37 274 installed in PBR (match0x271ce00) 275 276This means that the Flowspec entry has been installed in an ``iptable`` named 277``match0x271ce00``. Once you have confirmation it is installed, you can check 278whether you find the associate entry by executing following command. You can 279also check whether incoming traffic has been matched by looking at counter 280line. 281 282.. code-block:: frr 283 284 CLI# show pbr ipset match0x271ce00 285 IPset match0x271ce00 type net,port 286 to 5.5.5.0/24:proto 6:80-120 (8) 287 pkts 1000, bytes 1000000 288 to 5.5.5.2:proto 17:50-90 (5) 289 pkts 1692918, bytes 157441374 290 291As you can see, the entry is present. note that an ``iptable`` entry can be 292used to host several Flowspec entries. In order to know where the matching 293traffic is redirected to, you have to look at the policy routing rules. The 294policy-routing is done by forwarding traffic to a routing table number. That 295routing table number is reached by using a ``iptable``. The relationship 296between the routing table number and the incoming traffic is a ``MARKER`` that 297is set by the IPtable referencing the IPSet. In Flowspec case, ``iptable`` 298referencing the ``ipset`` context have the same name. So it is easy to know 299which routing table is used by issuing following command: 300 301.. code-block:: frr 302 303 CLI# show pbr iptable 304 IPtable match0x271ce00 action redirect (5) 305 pkts 1700000, bytes 158000000 306 table 257, fwmark 257 307 ... 308 309As you can see, by using following Linux commands, the MARKER ``0x101`` is 310present in both ``iptable`` and ``ip rule`` contexts. 311 312.. code-block:: shell 313 314 # iptables -t mangle --list match0x271ce00 -v 315 Chain match0x271ce00 (1 references) 316 pkts bytes target prot opt in out source destination 317 1700K 158M MARK all -- any any anywhere anywhere 318 MARK set 0x101 319 1700K 158M ACCEPT all -- any any anywhere anywhere 320 321 # ip rule list 322 0:from all lookup local 323 0:from all fwmark 0x101 lookup 257 324 32766:from all lookup main 325 32767:from all lookup default 326 327This allows us to see where the traffic is forwarded to. 328 329.. _flowspec-known-issues: 330 331Limitations / Known Issues 332-------------------------- 333 334As you can see, Flowspec is rich and can be very complex. As of today, not all 335Flowspec rules will be able to be converted into Policy Based Routing actions. 336 337- The ``Netfilter`` driver is not integrated into FRR yet. Not having this 338 piece of code prevents from injecting flowspec entries into the underlying 339 system. 340 341- There are some limitations around filtering contexts 342 343 If I take example of UDP ports, or TCP ports in Flowspec, the information 344 can be a range of ports, or a unique value. This case is handled. 345 However, complexity can be increased, if the flow is a combination of a list 346 of range of ports and an enumerate of unique values. Here this case is not 347 handled. Similarly, it is not possible to create a filter for both src port 348 and dst port. For instance, filter on src port from [1-1000] and dst port = 349 80. The same kind of complexity is not possible for packet length, ICMP type, 350 ICMP code. 351 352There are some other known issues: 353 354- The validation procedure depicted in :rfc:`5575` is not available. 355 356 This validation procedure has not been implemented, as this feature was not 357 used in the existing setups you shared with us. 358 359- The filtering action shaper value, if positive, is not used to apply shaping. 360 361 If value is positive, the traffic is redirected to the wished destination, 362 without any other action configured by Flowspec. 363 It is recommended to configure Quality of Service if needed, more globally on 364 a per interface basis. 365 366- Upon an unexpected crash or other event, *zebra* may not have time to flush 367 PBR contexts. 368 369 That is to say ``ipset``, ``iptable`` and ``ip rule`` contexts. This is also a 370 consequence due to the fact that ip rule / ipset / iptables are not discovered 371 at startup (not able to read appropriate contexts coming from Flowspec). 372 373Appendix 374-------- 375 376More information with a public presentation that explains the design of Flowspec 377inside FRRouting. 378 379[Presentation]_ 380 381.. [Draft-IETF-IDR-Flowspec-redirect-IP] <https://tools.ietf.org/id/draft-ietf-idr-flowspec-redirect-ip-02.txt> 382.. [Draft-IETF-IDR-Flowspec-Interface-Set] <https://tools.ietf.org/id/draft-ietf-idr-flowspec-interfaceset-03.txt> 383.. [Draft-IETF-IDR-Flow-Spec-V6] <https://tools.ietf.org/id/draft-ietf-idr-flow-spec-v6-10.txt> 384.. [Presentation] <https://docs.google.com/presentation/d/1ekQygUAG5yvQ3wWUyrw4Wcag0LgmbW1kV02IWcU4iUg/edit#slide=id.g378f0e1b5e_1_44> 385