Timber by www.emsien3.com EMSIEN-3 Ltd
  • OPT/Net Blog

JUNOS router as BGP Route Server - Part 3

Blog by Taras Matselyukh – CTO and Principal Consultant at Opt/Net Consulting B.V.
Hashtags: #BGPRouteServerJUNOS

Generating aggregates and summary generated routes

Our pseudo route server provides a convenient platform for the route generation and summarisation within IX domain. In Junos you have two options for this: aggregate routes and generates routes.

There is a big difference between the two. While aggregate route will generate a super route if contributing prefix exists in the routing table, it will install the generating router’s own next-hop in the aggregate. The generated route will use the next-hop of the primary contributing route instead. This allows to address different needs for the administrators of the IX domains.

Generated routes

Because generated routes maintain the next-hop of the contributing route, these routes are great to summarize the routes from the route server clients if necessary. The special care should be taken when selecting the primary contributing route in order to ensure predictable results, as shown in the example.

Please, note that these routes are still considered to originate from the aggregate protocol.

taras@J# show policy-options 

policy-statement contribute-filter {
    from {
        protocol bgp;
        route-filter 192.168.3.0/24 exact;
    }
    then accept;
}

policy-statement send-generated-only {
    term only-aggregate {
        from protocol aggregate;
        then accept;
    }
    term reject-all-other-routes {
        then reject;
    }
}

[edit]

taras@J# show protocols        
bgp {
    group ebgp {
        type external;
        export send-generated-only;
        neighbor 192.168.3.201 {
            peer-as 400;
        }
        neighbor 192.168.3.1 {
            peer-as 300;
        }
        neighbor 192.168.3.202 {
            peer-as 100;
        }
    }
}

[edit]

taras@J# show routing-options 
martians {
    0.0.0.0/0 exact;
}

generate {
    defaults {
        preference 130;
    }
    route 192.168.0.0/22 policy contribute-filter;
}

autonomous-system 200;

Also, I would like to draw your attention that I have deliberately shorted the send-generated-only routing policy with reject-all-other-routes policy terminating reject action. This prevents evaluation of all other policies, which may be chained at the export command, as well as default BGP export policy. Otherwise, the default BGP export policy would redistribute all active BGP prefixes to all EBGP peers, which was not desired in this example. Of course, your configurations might differ accordingly to your desires and policies.

--------------- Cisco client ------------- before and after application of the send-generated-only routing policy on Route Server

BEFORE:

C1#sh ip route

Codes: C - connected, S - static, I - IGRP, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route

Gateway of last resort is not set

     20.0.0.0/30 is subnetted, 1 subnets
C       20.0.1.0 is directly connected, Serial1
     10.0.0.0/32 is subnetted, 3 subnets
B       10.2.2.2 [20/0] via 20.0.1.2, 00:39:58
B       10.0.0.1 [20/0] via 192.168.3.201, 00:39:58
C       10.1.1.1 is directly connected, Loopback0
     192.168.255.0/32 is subnetted, 1 subnets
B       192.168.255.1 [20/0] via 192.168.3.1, 00:37:53
B    192.168.0.0/24 [20/0] via 192.168.3.1, 00:37:53
B    192.168.1.0/24 [20/0] via 192.168.3.1, 00:37:53
B    192.168.2.0/24 [20/0] via 192.168.3.1, 00:37:53
C    192.168.3.0/24 is directly connected, Ethernet0

AFTER:

C1#sh ip route

Codes: C - connected, S - static, I - IGRP, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area 
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route

Gateway of last resort is not set

     20.0.0.0/30 is subnetted, 1 subnets
C       20.0.1.0 is directly connected, Serial1
     10.0.0.0/32 is subnetted, 2 subnets
B       10.2.2.2 [20/0] via 20.0.1.2, 00:45:40
C       10.1.1.1 is directly connected, Loopback0
C    192.168.3.0/24 is directly connected, Ethernet0
B    192.168.0.0/22 [20/0] via 192.168.3.1, 00:00:03

C1#sh ip bgp 192.168.0.0 255.255.252.0

