Routing Policies

Module Introduction

Before you start the hands-on part of this module, you should load the appropriate configuration and verify that the testbed is up and running by executing the corresponding robot file:

student@tour:~/trainings_resources/robot$ robot policies/policies_setup.robot

In order to get a better understanding, the lab setup is shown in the picture below.

policy lab
Figure 1. Policy Lab Setup

Policy Framework Overview

In general, a router uses various routing protocols (e.g., static routing, OSPF, BGP, …​) to learn about possible destinations. Depending on the routing protocols in use, it chooses the best (shortest) path based on protocol specific algorithms and stores it in its routing table. If multiple routing protocols are used in parallel, the router prefers routes from protocols with numerical lower route preference. Finally, the router than installs the active path into the forwarding table which is used to forward packets out the proper interface. In addition, those active paths will be sent to the corresponding protocol neighbors to help other routers building an end-to-end path.

Routing policies are control plane mechanisms that can modify the routers default route selection behavior. The goal of using routing policies is to optimize the traffic flow based on parameters other than shortest path, e.g., network utilization or business advantages like financial costs. Key aspects of routing policies are

  • accepting or rejecting routes based on BGP path attributes

  • modification of BGP path attributes prior to accepting from peer or advertising to peer in order to influence routing decisions

  • redistribution of routes into routing protocols, e.g., static routes

In RBFS, a routing policy is defined by a policy statement which is composed of one or more blocks called ordinals that are daisy-chained and evaluated step-by-step. Each ordinal consists of a set of match rules and a set of actions rules.

policy statement
Figure 2. Policy Statement Components

A route is evaluated in each ordinal until a match is found. In case of a match, the corresponding actions will be executed. If there is no match, the action block will not be executed, and the next ordinal will be processed.

If there an empty match block, it is assumed that all routes match and the action block will be executed.

The action block can contain one or more action rules. An action rule can be either a modifying action, i.e., changing certain parameters associated with the route, or a terminating action, i.e., allowing or rejecting the route.

The action block is optional. The implicit default action is deny. However, it is best practice to configure a deny action explicitly to avoid confusion.

Action rules are evaluated step-by-step. Modifying action rules must be in front of the terminating action in order to get executed. If no ordinal exists and if the policy is used, then all routes or objects will be denied.

First BGP Policy

The policy framework is generic and can serve multiple purposes and applications. Because the most common use case is control of routing updates in BGP, we will focus on BGP in this module. As BGP policies can get very complex, it is the best way to understand the concept of routing policies through some examples. Therefore, we will go through the process of creating a very simple BGP import policy step-by-step.

BGP routing policies have two main attachment points: as import policies and as export policies. The following figure provides a short summary of the BGP route evaluation process for instance default and IPv4 unicast address-family:

bgp policy processing
Figure 3. BGP Policy Processing in RBFS

The routing table has two equally good paths to certain prefixes. In this section we will pick two specific prefixes for demonstration: 172.16.104.0/27 and 172.16.104.32/29.

We already know that the most significant BGP attribute in the route selection process is the BGP Local Preference attribute. The BGP FIB reveals the Local Preference value for the considered prefixes:

cfg> show bgp fib ipv4 unicast 172.16.104.0/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.0/27
    Next hop key: 82ec1322c525cdfa8d5877afc1392b7275b94810cfcbd52b
    Peer: None, Peer domain: None
    Route source: bgp, Send path ID: 130982003, Received path ID: None, Path hash: None
    As path: 65002, 65004, Originator ID: None, Origin: Incomplete
    Community: ['102:2']
    Extended community: None
    Large community: None
    Cluster list: None
    IGP metric: 4294967295, Local preference: None, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.6, Label -
    Next hop:
      172.16.0.2, Label -
cfg> show bgp fib ipv4 unicast 172.16.104.32/29
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.32/29
    Next hop key: 82ec1322c525cdfa8d5877afc1392b7275b94810cfcbd52b
    Peer: None, Peer domain: None
    Route source: bgp, Send path ID: 130982003, Received path ID: None, Path hash: None
    As path: 65002, 65004, Originator ID: None, Origin: Incomplete
    Community: ['102:2']
    Extended community: None
    Large community: None
    Cluster list: None
    IGP metric: 4294967295, Local preference: None, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.6, Label -
    Next hop:
      172.16.0.2, Label -

