This is part 2 of a multi-tutorial series on GoBGP. Part 1 can be viewed at http://netreflection.blogspot.com/2017/01/introduction-to-gobgp.html and focused more on getting started. In part 2 we will explore using multiple neighbors, with various policies per neighbor. This tutorial assumes either Part 1 was reviewed or base familiarity with GoBGP. Multiple AS's will be utilized as showing in figure 1.
Figure 1.
The configurations of each router are as follows:
R1 Base Configuration
[global.config] as = 65001 router-id = "172.40.1.2" [zebra] [zebra.config] enabled = true url = "unix:/var/run/quagga/zserv.api" redistribute-route-type-list = ["connect"] [[neighbors]] [neighbors.config] neighbor-address = "172.40.1.3" peer-as = 65001
[neighbors.route-reflector.config]
route-reflector-client = true
route-reflector-cluster-id = "172.40.1.2"
[[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"
[[neighbors]]
[neighbors.config]
neighbor-address = "172.40.2.3"
peer-as = 65001
[neighbors.route-reflector.config]
route-reflector-client = true
route-reflector-cluster-id = "172.40.1.2"
[[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" [[neighbors]] [neighbors.config] neighbor-address = "192.65.1.3" peer-as = 65002 [[neighbors.afi-safis]] [neighbors.afi-safis.config] afi-safi-name = "ipv4-unicast" [[neighbors.afi-safis]] [neighbors.afi-safis.config] afi-safi-name = "ipv6-unicast"
Figure 2.
One highlight to R1's configuration, as we have R2 and R3 in the same AS as R1, we have to make R1 a route-reflector to reflect routes from R2 to R3 and vice-versa. Those configurations are highlighted in figure 2 with red letters.
R2 Base Configuration
[global.config] as = 65001 router-id = "172.40.1.3" [zebra] [zebra.config] enabled = true url = "unix:/var/run/quagga/zserv.api" redistribute-route-type-list = ["connect"] [[neighbors]] [neighbors.config] neighbor-address = "172.40.1.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"
Figure 3.
R3 Base Configuration
[global.config] as = 65001 router-id = "172.40.2.3" [zebra] [zebra.config] enabled = true url = "unix:/var/run/quagga/zserv.api" redistribute-route-type-list = ["connect"] [[neighbors]] [neighbors.config] neighbor-address = "172.40.2.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"
Figure 4.
R4 Base Configuration
[global.config] as = 65002 router-id = "192.65.1.3" [zebra] [zebra.config] enabled = true url = "unix:/var/run/quagga/zserv.api" redistribute-route-type-list = ["connect"] [[neighbors]] [neighbors.config] neighbor-address = "192.65.1.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"
Figure 5.
To quickly show that all neighbors are established and exchanging routes, figure 6 is the output from R1's neighbors.
R1:~# gobgp neighbor Peer AS Up/Down State |#Advertised Received Accepted 172.40.1.3 65001 00:00:17 Establ | 6 2 2 172.40.2.3 65001 00:00:15 Establ | 6 2 2 192.65.1.3 65002 00:00:18 Establ | 6 2 2
Figure 6.
Now R1 is going to generate routes, R4 will not get any routes with the community 100:50, R2 and R3 will not get any routes with the community 200:50. But first we need to add those routes. Figure 7 has the routes to be added.
Apply to R1
gobgp global rib add 10.50.1.0/24 origin igp nexthop 10.8.1.1 community 100:50 -a ipv4 gobgp global rib add 10.50.2.0/24 origin igp nexthop 10.8.1.1 community 100:50 -a ipv4 gobgp global rib add 10.50.3.0/24 origin igp nexthop 10.8.1.1 community 100:50 -a ipv4 gobgp global rib add 192.168.50.0/24 origin igp nexthop 10.8.1.1 community 200:50 -a ipv4 gobgp global rib add 192.201.0.0/16 origin igp nexthop 10.8.1.1 community 200:50 -a ipv4
Figure 7.
After applying the routes, each neighbor should be receiving 11 routes as shown in figure 8.
R1:~# gobgp neighbor Peer AS Up/Down State |#Advertised Received Accepted 172.40.1.3 65001 00:17:59 Establ | 11 2 2 172.40.2.3 65001 00:17:57 Establ | 11 2 2 192.65.1.3 65002 00:18:00 Establ | 11 2 2
Figure 8.
Now we need to create the following items:
- Define neighbor sets
- Define community sets
- Define multiple policies
- Attach the policy's globally.
Add the configuration from figure 9 to R1
[[defined-sets.neighbor-sets]] neighbor-set-name = "ns1" neighbor-info-list = ["172.40.1.3","172.40.2.3"] [[defined-sets.neighbor-sets]] neighbor-set-name = "extns1" neighbor-info-list = ["192.65.1.3"]
Figure 9.
Reload and verify the neighbor-sets are defined.
R1# gobgp policy neighbor NAME ADDRESS extns1 192.65.1.3 ns1 172.40.1.3 172.40.2.3
Figure 10.
Now lets create the community-sets to be used in the policies. Figure 11 has the community-sets to be added to R1.
[[defined-sets.bgp-defined-sets.community-sets]] community-set-name = "cs0" community-list = ["100:50"] [[defined-sets.bgp-defined-sets.community-sets]] community-set-name = "cs1" community-list = ["200:50"]
Figure 11.
This time, we will hold off on applying until the remainder of the configuration is complete. Now we need to create 2 policies, 1 which will restrict all internal routers from getting routes with community 200:50 and the other policy, which will prevent all routes with the community 100:50 from leaking outside AS 65001 (or to R4, the external site). Figure 12 has he policies to be applied to R1.
[[policy-definitions]] name = "policy1" [[policy-definitions.statements]] name = "Drop community 200:50 to internal routers" [policy-definitions.statements.conditions.match-neighbor-set] neighbor-set = "ns1" match-set-options = "any" [policy-definitions.statements.conditions.bgp-conditions.match-community-set] community-set = "cs1" match-set-options = "any" [policy-definitions.statements.actions.route-disposition] accept-route = false [[policy-definitions]] name = "policy2" [[policy-definitions.statements]] name = "Drop community 100:50 to external routers" [policy-definitions.statements.conditions.match-neighbor-set] neighbor-set = "extns1" match-set-options = "any" [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 12.
After this we need to apply the policy globally. We do this as depicted in figure 13.
[global.config]
as = 65001
router-id = "172.40.1.2"
[global.apply-policy.config]
export-policy-list = ["policy1","policy2"]
Figure 13.
Next let's verify the policies are attached and properly defined. Figure 14 has the output showing running policy.
R1:~# gobgp policy Name policy1: StatementName Drop community 200:50 to internal routers: Conditions: NeighborSet: ANY ns1 CommunitySet: ANY cs1 Actions: REJECT Name policy2: StatementName Drop community 100:50 to external routers: Conditions: NeighborSet: ANY extns1 CommunitySet: ANY cs0 Actions: REJECT
Figure 14.
Figure 15 shows a script to get what is being advertised out from R1 to each peer. Notice the routes highlighted in red in accordance to the polices.
R1:~# for i in `gobgp neighbor |egrep -v "Peer" | awk '{print $1}'` do echo $i gobgp neighbor $i adj-out done
OUTPUT:
172.40.1.3 Network Next Hop AS_PATH Attrs 10.8.1.0/24 172.40.1.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 10.8.3.0/24 172.40.2.3 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 172.40.2.3} {ClusterList: [172.40.1.2]}] 10.20.0.0/24 192.65.1.3 65002 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 192.65.1.3} {ClusterList: [172.40.1.2]}] 10.50.1.0/24 10.8.1.1 [{Origin: i} {LocalPref: 100} {Communities: 100:50} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 10.50.2.0/24 10.8.1.1 [{Origin: i} {LocalPref: 100} {Communities: 100:50} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 10.50.3.0/24 10.8.1.1 [{Origin: i} {LocalPref: 100} {Communities: 100:50} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 172.40.1.0/29 172.40.1.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 172.40.2.0/29 172.40.1.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 192.65.1.0/29 172.40.1.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 172.40.2.3 Network Next Hop AS_PATH Attrs 10.8.1.0/24 172.40.2.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 10.8.2.0/24 172.40.1.3 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 172.40.1.3} {ClusterList: [172.40.1.2]}] 10.20.0.0/24 192.65.1.3 65002 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 192.65.1.3} {ClusterList: [172.40.1.2]}] 10.50.1.0/24 10.8.1.1 [{Origin: i} {LocalPref: 100} {Communities: 100:50} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 10.50.2.0/24 10.8.1.1 [{Origin: i} {LocalPref: 100} {Communities: 100:50} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 10.50.3.0/24 10.8.1.1 [{Origin: i} {LocalPref: 100} {Communities: 100:50} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 172.40.1.0/29 172.40.2.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 172.40.2.0/29 172.40.2.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 192.65.1.0/29 172.40.2.2 [{Origin: i} {Med: 0} {LocalPref: 100} {Originator: 0.0.0.0} {ClusterList: [172.40.1.2]}] 192.65.1.3 Network Next Hop AS_PATH Attrs 10.8.1.0/24 192.65.1.2 65001 [{Origin: i} {Med: 0}] 10.8.2.0/24 192.65.1.2 65001 [{Origin: i}] 10.8.3.0/24 192.65.1.2 65001 [{Origin: i}] 172.40.1.0/29 192.65.1.2 65001 [{Origin: i} {Med: 0}] 172.40.2.0/29 192.65.1.2 65001 [{Origin: i} {Med: 0}] 192.65.1.0/29 192.65.1.2 65001 [{Origin: i} {Med: 0}] 192.168.50.0/24 10.8.1.1 65001 [{Origin: i} {Communities: 200:50}] 192.201.0.0/16 10.8.1.1 65001 [{Origin: i} {Communities: 200:50}]
Figure 15.
Finally, as I always like to see the whole config after all the changes, here is the final configuration for R1:
[global.config] as = 65001 router-id = "172.40.1.2" [global.apply-policy.config] export-policy-list = ["policy1","policy2"] [zebra] [zebra.config] enabled = true url = "unix:/var/run/quagga/zserv.api" redistribute-route-type-list = ["connect"] [[neighbors]] [neighbors.config] neighbor-address = "172.40.1.3" peer-as = 65001 [neighbors.route-reflector.config] route-reflector-client = true route-reflector-cluster-id = "172.40.1.2" [[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" [[neighbors]] [neighbors.config] neighbor-address = "172.40.2.3" peer-as = 65001 [neighbors.route-reflector.config] route-reflector-client = true route-reflector-cluster-id = "172.40.1.2" [[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" [[neighbors]] [neighbors.config] neighbor-address = "192.65.1.3" peer-as = 65002 [[neighbors.afi-safis]] [neighbors.afi-safis.config] afi-safi-name = "ipv4-unicast" [[neighbors.afi-safis]] [neighbors.afi-safis.config] afi-safi-name = "ipv6-unicast" [[defined-sets.neighbor-sets]] neighbor-set-name = "ns1" neighbor-info-list = ["172.40.1.3","172.40.2.3"] [[defined-sets.neighbor-sets]] neighbor-set-name = "extns1" neighbor-info-list = ["192.65.1.3"] [[defined-sets.bgp-defined-sets.community-sets]] community-set-name = "cs0" community-list = ["100:50"] [[defined-sets.bgp-defined-sets.community-sets]] community-set-name = "cs1" community-list = ["200:50"] [[policy-definitions]] name = "policy1" [[policy-definitions.statements]] name = "Drop community 200:50 to internal routers" [policy-definitions.statements.conditions.match-neighbor-set] neighbor-set = "ns1" match-set-options = "any" [policy-definitions.statements.conditions.bgp-conditions.match-community-set] community-set = "cs1" match-set-options = "any" [policy-definitions.statements.actions.route-disposition] accept-route = false [[policy-definitions]] name = "policy2" [[policy-definitions.statements]] name = "Drop community 100:50 to external routers" [policy-definitions.statements.conditions.match-neighbor-set] neighbor-set = "extns1" match-set-options = "any" [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
Hopefully you found this helpful. In a part 3 that will come at a later time, we will explore a more complex setup and policy.
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.
ReplyDeleteI 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
ReplyDelete[policy-definitions.statements.actions.route-disposition]
accept-route = false
The new one is
[policy-definitions.statements.actions]
route-disposition] = "reject-route"