BGP routing table entry for 192.168.0.0/22, version 18
Paths: (1 available, best #1, table Default-IP-Routing-Table)
  Advertised to non peer-group peers:
  20.0.1.2 
  200
    192.168.3.1 from 192.168.3.200 (192.168.3.200)
      Origin IGP, localpref 100, valid, external, best

Please, note that the next-hop is still set to the router (192.168.3.1), which originated the contributing route for our route server (192.168.3.200)

Aggregate routes

Injection of the aggregate routes may be useful if administrator of the route server would like to actually receive the traffic destined to one of it’s clients, before forwarding the traffic to the final destinations. There may be valid reasons for this. In order to do so, it is easy to inject a supernet aggregate route for the prefix of interest.

In this example I will create an aggregate route for the 10.0.0.0/8 prefix with no preference for the contributing routes.

[edit routing-options]

taras@J# show 
aggregate {
    defaults {
        preference 164;
        community 200:666;
    }
    route 10.0.0.0/8 discard;
}

In the example, I set the aggregate route preference to be slightly better than default precedence of the BGP routes, in case if there is the specific route that makes it into a routing table from BGP at some point in time. Also, I changed the default ‘reject’ action to more discreet ‘discard’ from default ‘reject’ and tagged my aggregate route with a community 200:666.

This is how the aggregate route appears on the J router, which acts as pseudo route server.

taras@J> show route 10/8 exact extensive 

inet.0: 13 destinations, 16 routes (12 active, 0 holddown, 1 hidden)
10.0.0.0/8 (1 entry, 1 announced)

TSI:
KRT in-kernel 10.0.0.0/8 -> {}
Page 0 idx 0 Type 1 val 8c1ac60
    Nexthop: Self
    AS path: [200] {100 400 500} ? (LocalAgg)
    Communities: 200:666
Path 10.0.0.0 Vector len 4.  Val: 0
        *Aggregate Preference: 164
                Next hop type: Discard
                Next-hop reference count: 2
                State: <Active Int Ext>
                Local AS:   200 
                Age: 1:44:28 
                Task: Aggregate
                Announcement bits (2): 0-KRT 2-BGP RT Background
                AS path: {100 400 500} ? (LocalAgg)
                Communities: 200:666
                                Flags: DiscardDepth: 0Active
                AS path list:
                AS path: 100 ? Refcount: 1
                AS path: 400 I Refcount: 1
                AS path: 100 500 ? Refcount: 1
                Contributing Routes (3):
                10.0.0.1/32 proto BGP
                10.1.1.1/32 proto BGP
                10.2.2.2/32 proto BGP

taras@J> show route advertising-protocol bgp 192.168.3.202    

inet.0: 13 destinations, 16 routes (12 active, 0 holddown, 1 hidden)
  Prefix  Nexthop       MED     Lclpref    AS path
* 10.0.0.0/8              Self                                    {100 400 500} ?
* 192.168.0.0/22          192.168.3.1                             I

Please, note the LocalAggr information, which derives from the AS systems, which routes contributed to the aggregate.
The next-hop is set to the IP address of the router J as shown in the output from router S.

taras@S> show route 10/8 exact detail 

inet.0: 19 destinations, 19 routes (18 active, 0 holddown, 1 hidden)
10.0.0.0/8 (1 entry, 1 announced)
        *BGP    Preference: 170/-101
                Next hop type: Router, Next hop index: 596
                Address: 0x1651568
                Next-hop reference count: 3
                Source: 192.168.3.200
                Next hop: 192.168.3.200 via vlan.1, selected
                State: <Active Ext>
                Local AS:   300 Peer AS:   200
                Age: 1:55:33 
                Task: BGP_200.192.168.3.200+56637
                Announcement bits (2): 0-KRT 3-Resolve tree 1 
                AS path: 200 {100 400 500} ? Aggregator: 200 192.168.3.200
                Communities: 200:666
                Accepted
                Localpref: 100
                Router ID: 192.168.3.200

Filtering routing updates from the clients

There are many reasons why you may need to filter incoming routing updates from your clients, which also may involve commercial and policy needs.

The most typical use is very basic incoming filters for prefixes received from IX members, which block the RFC1918 ranges, “bogon” prefixes and the default route. The complete up-to-date list may be found on Team CYMRU's BOGON List.
http://www.team-cymru.org/Services/Bogons/bogon-bn-nonagg.txt
The latest sample of the BOGON List:

0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4

As you’d see, these are very similar to the “martian routes” described earlier, but broader. (prefixes that are incremental to the default Martians list are in red colour)

Below I will illustrate how to create a simple import policy, which rejects incoming prefixes from the list above, and how to apply it in our pseudo route server.

The default import routing policy for the BGP is to accept all BGP routes and import valid routes to inet.0 routing table. Custom import policy may be applied at the protocol, group and neighbour levels. There may be more than one import policy configured at the different level, but only higher hierarchy’s more specific policy will apply (e.g. policy configured as the neighbour level will override the policy at the group level).
Our new import policy will use the prefix-list:

[edit policy-options]

taras@J# show 
prefix-list bogon-routes {
    10.0.0.0/8;
    100.64.0.0/10;
    169.254.0.0/16;
    172.16.0.0/12;
    192.0.2.0/24;
    192.168.0.0/16;
    198.18.0.0/15;
    198.51.100.0/24;
    203.0.113.0/24;
    224.0.0.0/4;
}

policy-statement reject-bogon-routes {
    from {
        prefix-list-filter bogon-routes orlonger;
    }
    then reject;
}

and we will apply the policy at the protocol level, since this will be a policy that we want apply to all incoming BGP updates.

Note: Please, note that I am using <prefix-list-filer> command instead of just <prefix-list>. This is because would give us exact match only for the prefixes, but we would like to have all subnets within these prefixes covered as well.
taras@J# show protocols 
bgp {
    import reject-bogon-routes;
    group ebgp {
        type external;
        neighbor 192.168.3.201 {
            peer-as 400;
        }

        neighbor 192.168.3.1 {
            peer-as 300;
        }

        neighbor 192.168.3.202 
            peer-as 100;
        }
    }
}