Note, that for both prefixes under consideration no local preference value is set and two different nexthops (R2 and R3) exist.

We will now implement a simple policy statement consisting of one ordinal. The match rule is only executed for prefix 172.16.104.0/27. The value-type discrete refers to a single value instead of a list of prefixes. The match-type exact indicates that we want to exactly match the given prefix. It is also possible to build more complex matches with regular expressions or prefix-lengths which we will cover later.

cfg> set policy statement ISP2_IN ordinal 10 match rule 1 type ipv4-prefix
cfg> set policy statement ISP2_IN ordinal 10 match rule 1 value-type discrete
cfg> set policy statement ISP2_IN ordinal 10 match rule 1 match-type exact
cfg> set policy statement ISP2_IN ordinal 10 match rule 1 value 172.16.104.0/27
cfg> commit

The action block consists of two rules. The first rule will set the local preference value to 200. The second rule will accept the prefix. Remember, the implicit default action is deny.

cfg> set policy statement ISP2_IN ordinal 10 action rule 1 type local-preference
cfg> set policy statement ISP2_IN ordinal 10 action rule 1 operation overwrite
cfg> set policy statement ISP2_IN ordinal 10 action rule 1 value 200
cfg> set policy statement ISP2_IN ordinal 10 action rule 2 operation return-permit
cfg> commit

A routing policy by itself does nothing. You can configure as many routing policy statements as you like without changing the behavior of the system. In order to get it working, we need to apply the policy statement to an attachment point, i.e., we need to specify which protocol, address-family, neighbor, etc. should be controlled by this policy statement. In our example, we want to execute it on all IPv4 routes that are learned from BGP peer R2, so we modify the peer-group:

cfg> set instance default protocol bgp peer-group ISP2 address-family ipv4 unicast policy import ISP2_IN
cfg> commit

In BGP, policies are attached at the peer-group level. In addition, you need to specify which address-family the policy should operate on and whether it is an import policy controlling BGP updates received from another peer or an export policy controlling BGP updates sent out to another peer.

In addition, route policy statements can be used to control which routes are redistributed into BGP.

Now, let’s have look at the result:

cfg> show bgp fib ipv4 unicast 172.16.104.0/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.0/27
    Next hop key: 784ac3ae40014c2e2ebf604130c8aec71ed35515f5aa7499
    Peer: None, Peer domain: None
    Route source: bgp, Send path ID: 130982003, Received path ID: None, Path hash: None
    As path: 65002, 65004, Originator ID: None, Origin: Incomplete
    Community: ['102:2']
    Extended community: None
    Large community: None
    Cluster list: None
    IGP metric: 4294967295, Local preference: 200, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.2, Label -

From the output of prefix 172.16.24.0/27 we can see, that two things have changed after applying the policy statement: The local preference value is now set to 200 and the nexthop is updated to R2 only, because now R2 has a better local preference than R3 and the paths are no longer considered equally good for multipath. Great!

What about your second test prefix. As it is not part of our policy, it should be unchanged:

cfg> show bgp fib ipv4 unicast 172.16.104.32/29
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.32/29
    Next hop key: 1a3e19c2c2e845b1e8d8578d43f6a9f86356ca8c964f4a6a
    Peer: None, Peer domain: None
    Route source: bgp, Send path ID: 198092479, Received path ID: None, Path hash: None
    As path: 65003, 65004, Originator ID: None, Origin: Incomplete
    Community: ['103:3']
    Extended community: None
    Large community: None
    Cluster list: None
    IGP metric: 4294967295, Local preference: None, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.6, Label -

Oops! There is still no local preference set, but the list of nexthops only contains R3. The path to R2 has been removed. The reason is that there is no rule in our policy matching 172.16.104.32/29 and the default behavior is to reject everything that is not explicitly allowed. In order to fix this problem, we need to add another ordinal:

cfg> set policy statement ISP2_IN ordinal 90
cfg> set policy statement ISP2_IN ordinal 90 action
cfg> set policy statement ISP2_IN ordinal 90 action rule 1
cfg> set policy statement ISP2_IN ordinal 90 action rule 1 operation return-permit
cfg> commit
Exercise 1: Review and Verify Example Configuration

