When you are trying to set up a route manually for a particular purpose, you are faced with these 3 different options in Junos:
- STATIC
- GENERATED (summary route)
- AGGREGATE (summary route)
And probably you have asked yourself: What are the differences? Which one should I use? Does it really matter?
The goal of this article is to help you answer these questions, so next time you need to manually configure a route in your Juniper device(s), it will be easier for you to decide which type you need to use.
STATIC ROUTES
These are the easiest, maybe most common ones, or simply the ones that you have heard about since you started your career in Networking.
I am sure you can tell me what a static route is. You would probably say something like a manually configured route that is added to the routing table as soon as I configure it, and being “static”, it is a route that doesn’t change, doesn’t move, doesn’t go away, and it always preferred.
And for the most part: you would be right! You create a static route manually, by defining the destination prefix, and the next hop. The route goes to the routing table, and it does not change, does not move, does not depend on a metric, or bandwidth, does not adapt to changes in the network, BUT it can actually go away or just become useless! It turns out that even static routes have some requirements to become active and be usable for forwarding traffic. We will talk about that.
You probably know that a static route in Junos is configured under the [routing-options] hierarchy, using set static <prefix> next-hop <next-hop-address>. But, is that all you can do? Nope!
There are several options and knobs that you can add to your static route. We are going to talk about a few of them too, using some examples.
1) NEXT HOP
The next hop is typically the IP address of a directly connected device. Consider the following example:
Customer_Router_VR is configured with a static default route, that points to the address of ISP_Router_VR, while ISP_Router_VR is configured with a static route to the customer prefix, that points to the IP address of the physical interface of Customer_Router_VR . Both routers basically have static routes pointing to each other’s IP address
Here is how the configuration looks like:
[edit routing-instances] jcluser@vMX-addr-0# show | display set relative | match routing-options set Customer__VR routing-options static route 0.0.0.0/0 next-hop 172.16.1.2 set ISP_Router_VR routing-options static route 10.1.1.0/24 next-hop 172.16.1.1
We can validate connectivity between the Internal User and the Web Server.:
jcluser@vMX-addr-0> ping 192.168.1.1 routing-instance Internal_User_VR rapid PING 192.168.1.1 (192.168.1.1): 56 data bytes !!!!! --- 192.168.1.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.365/0.446/0.660/0.110 ms
Let’s take a look at how one of this routes looks like in the routing table:
jcluser@vMX-addr-0> show route 10.1.1.1 table ISP_Router_VR.inet.0 ISP_Router_VR.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 10.1.1.0/24 *[Static/5] 00:07:24 > to 172.16.1.1 via lt-0/0/0.2
NOTE: I am typing show route 10.1.1.1, which is asking the router to find the longest match for 10.1.1.1. In other words, the route that the router would use to send traffic to 10.1.1.1.
In the show route output we can see a few things:
- 10.1.1.0/24 is the destination prefix.
- Between square brackets, the router shows the protocol or source of the route (in this case static), and the route’s preference value. The default preference value for a static route is 5, which makes it better than a router learned from a dynamic routing protocols such as OSPF, which has a default preference of 10. We will talk more about this later.
- The * symbol indicates that the route is ACTIVE, which means it is the route that will be installed in the forwarding table, and that will be used to forward traffic.
- The next-hop is 172.16.1.2
If you needed to describe this static route to someone you could say: “traffic going to 10.1.1.0/24 should be sent to 172.16.1.1”. It is important to highlight that this next-hop is reachable out of interface lt-0/0/0.1 and is directly connected. Here is where we start talking about the requirements for a static route to become active:
- the next-hop must be reachable, and
- by default the next-hop must be directly connected.
Let’s say that we change the next hop of the static default route on the Customer_Router to be the loopback address on the ISP_Router.
[edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# show route 0.0.0.0/0 next-hop 172.16.1.2; [edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# replace pattern 172.16.1.2 with 2.2.2.2 [edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# show route 0.0.0.0/0 next-hop 2.2.2.2; [edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# commit commit complete
When we check the routing table again, we find that the 0/0 route is gone, and the internal user is no longer able to reach the Web Server:
jcluser@vMX-addr-0> show route 0/0 exact table Customer__VR.inet.0 (no output) jcluser@vMX-addr-0> jcluser@vMX-addr-0> ping 192.168.1.1 routing-instance Internal_User_VR rapid PING 192.168.1.1 (192.168.1.1): 56 data bytes 36 bytes from 10.1.1.254: Destination Net Unreachable Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 0054 3a6b 0 0000 40 01 7393 10.1.1.1 192.168.1.1 .36 bytes from 10.1.1.254: Destination Net Unreachable Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 0054 3a81 0 0000 40 01 737d 10.1.1.1 192.168.1.1 .36 bytes from 10.1.1.254: Destination Net Unreachable Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 0054 3a90 0 0000 40 01 736e 10.1.1.1 192.168.1.1 .36 bytes from 10.1.1.254: Destination Net Unreachable Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 0054 3aa3 0 0000 40 01 735b 10.1.1.1 192.168.1.1 .36 bytes from 10.1.1.254: Destination Net Unreachable Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 0054 3ab3 0 0000 40 01 734b 10.1.1.1 192.168.1.1 . --- 192.168.1.1 ping statistics --- 5 packets transmitted, 0 packets received, 100% packet loss
And you are probably going to say: “duh! That’s pretty obvious, Customer_Router does not know how to get to the loopback of ISP_Router. And you would be right, so let’s fix that.
We add a static route to reach the loopback of ISP_Router (2.2.2.2):
[edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# set route 2.2.2.2 next-hop 172.16.1.2 [edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# commit commit complete
We validate that the route has been added:
jcluser@vMX-addr-0> show route 2.2.2.2 table Customer__VR.inet.0 Customer__VR.inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2.2.2.2/32 *[Static/5] 00:00:34 > to 172.16.1.2 via lt-0/0/0.1
But our default route is still not there:
jcluser@vMX-addr-0> show route 0/0 exact table Customer__VR.inet.0 (no output) jcluser@vMX-addr-0>
That is because the router by default expects the next-hop to be directly connected. This is where we introduce the second option that we will describe in this article.
2) RESOLVE:
You guess right, the resolve option can be used when the specified next hop is not directly connected.
Let’s add that to our configuration:
[edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# set route 0.0.0.0/0 resolve [edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# commit commit complete jcluser@vMX-addr-0> show route 0/0 exact table Customer__VR.inet.0 Customer__VR.inet.0: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 0.0.0.0/0 *[Static/5] 00:00:25, metric2 0 > to 172.16.1.2 via lt-0/0/0.1
BINGO! Out default route is back!
What we did here was tell our router that it was OK for him to go to the routing table to figure out how to get to the next-hop of the static route and use that information as the next-hop.
In other words, we told our router that in order to send traffic to any unknown destination (0/0), traffic had to be sent to 2.2.2.2, and that we were giving it permission to figure out how to get to 2.2.2.2. The router did a route lookup and ended up using 172.16.1.2 as the next-hop.
So, in order to send traffic to any destination, send traffic to 2.2.2.2, and to send traffic to 2.2.2.2 send traffic to 172.16.1.2. This is called Route Resolution, and the next-hop in the static route is an indirect next-hop.
Here is another example:
I know! I know! Why would I want to do something like this? Why not just configure next-hop as 172.16.1.2 to start with?
Well, what if our topology is actually like this?
172.16.3/24 is not being advertised by OSPF. R1 is configured with a static route pointing to the loopback of R3, and to get to the loopback of R3 is has two possible routes learned from OSPF. And if load balancing is enabled, R1 can now send traffic going to 172.16.3/24 via both R2 and R4.
Wait! Does that mean I can have a static route with two next-hops? Yeap!
Let’s add as second interface between Customer_Router and ISP_Router and a second next-hop to our static route.
[edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# set next-hop 172.16.1.2 [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# set next-hop 172.16.2.2 [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# show next-hop [ 172.16.1.2 172.16.2.2 ];
We don’t need resolve because we are using directly connected neighbor in this example.
You can see that the routing table shows two next hops. However, only one of these next-hops is being used for forwarding traffic: the one with the > symbol.
If we check the forwarding table we can see that 172.16.1.2 is the only next hop installed. article.
jcluser@vMX-addr-0> show route forwarding-table destination 0/0 table Customer__VR.inet.0 Routing table: Customer__VR.inet Internet: Enabled protocols: Bridging, Destination Type RtRef Next hop Type Index NhRef Netif default user 0 0.2.80.3.0.<more> ucst 616 4 lt-0/0/0.1 default perm 0 rjct 690 1 0.0.0.0/32 perm 0 dscd 688 1
In order to use both we would need to enable load balancing, but that can be the topic of another article. So, assuming we don’t want load balancing, what if we want 172.16.2.2 to be used instead of 172.16.1.1?
That is where we start talking about preference value, and qualified next-hop.
3) PREFERENCE VALUE:
You might be familiar with the preference value assigned to each routing protocols or source of routing information, which allows the router to choose between routes for the same destination, from different routing protocols,.Yes, like administrative distance.
We already saw that the default preference value for a static route is 5. That can of course be easily changed.
We can go under routing-options static and change the default preference for ALL static routes:
[edit routing-instances Customer__VR routing-options static] jcluser@vMX-addr-0# set defaults preference 10
Not what we want to do right now.
Or we can go under a specific static route and change the value only for that route:
[edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# set preference 10 [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# commit commit complete jcluser@vMX-addr-0> show route 0/0 exact table Customer__VR.inet.0 Customer__VR.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 0.0.0.0/0 *[Static/10] 00:00:39 > to 172.16.1.2 via lt-0/0/0.1 to 172.16.2.2 via lt-0/0/0.7
However, when we do that, the preference value is changed for all static routes, not for any specific next-hop.
Again, not what we want right now.
If what we want is one next-hop to be preferred over another next-hop for the same route, we need the ability to change the preference value for that specific next-hop within a specific static route. To achieve this we have something Qualified Next Hop.
4) QUALIFIED NEXT HOP
A qualified next hop is a next hop which can be “qualified” using attributes such as metric, preference, or tag.
[edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# set qualified-next-hop 172.16.2.2 ? Possible completions: <[Enter]> Execute this command + apply-groups Groups from which to inherit configuration data + apply-groups-except Don't inherit configuration data from these groups > bfd-liveness-detection Bidirectional Forwarding Detection (BFD) options interface Interface of qualified next hop mac-address Next-hop Mac Address metric Metric of qualified next hop preference Preference of qualified next hop tag Tag string | Pipe through a command
For a given static route you can configure next-hops and qualified next-hops at the same time:
[edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# help apropos next-hop | match set set next-hop set qualified-next-hop ---more--- [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# set next-hop 172.16.2.2 [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# set qualified-next-hop 172.16.1.2 preference 10 [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# show next-hop 172.16.2.2; qualified-next-hop 172.16.1.2 { preference 10; } [edit routing-instances Customer__VR routing-options static route 0.0.0.0/0] jcluser@vMX-addr-0# commit commit complete jcluser@vMX-addr-0> show route 0/0 exact table Customer__VR.inet.0 Customer__VR.inet.0: 9 destinations, 10 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 0.0.0.0/0 *[Static/5] 00:00:38 > to 172.16.2.2 via lt-0/0/0.7 [Static/10] 00:00:38 > to 172.16.1.2 via lt-0/0/0.1
You can see now, that each next hop has its own preference value. Basically, we now have two static default routes with different next-hops and different preference values. The one with the LOWEST preference value is selected and becomes the active route.
Hopefully, you are still with me. Because now we are going to talk about an interesting option, the TRASH CAN!
5) REJECT/DISCARD
Imagine that instead of pointing your static route to the address of one of your neighbors, you point it to the trash can or bit bucket. That is, when traffic matches this route it is thrown away. Sounds kind of absurd but believe it or now, there are situations when you want exactly that, and surely, we will talk about that in a few. For now, just have faith, and keep reading.
Before I get into the examples, let me explain one more thing. There are two types of trash cans: one that is silent, and one that tells about the packet being dropped.
And BTW. This is how I remember which one is which: Discard Don’t sent an ICMP message back.
Let’s take a look at an example, where using the trash can is useful.
Our customer router has learned routes to the subnets 172.16.100/28, 172.16.100.16/28, 172.16.100.32/28 and 172.16.100.48/28.
If you do a little binary math on the last octet, you will find that these 4 subnets have in common the first 26 bits.
Thus, the 4 subnets can be summarized as 172.16.100/26, which the ISP_Router has a static route in its routing table for.
Life is good as long as all 4 subnets are up and reachable, as shown in the example below:
1) ISP_Router receives a packet with DA = 172.16.100.50
2) ISP_Router performs a L3 lookup, and the packet matches the static route pointing to 172.16.1.1
3) Packet is sent to Customer_Router
4) Customer_Router also performs a L3 lookup
5) Customer_Router sends the packet out of ge-0/0/0.0 to the proper next-hop (not shown in the diagram).
Now, what if network 172.16.100.48/28 becomes unavailable?
The ISP_Router is NOT aware of this subnet being unavailable, so when the packet going to 172.16.100.50 arrives, it forwards it the exact same way.
And here we go, because the specific route to 172.16.100.48/28 is no longer present in Customer_Router’s routing table, the only route that matches is the default route which points back to 172.16.1.2 (the ISP_Router). And guess what? When the ISP_Router receives the packet back, it does an L3 lookup and determines that the packet needs to sent back to Customer_Router.
You just got a beautiful routing loop!!! It will stop when the TTL expire, thanks goodness, but in the meantime you are wasting resources!
The solution is quite simple: Add a static route that summarizes all the subnets, and has a next-hop equal to (yes) the trash can!
So, when the packet arrives now to Customer_Router (while the specific subnet is still unreachable), the packet matches the 172.16.100/26 route because of longest match. As a result, the packet is thrown away, rather than sent back to the ISP_Router. Some bandwidth and processing cycles were saved.
But what if all 4 subnets are down? The ISP_Router has no clue, so any traffic that the ISP_Router receives going to any of these subnets is going to be sent to the Customer_Router, only to be dropped.
It would be nice if the route that the ISP_Router has for the networks inside the customer’s site, was dynamic and would go away when all the networks are down.
Let’s say that the customer has decided to run BGP and use routing policies to exchange routing information with the ISP and with the internal networks. Here is our new topology:
The relevant configuration sections are shown below:
– Enable tunnel services so that tunnel interfaces get created:
[edit chassis] jcluser@vMX-addr-0# show | display set relative set fpc 0 pic 0 tunnel-services
– Configure the interfaces:
[edit interfaces] jcluser@vMX-addr-0# show | display set relative set lt-0/0/0 unit 1 encapsulation ethernet set lt-0/0/0 unit 1 peer-unit 2 set lt-0/0/0 unit 1 family inet address 172.16.2.1/24 set lt-0/0/0 unit 2 encapsulation ethernet set lt-0/0/0 unit 2 peer-unit 1 set lt-0/0/0 unit 2 family inet address 172.16.2.2/24 set lt-0/0/0 unit 3 encapsulation ethernet set lt-0/0/0 unit 10 encapsulation ethernet set lt-0/0/0 unit 10 peer-unit 11 set lt-0/0/0 unit 10 family inet address 172.16.1.2/24 set lt-0/0/0 unit 11 encapsulation ethernet set lt-0/0/0 unit 11 peer-unit 10 set lt-0/0/0 unit 11 family inet address 172.16.1.1/24 set lo0 unit 11 family inet address 172.16.100.1/28 set lo0 unit 11 family inet address 172.16.100.17/28 set lo0 unit 11 family inet address 172.16.100.33/28 set lo0 unit 11 family inet address 172.16.100.49/28
NOTE: The loopback addresses will simulate the internal subnets
– Add routing instance that will simulate the multiple routers:
[edit routing-instances] jcluser@vMX-addr-0# show | display set relative set Customer_Router_VR instance-type virtual-router set Customer_Router_VR interface lt-0/0/0.1 set Customer_Router_VR interface lt-0/0/0.10 set Customer_Router_VR routing-options autonomous-system 100 set Customer_Router_VR routing-options autonomous-system independent-domain set Customer_Router_VR protocols bgp group IBGP peer-as 100 set Customer_Router_VR protocols bgp group IBGP neighbor 172.16.1.1 set Customer_Router_VR protocols bgp group EBGP export SUMMARY set Customer_Router_VR protocols bgp group EBGP peer-as 200 set Customer_Router_VR protocols bgp group EBGP neighbor 172.16.2.2 set ISP_Router_VR instance-type virtual-router set ISP_Router_VR interface lt-0/0/0.2 set ISP_Router_VR routing-options autonomous-system 200 set ISP_Router_VR routing-options autonomous-system independent-domain set ISP_Router_VR protocols bgp group EBGP peer-as 100 set ISP_Router_VR protocols bgp group EBGP neighbor 172.16.2.1 set SITE1_GW_VR instance-type virtual-router set SITE1_GW_VR interface lt-0/0/0.11 set SITE1_GW_VR interface lo0.11 set SITE1_GW_VR routing-options autonomous-system 100 set SITE1_GW_VR routing-options autonomous-system independent-domain set SITE1_GW_VR protocols bgp group IBGP local-address 172.16.1.1 set SITE1_GW_VR protocols bgp group IBGP export lo0.11 set SITE1_GW_VR protocols bgp group IBGP peer-as 100 set SITE1_GW_VR protocols bgp group IBGP local-as 100 set SITE1_GW_VR protocols bgp group IBGP neighbor 172.16.1.2
– Configure the routing-policies referenced under protocols BGP:
[edit policy-options policy-statement SUMMARY] jcluser@vMX-addr-0# show | display set relative set term 1 from route-filter 172.16.100.0/26 exact set term 1 then accept set term 2 then reject [edit policy-options policy-statement lo0.11] jcluser@vMX-addr-0# show | display set relative set term 1 from protocol direct set term 1 from interface lo0.11 set term 1 then accept
Notice that SITE1_GW_VR is using a routing-policy called lo0.11, which advertises the subnets under lo0.11. Then Customer_Router_VR is using a policy called SUMMARY which matches 172.16.100.0/26 exact, and rejects everything else. Thus, the only route that Customer_Router_VR will advertise to the ISP is the 172.16.100.0/26. Remember that by default, active IBGP routes are advertised to EBGP neighbor, and we do not want to advertise the specific routes, only the summary.
We check the routes that we are receiving from SITE1. We see all 4 subnets coming in.
jcluser@vMX-addr-0> show route receive-protocol bgp 172.16.1.1 table Customer_Router.inet.0 Customer_Router_VR.inet.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 172.16.100.0/28 172.16.1.1 100 I * 172.16.100.16/28 172.16.1.1 100 I * 172.16.100.32/28 172.16.1.1 100 I * 172.16.100.48/28 172.16.1.1 100 I
Then we check what we are advertising the ISP. We see nothing!!
jcluser@vMX-addr-0> show route advertising-protocol bgp 172.16.2.2 table Customer_Router (no output) jcluser@vMX-addr-0>
Remember that our export policy only matches on 172.16.100/26 exact. All the routes we are receiving are /28. So, let’s add a static route for the summary route.
[edit routing-instances Customer_Router_VR routing-options] jcluser@vMX-addr-0# set static route 172.16.100/26 reject [edit routing-instances Customer_Router_VR routing-options] jcluser@vMX-addr-0# commit commit complete
And then we check what we are sending to the ISP Router again. The route is being advertised now.
jcluser@vMX-addr-0> show route advertising-protocol bgp 172.16.2.2 table Customer_Router_VR.inet.0 Customer_Router_VR.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path 172.16.100.0/26 Self I
Even though we were able to send the route dynamically to the ISP, we are really not achieving what we wanted. The reason why we made all these changes was to make sure that if all the internal networks went away, the ISP would stop sending us traffic. I am sure you realize that this is not happening, and why, but let’s take a look.
We can simply shutdown the interface connecting to SITE1.
root@vMX-addr-0:/var/home/jcluser # ifconfig lt-0/0/0.10 down root@vMX-addr-0:/var/home/jcluser #
And all the routes we were receiving are obviously gone. However,the static routes is still there, and the ISP is still receiving the information.
jcluser@vMX-addr-0> show route 172.16.100/24 Customer_Router_VR.inet.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Static/5] 00:04:44 Reject ISP_Router_VR.inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[BGP/170] 00:04:44, localpref 100 AS path: 100 I, validation-state: unverified > to 172.16.2.1 via lt-0/0/0.2
If you still remember some of what you read about static routes 😉 , you will know that the requirement for a static route to be active is next-hop reachability. Turns out we are just using our trash can as next hop, so our static route in this case will always be active.
OK, we know now that this is NOT going to work the way we want!! What do we do then?
This is where we finally introduce the idea of aggregate and generated routes. Get comfortable and keep reading.
AGGREGATE ROUTES
Aggregate routes are also manually defined routes, but have some interesting characteristics. They represent a collection of more specific routes, and the key here is “more specific routes”.
Aggregate routes are also defined under the [edit routing-options] hierarchy level by defining a destination prefix, but they do NOT give you the option of configuring a next hop.
Let me repeat that: aggregate routes do NOT let you configure a next hop address.
[edit routing-options aggregate] jcluser@vMX-addr-0# set route 172.16.100/26 next-h? No valid completions
So guess what, you can only point traffic matching an aggregate route to: the trash can!
You can do reject, which is the default, when you don’t specify anything (not an actual keyword), OR discard if you explicitly define it.
[edit routing-options aggregate] jcluser@vMX-addr-0# set route 172.16.100/26 r? No valid completions [edit routing-options aggregate] jcluser@vMX-addr-0# set route 172.16.100/26 d? Possible completions: discard Drop packets to destination; send no ICMP unreachables
There is the first difference between statics and aggregate routes: the NEXT HOP!
Now, the big great awesome difference between aggregates and statics is something called: CONTRIBUTING ROUTES.
Aggregate routes must have at least one contributing route! That is the requirement for aggregate routes to become active.
Let’s go back to the lab and replace the static route with an aggregate route.
We first create the aggregate route:
[edit routing-instances Customer_Router_VR routing-options aggregate] jcluser@vMX-addr-0# set route 172.16.100/26 discard [edit routing-instances Customer_Router_VR routing-options aggregate] jcluser@vMX-addr-0# commit commit complete
And modify the policy:
[edit policy-options policy-statement SUMMARY] jcluser@vMX-addr-0# set term 1 from protocol aggregate [edit policy-options policy-statement SUMMARY] jcluser@vMX-addr-0# show | display set relative set term 1 from protocol aggregate set term 1 from route-filter 172.16.100.0/26 exact set term 1 then accept set term 2 then reject
We then check the status of the new route and we notice that it is HIDDEN!.
jcluser@vMX-addr-0> show route protocol aggregate hidden table Customer_Router_VR.inet.0 Customer_Router_VR.inet.0: 9 destinations, 10 routes (9 active, 0 holddown, 1 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 [Aggregate] 00:02:30 Discard
When we look at the details.
jcluser@vMX-addr-0> show route protocol aggregate hidden table Customer_Router_VR.inet.0 extensive Customer_Router_VR.inet.0: 9 destinations, 10 routes (9 active, 0 holddown, 1 hidden) 172.16.100.0/26 (2 entries, 1 announced) TSI: KRT in-kernel 172.16.100.0/26 -> {} Aggregate Next hop type: Discard, Next hop index: 0 Address: 0xce30670 Next-hop reference count: 1 State: <Hidden Int Ext> Inactive reason: Unusable path Local AS: 100 Age: 1:40 Validation State: unverified Task: Aggregate AS path: I Flags: Discard Depth: 0 Inactive
We find “inactive reason: unusable path”. Then we remember that we shut down the interface lt-0/0/0.10 before! 😊
root@vMX-addr-0:/var/home/jcluser # ifconfig lt-0/0/0.10 up root@vMX-addr-0:/var/home/jcluser #
We fix that, and now the route is a valid route. Thought we notice that it is not active.
jcluser@vMX-addr-0> show route 172.16/16 table Customer_Router_VR.inet protocol aggregate Customer_Router_VR.inet.0: 9 destinations, 10 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 [Aggregate/130] 00:00:21 Discard
Can you figure out why?
Check the routing table again, this time without specifying protocol aggregate.
jcluser@vMX-addr-0> show route 172.16.100/26 exact table Customer_Router_VR.inet.0 Customer_Router_VR.inet.0: 9 destinations, 10 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Static/5] 00:32:43 Reject [Aggregate/130] 00:02:18 Discard
Aha! We never removed the static route that we had previously configured, and if you pay attention to the values between square brackets you will see that the default preference value for aggregate routes is 130, and the default for static routes is 5. Lower is better, thus the static route is selected as the active route.
We need to fix this if we want BGP to advertise the route, as it only considers active routes for advertisement by default.
We can just deactivate the static route:
[edit] jcluser@vMX-addr-0# top deactivate routing-instances Customer_Router_VR routing-options static [edit] jcluser@vMX-addr-0# commit commit complete
And here we go:
jcluser@vMX-addr-0> show route 172.16/16 table Customer_Router_VR.inet protocol aggregate Customer_Router_VR.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Aggregate/130] 00:04:15 Discard
Our aggregate is active, because the static is no longer there, though don’t forget the magic sauce: Contributing routes!
If we look at the extensive show route output, we can see the list of routes contributing to this aggregate.
jcluser@vMX-addr-0> show route 172.16/16 table Customer_Router_VR.inet protocol aggregate extensive Customer_Router_VR.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) 172.16.100.0/26 (1 entry, 1 announced) TSI: KRT in-kernel 172.16.100.0/26 -> {} Page 0 idx 1, (group EBGP type External) Type 1 val 0xba0bfc0 (adv_entry) Advertised metrics: Nexthop: Self AS path: [100] I (LocalAgg) Communities: Path 172.16.100.0 Vector len 4. Val: 1 *Aggregate Preference: 130 Next hop type: Discard, Next hop index: 0 Address: 0xce30670 Next-hop reference count: 2 State: <Active Int Ext> Local AS: 100 Age: 5:05 Validation State: unverified Task: Aggregate Announcement bits (3): 0-KRT 1-BGP_RT_Background 2-Resolve tree 1 AS path: I (LocalAgg) Flags: DiscardDepth: 0Active AS path list: AS path: I Refcount: 4 Contributing Routes (4): 172.16.100.0/28 proto BGP 172.16.100.16/28 proto BGP 172.16.100.32/28 proto BGP 172.16.100.48/28 proto BGP
Remember again: Contributing routes are more specific routes within the range defined by your aggregate. And, as long as one of this routes exists in the routing table, your aggregate with be active in the routing table.
If your aggregate is 172.16.1/24, any route that begins with 172.16.1.0 in the first 24 bits and is more specific (subnet mask is longer than 24), will be a contributing route. 172.16.1.0/26, 172.16.1.128/26, 172.16.1.192/28, 172.16.1.208/28 and 172.16.1.240/28 are examples of contributing routes for 172.16.1/24.
Notice that I highlighted ANY ROUTE. That means any route that is more specific. You could configure an aggregate as 0/0, and every single route in the routing table will be more specific than 0/0, and will be a contributing route.
What if I only want certain routes to be contributing routes, and I want the aggregate to go away when those particular routes go away, regardless of the presence of other specific routes?
The answer is: Routing Policies!!!
Let’s go back to the lab to see how.
Here is our new topology and config:
[edit interfaces] jcluser@vMX-addr-0# show | display set relative set lt-0/0/0 unit 1 encapsulation ethernet set lt-0/0/0 unit 1 peer-unit 2 set lt-0/0/0 unit 1 family inet address 172.16.2.1/24 set lt-0/0/0 unit 2 encapsulation ethernet set lt-0/0/0 unit 2 peer-unit 1 set lt-0/0/0 unit 2 family inet address 172.16.2.2/24 set lt-0/0/0 unit 10 encapsulation ethernet set lt-0/0/0 unit 10 peer-unit 11 set lt-0/0/0 unit 10 family inet address 172.16.1.2/30 set lt-0/0/0 unit 11 encapsulation ethernet set lt-0/0/0 unit 11 peer-unit 10 set lt-0/0/0 unit 11 family inet address 172.16.1.1/30 set lt-0/0/0 unit 20 encapsulation ethernet set lt-0/0/0 unit 20 peer-unit 21 set lt-0/0/0 unit 20 family inet address 172.16.1.130/30 set lt-0/0/0 unit 21 encapsulation ethernet set lt-0/0/0 unit 21 peer-unit 20 set lt-0/0/0 unit 21 family inet address 172.16.1.129/30 set lo0 unit 1 family inet address 172.16.100.1/28 set lo0 unit 1 family inet address 172.16.100.17/28 set lo0 unit 1 family inet address 172.16.100.33/28 set lo0 unit 1 family inet address 172.16.100.49/28 set lo0 unit 2 family inet address 172.16.100.65/28 set lo0 unit 2 family inet address 172.16.100.81/28 set lo0 unit 2 family inet address 172.16.100.97/28 set lo0 unit 2 family inet address 172.16.100.113/28 [edit routing-instances] jcluser@vMX-addr-0# show | display set relative set Customer_Router_VR instance-type virtual-router set Customer_Router_VR interface lt-0/0/0.1 set Customer_Router_VR interface lt-0/0/0.10 set Customer_Router_VR interface lt-0/0/0.20 set Customer_Router_VR routing-options autonomous-system 100 set Customer_Router_VR routing-options autonomous-system independent-domain set Customer_Router_VR protocols bgp group IBGP type internal set Customer_Router_VR protocols bgp group IBGP neighbor 172.16.1.1 set Customer_Router_VR protocols bgp group IBGP neighbor 172.16.1.129 set Customer_Router_VR protocols bgp group EBGP neighbor 172.16.2.2 peer-as 200 set ISP_Router_VR instance-type virtual-router set ISP_Router_VR interface lt-0/0/0.2 set ISP_Router_VR routing-options autonomous-system 200 set ISP_Router_VR protocols bgp group EBGP neighbor 172.16.2.1 peer-as 100 set SITE1_GW instance-type virtual-router set SITE1_GW interface lt-0/0/0.11 set SITE1_GW interface lo0.1 set SITE1_GW routing-options autonomous-system 100 set SITE1_GW routing-options autonomous-system independent-domain set SITE1_GW protocols bgp group IBGP type internal set SITE1_GW protocols bgp group IBGP export LOOPBACK set SITE1_GW protocols bgp group IBGP neighbor 172.16.1.2 set SITE2_GW instance-type virtual-router set SITE2_GW interface lt-0/0/0.21 set SITE2_GW interface lo0.2 set SITE2_GW routing-options autonomous-system 100 set SITE2_GW routing-options autonomous-system independent-domain set SITE2_GW protocols bgp group IBGP type internal set SITE2_GW protocols bgp group IBGP export LOOPBACK set SITE2_GW protocols bgp group IBGP neighbor 172.16.1.130 [edit policy-options policy-statement LOOPBACK] jcluser@vMX-addr-0# show | display set relative set term 1 from protocol direct set term 1 from interface lo0.1 set term 1 from interface lo0.2 set term 1 then accept
There are now two different sites connected to the Customer Router. Each site is advertising 4 different subnets as shown:
The Customer Router should summarize the routes from each site and send that summary to the other site, and should summarize the entire range from both sites, and advertise that summary and only that summary to the ISP Router (no specific routes). The advertisements should stop if all the subnets go away.
Based on our current configuration the Customer_Router is receiving the subnets from the SITES, is advertising everything to the ISP router, but nothing to the SITE GWs.
jcluser@vMX-addr-0> show route 172.16.100/24 table SITE1_GW.inet.0 terse | match /2 * ? 172.16.100.0/28 D 0 >lo0.1 * ? 172.16.100.16/28 D 0 >lo0.1 * ? 172.16.100.32/28 D 0 >lo0.1 * ? 172.16.100.48/28 D 0 >lo0.1 jcluser@vMX-addr-0> show route 172.16.100/24 table SITE2_GW.inet.0 terse | match /2 * ? 172.16.100.64/28 D 0 >lo0.2 * ? 172.16.100.80/28 D 0 >lo0.2 * ? 172.16.100.96/28 D 0 >lo0.2 * ? 172.16.100.112/28 D 0 >lo0.2 jcluser@vMX-addr-0> route 172.16.100/24 table Customer_Router_VR.inet.0 | match "172.16" 172.16.100.0/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.1 via lt-0/0/0.10 172.16.100.16/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.1 via lt-0/0/0.10 172.16.100.32/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.1 via lt-0/0/0.10 172.16.100.48/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.1 via lt-0/0/0.10 172.16.100.64/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.129 via lt-0/0/0.20 172.16.100.80/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.129 via lt-0/0/0.20 172.16.100.96/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.129 via lt-0/0/0.20 172.16.100.112/28 *[BGP/170] 01:56:38, localpref 100 > to 172.16.1.129 via lt-0/0/0.20 jcluser@vMX-addr-0> show route 172.16.100/24 table ISP_Router_VR.inet.0 | match "172.16" 172.16.100.0/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.16/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.32/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.48/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.64/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.80/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.96/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2 172.16.100.112/28 *[BGP/170] 01:54:48, localpref 100 > to 172.16.2.1 via lt-0/0/0.2
We can solve the lack of advertisements to the SITE GWs quite easily.
We first create a couple of aggregate routes:
[edit routing-instances Customer_Router_VR routing-options] jcluser@vMX-addr-0# set aggregate route 172.16.100/26 discard [edit routing-instances Customer_Router_VR routing-options] jcluser@vMX-addr-0# set aggregate route 172.16.100.64/26 discard [edit routing-instances Customer_Router_VR routing-options] jcluser@vMX-addr-0# commit commit complete jcluser@vMX-addr-0> show route protocol aggregate table Customer_Router_VR.inet.0 Customer_Router_VR.inet.0: 16 destinations, 16 routes (16 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Aggregate/130] 00:00:31 Discard 172.16.100.64/26 *[Aggregate/130] 00:00:31 Discard jcluser@vMX-addr-0> show route protocol aggregate table Customer_Router_VR.inet.0 Customer_Router_VR.inet.0: 16 destinations, 16 routes (16 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Aggregate/130] 00:00:31 Discard 172.16.100.64/26 *[Aggregate/130] 00:00:31 Discard
Then we create an export policy to advertise the aggregates to the SITES.
[edit policy-options] jcluser@vMX-addr-0# show | display set relative | match AGG set policy-statement AGGREGATE1 term 1 from route-filter 172.16.100.64/26 exact set policy-statement AGGREGATE1 term 1 then accept set policy-statement AGGREGATE2 term 1 from route-filter 172.16.100.0/26 exact set policy-statement AGGREGATE2 term 1 then accept [edit routing-instances Customer_Router_VR protocols bgp group IBGP] jcluser@vMX-addr-0# set neighbor 172.16.1.1 export AGGREGATE1 [edit routing-instances Customer_Router_VR protocols bgp group IBGP] jcluser@vMX-addr-0# set neighbor 172.16.1.129 export AGGREGATE2 [edit routing-instances Customer_Router_VR protocols bgp group IBGP] jcluser@vMX-addr-0# commit commit complete
We check the routing tables of the SITE GW routers and yeap! Routes are there now.
jcluser@vMX-addr-0> show route table SITE1_GW.inet.0 protocol bgp SITE1_GW.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.64/26 *[BGP/170] 00:00:27, localpref 100 AS path: I, validation-state: unverified > to 172.16.1.2 via lt-0/0/0.11 jcluser@vMX-addr-0> show route table SITE2_GW.inet.0 protocol bgp SITE2_GW.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[BGP/170] 00:00:33, localpref 100 AS path: I, validation-state: unverified > to 172.16.1.130 via lt-0/0/0.21
We should in fact be able to ping from one site to the other.
jcluser@vMX-addr-0# run ping 172.16.100.65 source 172.16.100.1 routing-instance SITE1_GW rapid PING 172.16.100.65 (172.16.100.65): 56 data bytes !!!!! --- 172.16.100.65 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.310/0.424/0.697/0.141 ms
First problem solved! Let’s now tackle the second one. We should not be advertising everything to the ISP router as we are, only a summary for the entire range of addresses from the two Sites.
You probably thought about it already: a summary => a third aggregate route, and a new policy.
[edit routing-instances Customer_Router_VR routing-options aggregate] jcluser@vMX-addr-0# show route 172.16.100.0/26 discard; route 172.16.100.64/26 discard; [edit routing-instances Customer_Router_VR routing-options aggregate] jcluser@vMX-addr-0# set route 172.16.100.0/25 discard [edit policy-options] jcluser@vMX-addr-0# copy policy-statement AGGREGATE2 to policy-statement AGGREGATE3 [edit policy-options] jcluser@vMX-addr-0# edit policy-statement AGGREGATE3 [edit policy-options policy-statement AGGREGATE3] jcluser@vMX-addr-0# replace pattern /26 with /25 [edit policy-options policy-statement AGGREGATE3] jcluser@vMX-addr-0# show | display set relative set term 1 from route-filter 172.16.100.0/25 exact set term 1 then accept [edit routing-instances Customer_Router_VR protocols bgp group EBGP] jcluser@vMX-addr-0# set export AGGREGATE3 [edit routing-instances Customer_Router_VR protocols bgp group EBGP] jcluser@vMX-addr-0# commit commit complete
We check the routing table of ISP Router and…
jcluser@vMX-addr-0> show route 172.16.100/24 table ISP_Router_VR.inet.0 terse ISP_Router_VR.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both A V Destination P Prf Metric 1 Metric 2 Next hop AS path * ? 172.16.100.0/25 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.0/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.16/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.32/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.48/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.64/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.80/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.96/28 B 170 100 100 I unverified >172.16.2.1 * ? 172.16.100.112/28 B 170 100 100 I unverified >172.16.2.1
Wait! We see the aggregate route, but we still see all 8 specific routes. WHY?
Well, BGP advertisement rules, and default policy: “An active IBGP route is advertised to EBGP neighbors by default.”
We need to make sure that our policy overrides this behavior, so we go back and slightly change it:
[edit policy-options policy-statement AGGREGATE3] jcluser@vMX-addr-0# set term 2 then reject [edit policy-options policy-statement AGGREGATE3] jcluser@vMX-addr-0# commit commit complete
We check the routing table of ISP Router again:
jcluser@vMX-addr-0> show route 172.16.100/24 table ISP_Router_VR.inet.0 terse ISP_Router_VR.inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both A V Destination P Prf Metric 1 Metric 2 Next hop AS path * ? 172.16.100.0/25 B 170 100 100 I unverified >172.16.2.1
And that looks much better. Second problem solved!
We also said that these advertisements should stop when the subnets go away. We really don’t need to do anything at this point, but let’s check the contributing routes to see how this will work:
For the 172.16.100/26 aggregate, only the 4 subnets received from SITE1_GW are contributing routes. When these 4 routes go away, the aggregate will go away.
jcluser@vMX-addr-0> show route 172.16.100.0/26 exact table Customer_Router_VR.inet.0 extensive | find contributing Contributing Routes (4): 172.16.100.0/28 proto BGP 172.16.100.16/28 proto BGP 172.16.100.32/28 proto BGP 172.16.100.48/28 proto BGP
For the 172.16.100.64/26 aggregate, only the 4 subnets received from SITE2_GW are contributing routes. When these 4 routes go away, the aggregate will go away:
jcluser@vMX-addr-0> show route 172.16.100.64/26 exact table Customer_Router_VR.inet.0 extensive | find contributing Contributing Routes (4): 172.16.100.64/28 proto BGP 172.16.100.80/28 proto BGP 172.16.100.96/28 proto BGP 172.16.100.112/28 proto BGP
And for the 172.16.100.0/25 aggregate we have:
jcluser@vMX-addr-0> show route 172.16.100.0/25 exact table Customer_Router_VR.inet.0 extensive | find contributing Contributing Routes (2): 172.16.100.0/26 proto Aggregate 172.16.100.64/26 proto Aggregate
Interesting!!! I bet you were expecting 172.16.100.0/28, 172.16.100.16/28, 172.16.100.32/28 and so on to all be listed here. But a route can only be a contributing route of ONE aggregate. The 8 subnets are contributing routes of the /26 aggregates already.
SO:
- if the 4 subnets from SITE1 go away, 172.16.100.0/26 goes away,
- if the 4 subnets from SITE2 go away, 172.16.100.65/26 goes away, and
- if all 8 subnets go away, the two /26 aggregates which are the contributing routes of the /25 go away, Thus the /25 goes away too!
Now, one more thing before we move on to GENERATED routes: what if I do not want all the more specific routes within a range to be considered contributing routes?
Here is our new sample topology to look at this next question:
The situation is here is the following. SITE_GW1 and SITE-GW2 are both learning about subnets 172.16.100/28, 172.16.100.16/28, 172.16.100.32/28 and 172.16.100.64/28 from some IGP. Customer Router_1 and Customer_Router_2 will aggregate these subnets and advertise the aggregate to ISP_Router1 and ISP_Router2.
However, we need to make sure that the aggregate is only advertised if the router has specific routes to 172.16.100/28 and 172.16.100.48/28 (we only care about these two subnets). In other words, we want the Customer routers to stop advertising the aggregate if these two prefixes are no longer known. Let’s say that these two destinations are critical and we want Customer_Router_1 to stop advertising the aggregate when these two routes go away, so that the ISP starts sending traffic towards Customer_Router_2, for example.
What we need to do is make sure that ONLY these subnets are contributing routes. Let’s take a look at how to achieve this.
I am going to build only the top half of the topology, to demonstrate.
[edit interfaces] jcluser@vMX-addr-0# show | display set relative set lt-0/0/0 unit 1 encapsulation ethernet set lt-0/0/0 unit 1 peer-unit 2 set lt-0/0/0 unit 1 family inet address 172.16.1.1/24 set lt-0/0/0 unit 2 encapsulation ethernet set lt-0/0/0 unit 2 peer-unit 1 set lt-0/0/0 unit 2 family inet address 172.16.1.2/24 set lt-0/0/0 unit 3 encapsulation ethernet set lt-0/0/0 unit 3 peer-unit 4 set lt-0/0/0 unit 3 family inet address 172.16.2.1/24 set lt-0/0/0 unit 4 encapsulation ethernet set lt-0/0/0 unit 4 peer-unit 3 set lt-0/0/0 unit 4 family inet address 172.16.2.2/24 set lo0 unit 0 family inet address 172.16.100.1/28 set lo0 unit 0 family inet address 172.16.100.17/28 set lo0 unit 0 family inet address 172.16.100.33/28 set lo0 unit 0 family inet address 172.16.100.49/28 [edit routing-instances] jcluser@vMX-addr-0# show | display set relative set Customer_Router_1 instance-type virtual-router set Customer_Router_1 interface lt-0/0/0.2 set Customer_Router_1 interface lt-0/0/0.3 set Customer_Router_1 routing-options aggregate route 172.16.100.0/26 discard set Customer_Router_1 routing-options autonomous-system 100 set Customer_Router_1 routing-options autonomous-system independent-domain set Customer_Router_1 protocols bgp group IBGP neighbor 172.16.1.1 peer-as 100 set Customer_Router_1 protocols bgp group EBGP export aggregate set Customer_Router_1 protocols bgp group EBGP neighbor 172.16.2.2 peer-as 200 set ISP_Router_1 instance-type virtual-router set ISP_Router_1 interface lt-0/0/0.4 set ISP_Router_1 routing-options autonomous-system 200 set ISP_Router_1 routing-options autonomous-system independent-domain set ISP_Router_1 protocols bgp group EBGP neighbor 172.16.2.1 peer-as 100 set SITE_GW1 instance-type virtual-router set SITE_GW1 interface lt-0/0/0.1 set SITE_GW1 interface lo0.0 set SITE_GW1 routing-options autonomous-system 100 set SITE_GW1 routing-options autonomous-system independent-domain set SITE_GW1 protocols bgp group IBGP export loopback set SITE_GW1 protocols bgp group IBGP neighbor 172.16.1.2 peer-as 100 [edit policy-options policy-statement loopback] jcluser@vMX-addr-0# show| display set relative set term 1 from protocol direct set term 1 from interface lo0.0 set term 1 then accept [edit policy-options policy-statement aggregate] jcluser@vMX-addr-0# show | display set relative set term 1 from protocol aggregate set term 1 then accept set term 2 then reject
As in previous examples, with our current configuration Customer_Router_1 will be advertising the aggregate route only to ISP_Router_1, as required:
jcluser@vMX-addr-0> show route advertising-protocol bgp 172.16.2.2 Customer_Router_1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 172.16.100.0/26 Self I
However, the contributing routes of the aggregate are all 4 subnets:
jcluser@vMX-addr-0> show route 172.16.100/26 exact table Customer_Router_1.inet.0 extensive | find contributing Contributing Routes (4): 172.16.100.0/28 proto BGP 172.16.100.16/28 proto BGP 172.16.100.32/28 proto BGP 172.16.100.48/28 proto BGP
We need only 172.16.100/28 and 172.16.100.48/28 to be contributing routes. To achieve this we are going to create another routing-policy:
[edit policy-options policy-statement contributing] jcluser@vMX-addr-0# show| display set relative set term 1 from route-filter 172.16.100.0/28 exact set term 1 from route-filter 172.16.100.48/28 exact set term 1 then accept set term 2 then reject
And apply it to the aggregate route itself:
[edit routing-instances Customer_Router_1 routing-options] jcluser@vMX-addr-0# set aggregate route 172.16.100.0/26 policy contributing
And now, only the two routes that we are interested on are considered contributing routes as we wanted:
jcluser@vMX-addr-0> route 172.16.100/26 exact table Customer_Router_1.inet.0 extensive | find contributing Contributing Routes (2): 172.16.100.0/28 proto BGP 172.16.100.48/28 proto BGP
At this point we have probably covered more stuff about static and aggregate routes that you could ever imagine, but there is yet another route type that we need to talk about.
GENERATED ROUTES
This types of routes are similar to aggregate routes: they need contributing routes to exist! However, as you probably imagine there is one big difference, else why have them?
The big difference is that while aggregate routes do NOT allow you to configure a next-hop but only the trash can, generated routes do NOT allow you to configure either, though they DO HAVE a next-hop = a neighbor address.
[edit] jcluser@vMX-addr-0# set routing-options generate route 172.16.100/26 discard? No valid completions [edit] jcluser@vMX-addr-0# set routing-options generate route 172.16.100/26 next-hop? No valid completions
But, if the router does not allow you to configure a next-hop, where does it get it from?
The answer is: the router figures it out! The generated route inherits the next-hop of the primary contributing route, which is selected based on metric, preference value, and other attributes. Let’s take a look at an example:
The idea here is that Customer Router has a summary route, that requires contributing routes, and goes away when those contributing routes go away. The summary can be advertised to the ISP router, just like we did before with aggregate routes.
However, in this case rather than throwing away a packet when a specific subnet is not know, the packet is sent to the next hop of the aggregate. You will find that this is described as gateway of last resource in some documents.
The address of the next-hop for the generated route, will be inherited from one of the contributing routes.
Let’s take a look using the same configuration in the previous example, though for now, we are going to remove the export policy from EBGP:
[edit routing-instances Customer_Router_1 protocols bgp group EBGP] jcluser@vMX-addr-0# delete export [edit routing-instances Customer_Router_1 protocols bgp group EBGP] jcluser@vMX-addr-0# commit commit complete
Let’s check that we are receiving all the routes:
jcluser@vMX-addr-0> show route receive-protocol bgp 172.16.1.1 table Customer_Router_1.inet.0 Customer_Router_1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 172.16.100.0/28 172.16.1.1 100 I * 172.16.100.16/28 172.16.1.1 100 I * 172.16.100.32/28 172.16.1.1 100 I * 172.16.100.48/28 172.16.1.1 100 I
We know that because of the BGP default policy these will all be advertised to the ISP router:
jcluser@vMX-addr-0> show route advertising-protocol bgp 172.16.2.2 Customer_Router_1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 172.16.100.0/28 Self I * 172.16.100.16/28 Self I * 172.16.100.32/28 Self I * 172.16.100.48/28 Self I
To stop these routes from being advertised, and replace them with a summary we are going to create a generated route, and export it with a new policy.
[edit routing-instances Customer_Router_1 routing-options] jcluser@vMX-addr-0# set generate route 172.16.100.0/26
Now, you might find this interesting, when we try to configure our new policy.
[edit policy-options policy-statement generated] jcluser@vMX-addr-0# set term 1 from protocol g? No valid completions
We find that there is no option for protocol generated. We need to still to do:
from protocol aggregate.
In fact, we can just reapply the exact same policy we were using before:
[edit policy-options policy-statement aggregate] jcluser@vMX-addr-0# show| display set relative set term 1 from protocol aggregate set term 1 then accept set term 2 then reject [edit routing-instances Customer_Router_1 protocols bgp group EBGP] jcluser@vMX-addr-0# set export aggregate [edit routing-instances Customer_Router_1 protocols bgp group EBGP] jcluser@vMX-addr-0# commit commit complete
We check what we are now advertising to the ISP router, and find that only the summary is being advertised as we wanted:
jcluser@vMX-addr-0> show route advertising-protocol bgp 172.16.2.2 Customer_Router_1.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 172.16.100.0/26 Self I
So, the policy is exactly the same but instead of doing set routing-options aggregate we did set routing-options generated. What is the difference?
Let’s take a look at the route. But first, just for comparison, let me create an aggregate route also.
[edit routing-instances Customer_Router_1 routing-options] jcluser@vMX-addr-0# set aggregate route 172.16.100.64/26 discard [edit interfaces lo0 unit 0] jcluser@vMX-addr-0# set family inet address 172.16.100.65/28 [edit routing-instances Customer_Router_1 routing-options] jcluser@vMX-addr-0# commit commit complete
Here are our two routes so that we can compare them:
GENERATED: jcluser@vMX-addr-0> show route 172.16.100/26 exact table Customer_Router_1 Customer_Router_1.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Aggregate/130] 00:00:25, metric2 0 > to 172.16.1.1 via lt-0/0/0.2 AGGREGATE: jcluser@vMX-addr-0> show route 172.16.100.64/26 exact table Customer_Router_1 Customer_Router_1.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.64/26 *[Aggregate/130] 00:00:27 Discard
I hope the difference is now easy to spot: the generated route has an actual next-hop (172.16.1.1) and a metric, while the aggregate is pointing to the trash can (discard).
Besides that, there is really not much difference. They both have the same preference value (130) and they both are referred to as “Aggregate” routes.
In fact, you can enter: show route protocols aggregate, and obtain information about the two routes:
jcluser@vMX-addr-0> show route protocol aggregate table Customer_Router_1.inet.0 Customer_Router_1.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 172.16.100.0/26 *[Aggregate/130] 00:05:50, metric2 0 > to 172.16.1.1 via lt-0/0/0.2 172.16.100.64/26 *[Aggregate/130] 00:05:50 Discard
Let’s check more details:
jcluser@vMX-addr-0> show route protocol aggregate table Customer_Router_1.inet.0 Customer_Router_1.inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) 172.16.100.0/26 (1 entry, 1 announced) TSI: KRT in-kernel 172.16.100.0/26 -> {indirect(1048574)} Page 0 idx 0, (group EBGP type External) Type 1 val 0xba0c7bc (adv_entry) Advertised metrics: Nexthop: Self AS path: [100] I Communities: Path 172.16.100.0 Vector len 4. Val: 0 *Aggregate Preference: 130 Next hop type: Indirect, Next hop index: 0 Address: 0xce31f90 Next-hop reference count: 12 Next hop type: Router, Next hop index: 665 Next hop: 172.16.1.1 via lt-0/0/0.2, selected <= REAL NEXT HOP Session Id: 0x140 Protocol next hop: 172.16.1.1 Indirect next hop: 0xba3d900 1048574 INH Session ID: 0x141 State: <Active Int Ext> Local AS: 100 Age: 6:56 Metric2: 0 Validation State: unverified Task: Aggregate Announcement bits (3): 0-KRT 2-BGP_RT_Background 3-Resolve tree 1 AS path: I Flags: Generate ResolveDepth: 0Active Contributing Routes (4): 172.16.100.0/28 proto BGP 172.16.100.16/28 proto BGP 172.16.100.32/28 proto BGP 172.16.100.48/28 proto BGP Indirect next hops: 1 Protocol next hop: 172.16.1.1 Indirect next hop: 0xba3d900 1048574 INH Session ID: 0x141 Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 172.16.1.1 via lt-0/0/0.2 Session Id: 0x140 172.16.1.0/24 Originating RIB: Customer_Router_1.inet.0 Node path count: 1 Forwarding nexthops: 1 Next hop type: Interface Nexthop: via lt-0/0/0.2 172.16.100.64/26 (1 entry, 1 announced) TSI: KRT in-kernel 172.16.100.64/26 -> {} Page 0 idx 0, (group EBGP type External) Type 1 val 0xba0c650 (adv_entry) Advertised metrics: Nexthop: Self AS path: [100] I (LocalAgg) Communities: Path 172.16.100.64 Vector len 4. Val: 0 *Aggregate Preference: 130 Next hop type: Discard, Next hop index: 0 <= TRASH CAN AS NEXT HOP Address: 0xce30670 Next-hop reference count: 2 State: <Active Int Ext> Local AS: 100 Age: 6:56 Validation State: unverified Task: Aggregate Announcement bits (3): 0-KRT 2-BGP_RT_Background 3-Resolve tree 1 AS path: I (LocalAgg) Flags: DiscardDepth: 0Active AS path list: AS path: I Refcount: 1 Contributing Routes (1): 172.16.100.64/28 proto BGP
In this example is it not easy to tell which route was used to select the next-hop, so let me use some little tricks to show you the behavior:
[edit policy-options policy-statement loopback] jcluser@vMX-addr-0# show| display set relative set term 1 from route-filter 172.16.100.0/28 exact set term 1 then next-hop 172.16.1.11 set term 1 then accept set term 2 from route-filter 172.16.100.16/28 exact set term 2 then next-hop 172.16.1.12 set term 2 then accept set term 4 from route-filter 172.16.100.32/28 exact set term 4 then next-hop 172.16.1.14 set term 4 then accept set term 3 from route-filter 172.16.100.48/28 exact set term 3 then next-hop 172.16.1.13 set term 3 then accept [edit routing-instances Customer_Router_1 protocols bgp group IBGP] jcluser@vMX-addr-0# set accept-remote-nexthop [edit policy-options policy-statement loopback] jcluser@vMX-addr-0# commit commit complete jcluser@vMX-addr-0> show route receive-protocol bgp 172.16.1.1 table Customer_Router_1.inet.0 Customer_Router_1.inet.0: 10 destinations, 10 routes (9 active, 0 holddown, 1 hidden) Prefix Nexthop MED Lclpref AS path * 172.16.100.0/28 172.16.1.11 100 I * 172.16.100.16/28 172.16.1.12 100 I * 172.16.100.32/28 172.16.1.14 100 I * 172.16.100.48/28 172.16.1.13 100 I
The routes now have different next-hops, and when we can check the aggregate route again, and compare the contributing routes to figure out which one was selected as the primary route and why:
jcluser@vMX-addr-0> show route 172.16.100.0/26 exact extensive table Customer_Router_1.inet.0 | match "next hop" Next hop type: Indirect, Next hop index: 0 Next hop type: Router, Next hop index: 672 Next hop: 172.16.1.11 via lt-0/0/0.2, selected Protocol next hop: 172.16.1.11 Indirect next hop: 0xba3f700 1048577 INH Session ID: 0x14e Indirect next hops: 1 Protocol next hop: 172.16.1.11 Indirect next hop: 0xba3f700 1048577 INH Session ID: 0x14e Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 172.16.1.11 via lt-0/0/0.2 Next hop type: Interface
I can change the next-hop of the first route, and the next-hop of the aggregate also changes:
[edit policy-options policy-statement loopback term 1] jcluser@vMX-addr-0# set then next-hop 172.16.1.111 [edit policy-options policy-statement loopback term 1] jcluser@vMX-addr-0# commit commit complete jcluser@vMX-addr-0> show route 172.16.100.0/26 exact extensive table Customer_Router_1.inet.0 | match "next hop" Next hop type: Indirect, Next hop index: 0 Next hop type: Router, Next hop index: 673 Next hop: 172.16.1.111 via lt-0/0/0.2, selected Protocol next hop: 172.16.1.111 Indirect next hop: 0xba3f400 1048578 INH Session ID: 0x14c Indirect next hops: 1 Protocol next hop: 172.16.1.111 Indirect next hop: 0xba3f400 1048578 INH Session ID: 0x14c Indirect path forwarding next hops: 1 Next hop type: Router Next hop: 172.16.1.111 via lt-0/0/0.2 Next hop type: Interface
So, the primary contributing route in this case, is the route with the lowest value.
You can change this using a policy that changes which routes are contributing routes as we did before, or you can play with the metric, or preference value, to make one route preferred over another. The router takes into account the metric, preference value, and subnet mask length of the routes to choose which contributing route is the primary.
I am attaching a document that shows you some examples changing metric, preference and subnet mask length.
IN SUMMARY
That was a long article, which you were probably not expecting, so here is a quick summary of the things that we covered, that I hope you find helpful:
P.S. Though I try to make the examples similar to real cases, keep in mind that the intention of the examples is to demonstrate how the different types of manual routes, and their options work, not to show you how to necessarily do things in the real world, though I have found some of the tricks I showed you useful to solve or troubleshot some of my customers issues. 😉
Recent Comments