Before we applied our import policy, the route server received the following prefixes from its clients.

taras@J# run show route receive-protocol bgp 192.168.3.1  

inet.0: 12 destinations, 15 routes (11 active, 0 holddown, 1 hidden)
  Prefix  Nexthop       MED     Lclpref    AS path
* 192.168.0.0/24          192.168.3.1                             300 I
* 192.168.1.0/24          192.168.3.1                             300 I
* 192.168.2.0/24          192.168.3.1                             300 I
   192.168.3.0/24          192.168.3.1                             300 I
* 192.168.255.1/32        192.168.3.1                             300 I

__juniper_private1__.inet.0: 4 destinations, 4 routes (2 active, 0 holddown, 2 hidden)

taras@J# run show route receive-protocol bgp 192.168.3.202  

inet.0: 12 destinations, 15 routes (11 active, 0 holddown, 1 hidden)
  Prefix  Nexthop       MED     Lclpref    AS path
* 10.1.1.1/32             192.168.3.202        0                  100 ?
* 10.2.2.2/32             192.168.3.202                           100 500 ?
* 20.0.1.0/30             192.168.3.202        0                  100 ?
  192.168.3.0/24          192.168.3.202        0                  100 ?

__juniper_private1__.inet.0: 4 destinations, 4 routes (2 active, 0 holddown, 2 hidden)

after application of the import policy we can see all private routes (RFC1918) removed from the updates., as expected.

taras@S> show route receive-protocol bgp 192.168.3.200    

inet.0: 18 destinations, 18 routes (18 active, 0 holddown, 0 hidden)
  Prefix  Nexthop       MED     Lclpref    AS path
* 20.0.1.0/30             192.168.3.202                           200 100 ?

In the next part of this blog we will take a look at how to use private AS number for Route-server and hiding it downstream.
Stay tuned!

P.S.If you have feedback, questions or suggestions, please, discuss it on the LinkedIn with us or e-mail us This email address is being protected from spambots. You need JavaScript enabled to view it.