If you haven’t done yet, go through the steps of this example and configure them on your node. Verify that for both routes under consideration (172.16.104.0/27 and 172.16.104.32/29) the result is as expected.

Examine the BGP RIB-In for R2 on your router for those two prefixes. Does the local preference value meet your expectations?

Click to reveal the answer
cfg> show bgp rib-in ipv4 unicast peer R2 172.16.104.0/27
Instance: default, AFI: ipv4, SAFI: unicast
  Peer: R2, Received routes: 1
    172.16.104.0/27, Received path ID: 0, Next hop: 172.16.0.2
      Status: Policy Deny
      Protocol source: bgp, Send path ID: 130982003
      AS path: 65002, 65004
      MED: 0, Local preference: -
      Community: ['102:2']
      Extended community: -
      Large community: -
      Originator ID: -
      Cluster list: -
      Label: -, Last update: 0d:00h:23m:55s

Note, that the local preference value for 172.16.104.0/27 is not set in the BGP RIB-In. The RIB-In reflects the routes with the parameters learned from the BGP peer. The import policy evaluation happens afterwards.

Exercise 2: Redistribution Policy

Currently all direct routes (i.e., connected interfaces) are redistributed into BGP. Write a policy that only accepts the loopback-0/0/0/0 interface address and apply it as a redistribution policy. Verify that no routes for the hostif-0/0/1/0 and hostif-0/0/2/0 are sent to peers R2 and R3.

Click to reveal the answer

The current configuration contains a statement set instance default protocol bgp address-family ipv4 unicast redistribute direct which redistributes all interface routes into bgp:

cfg> show route ipv4 unicast source direct
Instance: default, AFI: ipv4, SAFI: unicast
Prefix/Label              Source         Pref    Next Hop             Interface
172.16.0.1/32             direct         0       172.16.0.1           hostif-0/0/1/0
172.16.0.0/30             direct         0       172.16.0.0           hostif-0/0/1/0
172.16.0.5/32             direct         0       172.16.0.5           hostif-0/0/2/0
172.16.0.4/30             direct         0       172.16.0.4           hostif-0/0/2/0
192.168.0.1/32            direct         0       192.168.0.1          lo-0/0/0/0

We introduce a redistribution policy which only accepts the IP address of the loopback interface and apply it:

cfg> set policy statement LOOP_v4_ONLY ordinal 10 match rule 1 type ipv4-prefix
cfg> set policy statement LOOP_v4_ONLY ordinal 10 match rule 1 value-type discrete
cfg> set policy statement LOOP_v4_ONLY ordinal 10 match rule 1 match-type exact
cfg> set policy statement LOOP_v4_ONLY ordinal 10 match rule 1 value 192.168.0.1/32
cfg> set policy statement LOOP_v4_ONLY ordinal 10 action rule 1 operation return-permit
cfg> set instance default protocol bgp address-family ipv4 unicast redistribute direct policy LOOP_v4_ONLY
cfg> commit

You can easily check with show bgp rib-out that routes for hostif-0/0/1/0 and hostif-0/0/2/0 are no longer advertised.

Policy Action Rules

Now that we have seen a very simple policy example, let’s explorer some more details on the policy actions. The general syntax of an action rule is given by the syntax

set policy statement <policy-name> ordinal <ordinal> action rule <rule> <attribute> <value>

There are three well-known attributes possible:

  • operation <operation-type>

  • type <attribute-type>

  • value <value>

The type and value attribute depend on the routing protocol in use. For IGP protocols (like OSPF and IS-IS) the igp-metric type is the most common one. For BGP, the types local-preference, med, community, large-community and extended-community are regularly used. For a full list of attribute types and supported operation types, please have look at the Policy Configuration.

The operation can be either a terminating or flow control operation or an operation that modifies a route attribute or metric. There are two terminating operations and one flow control operation:

  • operation return-deny: stops policy evaluation and rejects the corresponding routes

  • operation return-permit: stops policy evaluation and accepts the corresponding routes

  • operation goto-next-ordinal: no final decision is taken and policy evaluation continues with the next ordinal

With terminating or flow control operations, there is no additional type or value attribute associated.

