Tuesday, January 10, 2017

Introduction to GoBGP Part 1

Published by Tim Epkes
 
GoBGP is an open source initiative providing a feature rich and scalable BGP solution to the open source community.  GoBGP can be found on github at the following URL https://github.com/osrg/gobgp.

In this post I will show how to get started with GoBGP using two routers.  Future posts will include more complicated setups.


Both routers are linked via the 192.168.0.0/29, R1 is 192.168.0.2 and R2 is 192.168.0.3.  Each router has its own subnet (10.1.1.0/24 and 10.2.2.0/24 respectively).  The following is the configuration for R1:

R1 Configuration (in TOML) R2 Configuration (in TOML)
[global.config]
  as = 65001
  router-id = "192.168.0.2"
 
[zebra]
  [zebra.config]
    enabled = true
    url = "unix:/var/run/quagga/zserv.api"
    redistribute-route-type-list = ["connect"]
 
[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.0.3"
    peer-as = 65001
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv6-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-labelled-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "l3vpn-ipv4-unicast"
[global.config]
  as = 65001
  router-id = "192.168.0.3"
 
[zebra]
  [zebra.config]
    enabled = true
    url = "unix:/var/run/quagga/zserv.api"
    redistribute-route-type-list = ["connect"]
 
[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.0.2"
    peer-as = 65001
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv6-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "ipv4-labelled-unicast"
  [[neighbors.afi-safis]]
    [neighbors.afi-safis.config]
      afi-safi-name = "l3vpn-ipv4-unicast"
Note: The configuration file can be written in TOML, YAML or JSON (like the flexibility).

Once the two routers are configured and you have to start GoBGPd doing the following:

R1# gobgpd -f /etc/gobgpd/gobgpd.conf                                                  

R2# gobgpd -f /etc/gobgpd/gobgpd.conf                                                  

Note: To reload you can simply do a kill -HUP on the pid of GoBGPd.

To verify R1 is neighbored to R2 type the following:

R1# gobgp neighbor
Peer           AS  Up/Down State       |#Advertised Received Accepted                  
192.168.0.3 65001 00:29:12 Establ      |          2        2        2
Figure 1.

Figure 1 shows that R1 is successfully neighbored to R2, is advertising and receiving routes.  To obtain detailed information about your neighbor just specify the neighbor IP address in your gobgp neighbor command:

R1# gobgp neighbor 192.168.0.3
BGP neighbor is 192.168.0.3, remote AS 65001
  BGP version 4, remote router ID 192.168.0.3
  BGP state = BGP_FSM_ESTABLISHED, up for 00:36:03
  BGP OutQ = 0, Flops = 0
  Hold time is 90, keepalive interval is 30 seconds
  Configured hold time is 90, keepalive interval is 30 seconds                         
  Neighbor capabilities:
    multiprotocol:
        ipv4-unicast: advertised and received
        ipv6-unicast: advertised and received
        ipv4-labelled-unicast: advertised and received
        l3vpn-ipv4-unicast: advertised and received
    route-refresh: advertised and received
    4-octet-as: advertised and received
  Message statistics:
                         Sent       Rcvd
    Opens:                  1          1
    Notifications:          0          0
    Updates:                1          1
    Keepalives:            73         73
    Route Refesh:           0          0
    Discarded:              0          0
    Total:                 75         75
  Route statistics:
    Advertised:             2
    Received:               2
    Accepted:               2
Figure 2.

Figure 2 shows more detailed information about the neighbor like; R1 is established with its neighbor, the address families that can advertise and be received, routes advertised / received / accepted and other useful information.

From here we want to see the routes that are being exchanged.  To do this you need to take a look at the global rib using the following commands:

R1# gobgp global rib
    Network             Next Hop             AS_PATH              Age        Attrs
*>  10.1.1.0/24         0.0.0.0                                   00:01:43   [{Origin: i} {Med: 0}]
*>  10.2.2.0/24         192.168.0.3                               00:01:30   [{Origin: i} {Med: 0} {LocalPref: 100}]
*>  192.168.0.0/28      0.0.0.0                                   00:01:43   [{Origin: i} {Med: 0}]
*   192.168.0.0/28      192.168.0.3                               00:01:30   [{Origin: i} {Med: 0} {LocalPref: 100}]
Figure 3.

Figure 3 shows our routes locally and the routes from R2.  Now we are going to add some routes and provide community values.

R1# gobgp global rib add 10.50.1.0/24 origin igp nexthop 10.1.1.1 community 100:50 -a ipv4
R1# gobgp global rib add 10.50.2.0/24 origin igp nexthop 10.1.1.1 community 100:50 -a ipv4
R1# gobgp global rib add 10.50.3.0/24 origin igp nexthop 10.1.1.1 community 100:50 -a ipv4
R1# gobgp global rib add 192.168.50.0/24 origin igp nexthop 10.1.1.1 community 200:50 -a ipv4
Figure 4.

After adding the additional routes, verify the routes in the rib on the R2 side.

# gobgp global rib              
    Network             Next Hop             AS_PATH              Age        Attrs
*>  10.1.1.0/24         192.168.0.2                               00:31:01   [{Origin: i} {Med: 0} {LocalPref: 100}]
*>  10.2.2.0/24         0.0.0.0                                   4d 06:29:53 [{Origin: i} {Med: 0}]
*>  10.50.1.0/24        10.1.1.1                                  00:06:32   [{Origin: i} {LocalPref: 100} {Communities: 100:50}]
*>  10.50.2.0/24        10.1.1.1                                  00:06:32   [{Origin: i} {LocalPref: 100} {Communities: 100:50}]
*>  10.50.3.0/24        10.1.1.1                                  00:06:32   [{Origin: i} {LocalPref: 100} {Communities: 100:50}]
*>  192.168.0.0/28      0.0.0.0                                   4d 06:29:53 [{Origin: i} {Med: 0}]
*   192.168.0.0/28      192.168.0.2                               00:31:01   [{Origin: i} {Med: 0} {LocalPref: 100}]
*>  192.168.50.0/24     10.1.1.1                                  00:00:05   [{Origin: i} {LocalPref: 100} {Communities: 200:50}]
Figure 5.

Figure 5 shows the additional routes and the communities that were set.  To get summaries of routes GoBGP processed, execute the following:

R1# gobgp global rib summary   IPv4 is default 
Table ipv4-unicast
Destination: 7, Path: 8

R1# gobgp global rib summary -a ipv4-labelled
Table ipv4-labelled-unicast                                                             
Destination: 2, Path: 2

R1# gobgp global rib summary -a ipv6   
Table ipv6-unicast
Destination: 0, Path: 0
Figure 6.

Next, we want to create a policy that does not allow the community 200:50 prefixes out of R1.  To do this we need to accomplish the following:
  • Define a community set cs0
  • Create a policy leveraging the community set cs0
  • Attach the policy to the global configuration
First we create our community set, as follows:

[[defined-sets.bgp-defined-sets.community-sets]]                                        
  community-set-name = "cs0"
  community-list = ["200:50"]
Figure 7.

Figure 7 shows the community set definition.  First you provide your community set with a name and then a list of communities.

Next we create our policy, as follows:
[[policy-definitions]]
    name = "policy1"
    [[policy-definitions.statements]]
        name = "Drop community 200:50"
        [policy-definitions.statements.conditions.bgp-conditions.match-community-set]   
            community-set = "cs0"
            match-set-options = "any"
        [policy-definitions.statements.actions.route-disposition]
            accept-route = false
Figure 8.

Figure 8 shows the policy definition.  We give our policy a name, in this case "policy1" (for the lack of a better name).  Under policy-definition.statements, we give a brief description of the policy by assigning it to name.  A policy has to have the following:
  • Name
  • Condition
  • Action
The condition has various options, in this case the condition will just include a community-set.  We assign the community-set to "cs0" and have match-set-options = "any".  Any means match any community in the list.  You have 3 options for the match-set-options under match-community-set are:
  • Any - Match any one of the communities (default)
  • All - Match all of the communities in the defined community set
  • Invert - Match anything but the communities in the defined community set
Next the action then needs to be defined.  Here we are specifying the route-disposition, if the conditions are true,  disallow the route. 


Finally we attach the policy, as follows:

[global.config]                                                                             
  as = 65001
  router-id = "192.168.0.2"
[global.apply-policy.config]
  export-policy-list = ["policy1"]
Figure 9.

Figure 9  shows the policy attached to the global configuration.  In this case I want to restrict community 200:50 routes from going to R2, so I put policy1 in the export-policy-list.

You might ask, why would you apply it globally, when you want the policy to apply to a certain neighbor?  In this case I have only one neighbor, but if I had more than one neighbor, I still would apply it globally.  To restrict what peers it applies to you would need to assemble a neighbor-set that then applies that policy only to certain neighbors (a tutorial for another day).

Reload your gobgpd process and verify the policy is applied as shown in figure 10.

R1# gobgp policy
Name policy1:
    StatementName Drop community 200:50:                                               
      Conditions:
        CommunitySet: ANY cs0
      Actions:
        REJECT
Figure10.

To see what routes on R1 have been advertised to a specific neighbor, you can do the following commands:

# gobgp neighbor 192.168.0.3 adj-out
    Network             Next Hop             AS_PATH              Attrs
    10.1.1.0/24         192.168.0.2                               [{Origin: i} {Med: 0} {LocalPref: 100}]
    10.50.1.0/24        10.1.1.1                                  [{Origin: i} {LocalPref: 100} {Communities: 100:50}]
    10.50.2.0/24        10.1.1.1                                  [{Origin: i} {LocalPref: 100} {Communities: 100:50}]
    10.50.3.0/24        10.1.1.1                                  [{Origin: i} {LocalPref: 100} {Communities: 100:50}]
    192.168.0.0/28      192.168.0.2                               [{Origin: i} {Med: 0} {LocalPref: 100}]
Figure11.

I'll build off this tutorial in a part 2 at another time.  I hope you find this helpful.


2 comments:

  1. Quick Note: Between the pull I used for this post and the current pull, there are changes in config syntax for policy. I'll get those posted up as soon as I can.

    ReplyDelete
  2. I finished testing the change in config. The change is just in the Policy actions definition. In the new git pull the change is active. The current config line is
    [policy-definitions.statements.actions.route-disposition]
    accept-route = false
    The new one is
    [policy-definitions.statements.actions]
    route-disposition] = "reject-route"

    ReplyDelete