In addition, there are a couple of modifying operations, e.g.

  • operation add|substract|multiply|divide which allows to change the numeric value of a route metric with fundamental arithmetic operations, e.g., BGP Local Preference value

  • operation prepend|append which allows to add another entry to the beginning or the end of a list of metrics, e.g., BGP AS_PATH list

  • operation override which replaces the value of a given metric with another value.

  • operation delete-attribute which removes the corresponding metric from the route object

Exercise 3: Community Modification

R2 of ISP2 is sending route updates with BGP community attributes attached. Please modify the existing ISP2_IN policy to remove all communities from all received routes. Verify your result.

Click to reveal the answer

In this exercise, there are two aspects to consider. First of all, as all received routes should be modified, the new ordinal must be executed as the first ordinal, i.e., we need to choose an ordinal number below 10. Second, as there are additional rules following, this ordinal cannot be accepted or rejected but needs to pass the decision to the subsequent ordinals.

cfg> set policy statement ISP2_IN ordinal 1 action rule 1 type community
cfg> set policy statement ISP2_IN ordinal 1 action rule 1 operation delete-attribute
cfg> set policy statement ISP2_IN ordinal 1 action rule 2 operation goto-next-ordinal
cfg> commit
cfg> show bgp fib ipv4 unicast 172.16.104.0/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.0/27
    Next hop key: 784ac3ae40014c2e2ebf604130c8aec71ed35515f5aa7499
    Peer: None, Peer domain: None
    Route source: bgp, Send path ID: 130982003, Received path ID: None, Path hash: None
    As path: 65002, 65004, Originator ID: None, Origin: Incomplete
    Community: None
    Extended community: None
    Large community: None
    Cluster list: None
    IGP metric: 4294967295, Local preference: 200, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.2, Label -

If you want to steer incoming traffic into your autonomous system, you need to adjust BGP path attributes on the routes that you advertise to your neighboring peers. Looking at the BGP route selection process and bearing in mind, that local preference is an attribute only advertised to internal peers, the most common attributes to steer incoming traffic are the AS_PATH and the multi-exit discriminator (MED). As the MED can easily be overwritten easily by subsequent routers, prolonging the AS_PATH is a very popular mechanism.

Exercise 4: AS_PATH Modification

We want to receive traffic from AS65004 via R2, i.e., we need to make the path via R3. Write an export policy ISP3_OUT and apply it to R3. The policy should add your own AS number (65001) once more to the AS_PATH.

Click to reveal the answer

Let’s check the RIB-OUT before configuring the new policy:

cfg> show bgp rib-out ipv4 unicast peer R3
Instance: default, AFI: ipv4, SAFI: unicast
  Peer: R3, Sent routes: 29
    Prefix                 MED    Local Preference  Origin       Next Hop         AS Path
    172.16.101.0/28        0      -                 Incomplete   -                65001
    172.16.102.0/27        0      -                 Incomplete   -                65001, 65002
    172.16.103.0/27        0      -                 Incomplete   -                65001, 65003
    <...>

Now we need a policy that prepends the AS_PATH with ASN 65001:

cfg> set policy statement ISP3_OUT ordinal 10 action rule 1 type as-path
cfg> set policy statement ISP3_OUT ordinal 10 action rule 1 operation prepend
cfg> set policy statement ISP3_OUT ordinal 10 action rule 1 value 65001
cfg> set policy statement ISP3_OUT ordinal 10 action rule 2 operation return-permit
cfg> set instance default protocol bgp peer-group ISP3 address-family ipv4 unicast policy export ISP3_OUT
cfg> commit
cfg> show bgp rib-out ipv4 unicast peer R3
Instance: default, AFI: ipv4, SAFI: unicast
  Peer: R3, Sent routes: 29
    Prefix                    MED       Local Preference  Origin          Next Hop                            AS Path
    172.16.101.0/28           0         -                 Incomplete      -                                   65001, 65001
    172.16.102.0/27           0         -                 Incomplete      -                                   65001, 65001, 65002
    172.16.103.0/27           0         -                 Incomplete      -                                   65001, 65001, 65003
    <...>

As the AS_PATH attribute is a list of AS number, you need to use the operation prepend to add an additional AS number to the list. The operation add only works on numerical attributes.

AS_PATH is an ordered list describing the path through a sequence of autonomous systems. You can’t use the append operation because it adds the AS number on the wrong end of the list!

Policy Match Rules

The general syntax of a match rule is given by the syntax

set policy statement <policy-name> ordinal <ordinal> match rule <rule> <attribute> <value>

There are four attribute/value pairs that are all mandatory:

  • type specifies the kind of metric which should be matched, e.g., ipv4-prefix, as-path, community, etc.

  • match-type defines how the value should match the attribute type. The most frequent one is exact, but there is also support for various prefix-length matches as well as regular expressions (regex).

  • value-type indicates whether the given match value is either a single value (discrete) or a list of values.

  • value defines the attribute value.

For a full list of attribute types and supported match types please refer to the Policy User Guide.

Match-Type longer and or-longer

In our first example we used the match-type exact to filter the prefix 172.16.104.0/27 and nothing else. More often than not you need to deal with large routing tables and you want to filter on a network range including its subnets but you may not know which subnets are advertised. In this case the match-type longer (only the subnets) and or-longer (network and all subnets) are useful.

policy longer
Figure 4. Prefix Match Type
Exercise 5: Prefix Matching

Write a new policy ISP3_IN and apply it to peer R3. The policy should reject the 172.16.104.0/24 route including all its subnets. All other prefixes received from R3 should be unchanged.

Click to reveal the answer

First, we choose prefix 172.16.104.64/27 as an indicator of successful configuration. Before applying a new policy, the prefix is learned via R2 and R3:

cfg> show bgp fib ipv4 unicast 172.16.104.64/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.64/27
    <...>
    Next hop:
      172.16.0.6, Label -
    Next hop:
      172.16.0.2, Label -

Now we configure a policy with two ordinal and make use of the or-longer option:

cfg> set policy statement ISP3_IN ordinal 10 match rule 1 type ipv4-prefix
cfg> set policy statement ISP3_IN ordinal 10 match rule 1 value-type discrete
cfg> set policy statement ISP3_IN ordinal 10 match rule 1 match-type or-longer
cfg> set policy statement ISP3_IN ordinal 10 match rule 1 value 172.16.104.0/24
cfg> set policy statement ISP3_IN ordinal 10 action rule 1
cfg> set policy statement ISP3_IN ordinal 10 action rule 1 operation return-deny
cfg> set policy statement ISP3_IN ordinal 90
cfg> set policy statement ISP3_IN ordinal 90 action
cfg> set policy statement ISP3_IN ordinal 90 action rule 1
cfg> set policy statement ISP3_IN ordinal 90 action rule 1 operation return-permit
cfg> set instance default protocol bgp peer-group ISP3 address-family ipv4 unicast policy import ISP3_IN
cfg> commit
cfg> show bgp fib ipv4 unicast 172.16.104.64/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.64/27
  <...>
    Next hop:
      172.16.0.2, Label -

Match-Type Prefix-Length

In large-scale environments it is often difficult to keep prefix lists or match criteria based on certain prefixes up-to-date. A common scenario is that you want to accept reachability information from your neighboring peers, but do not want to accept small subnets but larger networks or aggregates. RBFS supports the match-types prefix-length-exact, prefix-length-greater and prefix-length-greater-or-exact to accomplish this task. These options allow you to filter on the prefix-length rather than the network. Therefore, only the prefix length in the value option is used!

Example: ipv4-prefix with value=0.0.0.0/24

  • prefix-length-exact matches all routes with prefix /24

  • prefix-length-greater matches all routes with prefix /25, /26, ../32

  • prefix-length-greater-or-exact matches alle routes with prefix /24, /25, ../32

0.0.0.0/24 and 10.10.10.0/24 result in the same matches as only the prefix length is considered.
Exercise 6: Prefix Length Matching

In your newly created policy ISP3_IN you recognize, that you want to accept some of the 172.16.104.0/24 subnets, but only those with prefix-length 24-27. Update your policy to reflect this.

Click to reveal the answer

Again, we take two test prefixes to check the policy. The 172.16.104.64/27 and 172.16.104.72/29 prefix are currently blocked from R3, i.e., only R2 is a next hop:

cfg> show bgp fib ipv4 unicast 172.16.104.64/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.64/27
  <...>
    Next hop:
      172.16.0.2, Label -
cfg> show bgp fib ipv4 unicast 172.16.104.72/29
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.72/29
  <...>
    Next hop:
      172.16.0.2, Label -

We modify the ordinal 10 in two ways: first we configure the match-logic to be and, so that both rules are applied, and second, we introduce a match on all prefixes equal or longer than 28:

cfg> set policy statement ISP3_IN ordinal 10 match-logic and
cfg> set policy statement ISP3_IN ordinal 10 match rule 2
cfg> set policy statement ISP3_IN ordinal 10 match rule 2 type ipv4-prefix
cfg> set policy statement ISP3_IN ordinal 10 match rule 2 value-type discrete
cfg> set policy statement ISP3_IN ordinal 10 match rule 2 match-type prefix-length-greater-or-exact
cfg> set policy statement ISP3_IN ordinal 10 match rule 2 value 0.0.0.0/28
cfg> commit
cfg> show bgp fib ipv4 unicast 172.16.104.64/27
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.64/27
  <...>
    Next hop:
      172.16.0.6, Label -
    Next hop:
      172.16.0.2, Label -
cfg> show bgp fib ipv4 unicast 172.16.104.72/29
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.72/29
    <...>
    Next hop:
      172.16.0.2, Label -

Match-Type Regular Expression

Regular expressions (short regex) are a way to define patterns which can be very useful in searching and replacing a sequence of characters within a string. With RBFS policies, regex can be used as a match-type for most attribute type, e.g., IP prefixes, communities, as-path, etc.

A regex pattern uses a few special purpose characters:

  • {m,n} between m and n characters

  • ? match 0 or 1 time (equal to {0,1})

  • * match 0 or more times (equal to {0,})

  • + match 1 or more times (equal to {1,})

  • [] defines a range of acceptable values

  • () is used for grouping

Exercise 7: Regular Expression Matching

From the 172.16.103.0/24 and 172.16.104.0/24 network, we receive a couple of /32 prefixes with an even number between 90-99 in the last octet that must be routed via R3. Modify your ISP3_IN policy to set the local preference value to 150. Tip: Use a regular expression with the range syntax.

Click to reveal the answer

We are using 172.16.104.92/32 as a prefix to test the policy:

cfg> show bgp fib ipv4 unicast 172.16.104.92/32
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.92/32
    <...>
    IGP metric: 4294967295, Local preference: None, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.2, Label -

cfg> set policy statement ISP3_IN ordinal 5 match rule 1 type ipv4-prefix
cfg> set policy statement ISP3_IN ordinal 5 match rule 1 value-type discrete
cfg> set policy statement ISP3_IN ordinal 5 match rule 1 match-type regex
cfg> set policy statement ISP3_IN ordinal 5 match rule 1 value 172.16.10[34].9[2468]/(32)
cfg> set policy statement ISP3_IN ordinal 5 action rule 1 type local-preference
cfg> set policy statement ISP3_IN ordinal 5 action rule 1 operation overwrite
cfg> set policy statement ISP3_IN ordinal 5 action rule 1 value 150
cfg> set policy statement ISP3_IN ordinal 5 action rule 2 operation return-permit
cfg> commit
cfg> show bgp fib ipv4 unicast 172.16.104.92/32
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 172.16.104.92/32
    <...>
    IGP metric: 4294967295, Local preference: 150, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.6, Label -

This is a simple example and might not be used in real world. Regex is most often used in community, large community and extended community filtering.

Policy Lists

If you define complex BGP peering policies and will notice that some rules occur over and over again in multiple policies, e.g., certain prefixes that are handled the same way. In order to simplify the configuration and make it easier to read and easier to keep it up-to-date, RBFS supports policy lists for

  • IPv4 and IPv6 Prefixes

  • Community, Large Community and Extended Community

  • AS_PATH

A policy list represents a set of entries. With IP prefixes it’s obvious that the implicit match-logic is or as two prefixes can hardly be matching at the same time. The policy list is defined using the set policy list <NAME> <TYPE> ordinal <number> value <value> syntax.

When using policy lists, the value-type within the policy statement changes to list instead of discrete.
Exercise 8: IPv4 Prefix List Matching

The loopback addresses of R2 (192.168.0.102), R3 (192.168.0.103), and R4 (192.168.0.104) should be reachabile via R2. Modify the ISP2_IN policy and set the local preference for these prefixes to 500. At the same time, modify the ISP3_IN policy and set the local preference to 10. Note, that it should be possible to add more IP addresses without touching or extending the policy itself.

Click to reveal the answer

Because we do not want to touch the policies whenever a new loopback address is added, we first define a IPv4 Prefix List:

cfg> set policy list LOOPBACKS ipv4-prefix ordinal 1 value 192.168.0.102/32
cfg> set policy list LOOPBACKS ipv4-prefix ordinal 2 value 192.168.0.103/32
cfg> set policy list LOOPBACKS ipv4-prefix ordinal 3 value 192.168.0.104/32
cfg> commit

Now this list can be used as a match criterion.

cfg> set policy statement ISP2_IN ordinal 20 match rule 1 type ipv4-prefix
cfg> set policy statement ISP2_IN ordinal 20 match rule 1 value-type list
cfg> set policy statement ISP2_IN ordinal 20 match rule 1 match-type exact
cfg> set policy statement ISP2_IN ordinal 20 match rule 1 value LOOPBACKS
cfg> set policy statement ISP2_IN ordinal 20 action rule 1 type local-preference
cfg> set policy statement ISP2_IN ordinal 20 action rule 1 operation overwrite
cfg> set policy statement ISP2_IN ordinal 20 action rule 1 value 500
cfg> set policy statement ISP2_IN ordinal 20 action rule 2 operation return-permit
cfg> commit
cfg> show bgp fib ipv4 unicast 192.168.0.102/32
Instance: default, AFI: ipv4, SAFI: unicast
  Prefix: 192.168.0.102/32
    <...>
    IGP metric: 4294967295, Local preference: 500, Multi exit discriminator: 0
    Preference: 20, External route: None, Readvertised route: None
    Route up: None
    Next hop:
      172.16.0.2, Label -

Policy Test

Policies can get fairly complex and therefore it is desirable to test a policy without applying it to operational traffic. RBFS provides a way to test a policy before attaching it to a protocol with the test policy run command. For policy tests we need three information:

  • the name of the policy to be tested

  • the daemon which is responsible to execute the policy

  • the routing information against which the policy is evaluated

Consider we want to test the operation of the ISP3_IN policy prior to attaching it to peer R3. As this is a BGP peering, the bgp.appd.1 is the daemon responsible for evaluating the policy. All routes which are learned from R3 are stored in the RIB-IN for this peer. Thus, we can execute the test.

The test policy command requires the corresponding BDS table as an input.
op> test policy run bgp.appd.1 policy-name ISP3_IN table default.bgp.rib-in.ipv4.unicast.172.16.0.6.172.16.0.5

The policy test feature will create two result tables. The result table with the name <bds_table>.policy.permit will show all objects permitted by the policy, the one named <bds_table>.policy.deny will show all objects denied by the policy.

op> show datastore bgp.appd.1 table default.bgp.rib-in.ipv4.unicast.172.16.0.6.172.16.0.5.policy.deny
Object: 0, Sequence 10, Last update: Tue Mar 28 11:38:23 GMT +0000 2023
  Attribute                 Type                       Length     Value
  status (1)                uint8 (2)                       1     Valid
  recv_path_id (2)          uint32 (4)                      4     0
  prefix4 (3)               ipv4prefix (13)                38     172.16.104.32/29
  send_path_id (6)          uint32 (4)                  65503     1970376574674623
  bgp_nh4 (9)               ipv4addr (12)                   4     172.16.0.6
  source (11)               uint8 (2)                       1     bgp
  sub_src (12)              uint8 (2)                       1     Local-Peer
  as_path (14)              array (7), uint32 (4)           8     [65003, 65004]
  origin (15)               uint8 (2)                       1     Incomplete
  med (16)                  uint32 (4)                      4     0
  peer_type (17)            uint8 (2)                       9     14890800324179656450
  igp_metric (56)           uint32 (4)                     20     850800723183534079
<...>

Summary

This module outlined the building blocks of the RBFS routing policy framework. You should be able to understand and configure policies using different match and action rules.

If you have completed the exercise, you can check the results by executing

student@tour:~/trainings_resources/robot$ robot policies/policies_verify.robot