One thing that Juniper excels
at is the flexibility of leaking routes from one routing table to another.
JUNOS has so many ways to leak routes from one routing table to the other that
it’s sometimes confusing. What I’ll be doing here is try to clarify as much as
possible the techniques commonly used to leak from one routing table to
another.
Let’s begin by the first
method which is using RIB groups.
You can consider RIB Groups as
a bucket that contains routes from different routing tables then you take the
routes from this bucket and put it in the desired routing table. We can split
the RIB Group usage into two main sections:
1. Directly connected Interfaces RIB groups
2. Dynamic Routing Protocols RIB groups.
The only difference between
the two is that the order of syntax. We’ll get to that later
Let’s check the following
diagram
Router R3 is connected to R2
via interface Ge-0/0/2 which is under Virtual-Router R2. Meanwhile, R1 and R4
are connected to R3 in inet.0 RT.
R3 is also has R1 and R4 as
OSPF neighbors in inet.0 RT whilst R2 is an OSPF neighbor in R2.inet.0 RT.
We can safely assume that all
the received routes from R2 is completely segregated from routes received from
R1 and R4.
Let’s check how the routing
table looks like on R3
root@R3>
show route
inet.0: 12 destinations, 12 routes (12 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
1.1.1.1/32 *[OSPF/10] 00:01:22, metric 1
> to 10.0.13.1 via
ge-0/0/1.0
3.3.3.3/32 *[Direct/0] 00:01:37
> via lo0.10
4.4.4.4/32 *[OSPF/10] 00:01:22, metric 1
> to 10.0.34.4 via
ge-0/0/3.0
10.0.12.0/24 *[OSPF/10] 00:01:22, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
10.0.13.0/24 *[Direct/0] 00:01:37
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:01:37
Local via ge-0/0/1.0
10.0.14.0/24 *[OSPF/10] 00:01:22, metric 2
to 10.0.13.1 via
ge-0/0/1.0
> to 10.0.34.4 via
ge-0/0/3.0
10.0.24.0/24 *[OSPF/10] 00:01:22, metric 2
> to 10.0.34.4 via
ge-0/0/3.0
10.0.34.0/24 *[Direct/0] 00:01:37
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:01:37
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:01:39, metric 1
MultiRecv
R2.inet.0: 4 destinations, 4 routes (4 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
2.2.2.2/32 *[OSPF/10] 00:01:17, metric 1
> to 10.0.23.2 via
ge-0/0/2.0
10.0.23.0/24 *[Direct/0] 00:01:37
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 00:01:37
Local via ge-0/0/2.0
224.0.0.5/32 *[OSPF/10] 00:01:39, metric 1
MultiRecv
Now let’s create a RIB group to share the interface
routes between inet.0 and R2.inet.0 routing tables.
routing-options
{
rib-groups {
DIRECT-ROUTES {
import-rib [ inet.0 R2.inet.0 ];
}
}
}
Here, we created a RIB group called DIRECT-ROUTES which
contains the routes of inet.0 and R2.inet.0 routing tables.
An important thing to remember
here as we mentioned earlier, when importing routes of a directly connected
interfaces, the sequence of routing tables between the brackets doesn’t matter;
like if you typed R2.inet.0 before inet.0 that wouldn’t make a difference, unlike
when importing routes from dynamic protocols which does make a difference.
Now here’s the tricky part when it comes to applying the
RIB group to the routing-instance. I’ll put it in simple words
If you want to import routes from inet.0 to R2.inet.0,
use the interface-routes under the routing options of inet.0
Here’s what the configuration looks like
routing-options
{
interface-routes {
rib-group inet DIRECT-ROUTES;
}
}
And here’s the result
root@R3>
show route
inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
1.1.1.1/32 *[OSPF/10] 00:32:24, metric 1
> to 10.0.13.1 via
ge-0/0/1.0
3.3.3.3/32 *[Direct/0] 00:32:39
> via lo0.10
4.4.4.4/32 *[OSPF/10] 00:32:24, metric 1
> to 10.0.34.4 via
ge-0/0/3.0
10.0.12.0/24 *[OSPF/10] 00:32:24, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
10.0.13.0/24 *[Direct/0] 00:32:39
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:32:39
Local via ge-0/0/1.0
10.0.14.0/24 *[OSPF/10] 00:32:24, metric 2
to 10.0.13.1 via
ge-0/0/1.0
> to 10.0.34.4 via
ge-0/0/3.0
10.0.24.0/24 *[OSPF/10] 00:32:24, metric 2
> to 10.0.34.4 via
ge-0/0/3.0
10.0.34.0/24 *[Direct/0] 00:32:39
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:32:39
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:32:41, metric 1
MultiRecv
R2.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
2.2.2.2/32 *[OSPF/10] 00:32:19, metric 1
> to 10.0.23.2 via
ge-0/0/2.0
3.3.3.3/32 *[Direct/0]
00:02:35
> via
lo0.10
10.0.13.0/24 *[Direct/0]
00:02:35
> via
ge-0/0/1.0
10.0.13.3/32 *[Local/0]
00:02:35
Local via ge-0/0/1.0
10.0.23.0/24 *[Direct/0] 00:32:39
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 00:32:39
Local via ge-0/0/2.0
10.0.34.0/24 *[Direct/0]
00:02:35
> via
ge-0/0/3.0
10.0.34.3/32 *[Local/0]
00:02:35
Local
via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:32:41, metric 1
MultiRecv
You can see now that all the routes that are directly
connected in inet.0 in now present in R2.inet.0 routing table. What makes me wonder
is why the reverse logic Juniper?, this configuration should be done under the
routing instance I want to import the routes to not the other way around!
Now, let’s import the direct routes from R2.inet.0 to
inet.0 routing table
routing-instances
{
R2 {
instance-type virtual-router;
interface ge-0/0/2.0;
routing-options {
interface-routes {
rib-group inet DIRECT-ROUTES;
}
}
}
}
Now let’s check the inet.0 routing table again
root@R3>
show route
inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
1.1.1.1/32 *[OSPF/10] 00:41:46, metric 1
> to 10.0.13.1 via
ge-0/0/1.0
3.3.3.3/32 *[Direct/0] 00:42:01
> via lo0.10
4.4.4.4/32 *[OSPF/10] 00:41:46, metric 1
> to 10.0.34.4 via ge-0/0/3.0
10.0.12.0/24 *[OSPF/10] 00:41:46, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
10.0.13.0/24 *[Direct/0] 00:42:01
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:42:01
Local via ge-0/0/1.0
10.0.14.0/24 *[OSPF/10] 00:41:46, metric 2
to 10.0.13.1 via
ge-0/0/1.0
> to 10.0.34.4 via
ge-0/0/3.0
10.0.23.0/24 *[Direct/0]
00:02:36
> via
ge-0/0/2.0
10.0.23.3/32 *[Local/0]
00:02:36
Local
via ge-0/0/2.0
10.0.24.0/24 *[OSPF/10] 00:41:46, metric 2
> to 10.0.34.4 via
ge-0/0/3.0
10.0.34.0/24 *[Direct/0] 00:42:01
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:42:01
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:42:03, metric 1
MultiRecv
R2.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
2.2.2.2/32 *[OSPF/10] 00:41:41, metric 1
> to 10.0.23.2 via
ge-0/0/2.0
3.3.3.3/32
*[Direct/0] 00:11:57
> via lo0.10
10.0.13.0/24 *[Direct/0] 00:11:57
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:11:57
Local via ge-0/0/1.0
10.0.23.0/24 *[Direct/0] 00:42:01
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 00:42:01
Local via ge-0/0/2.0
10.0.34.0/24 *[Direct/0] 00:11:57
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:11:57
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:42:03, metric 1
MultiRecv224.0.0.5/32 *[OSPF/10] 00:42:03, metric 1
MultiRecv
The direct routes of R2.inet.0 is now present in inet.0
routing table.
The second part of using RIB groups now is importing the
routes in dynamic routing protocols, let’s see how to do that using the same
reverse logic of Junos.
If you need to import the OSPF routes from R2.inet.0 to inet.0 routing table, here’s how to do it
routing-options
{
interface-routes {
rib-group inet DIRECT-ROUTES;
}
rib-groups {
DIRECT-ROUTES {
import-rib [ inet.0 R2.inet.0 ];
}
R2-TO-GLOBAL {
import-rib [
R2.inet.0 inet.0 ];
}
}
}
As previously mentioned, the first routing table in the
bracket is the routing table we’ll take the routes from and the second routing
table in the brackets will be the one we put the routes into.
If the first routing table doesn't match the table you’re
configuring the RIB group under, you’ll get the following error while committing
the changes:
root@R3#
commit
[edit
routing-instance R2 protocols]
'ospf'
rib-group R2-TO-GLOBAL: primary routing
table does not match instance
error:
configuration check-out failed
Let’s apply the defined RIB group under the R2.inet.0
routing instance OSPF protocol
routing-instances
{
R2 {
instance-type virtual-router;
interface ge-0/0/2.0;
routing-options {
interface-routes {
rib-group inet DIRECT-ROUTES;
}
}
protocols {
ospf {
rib-group R2-TO-GLOBAL;
area 0.0.0.1 {
interface ge-0/0/2.0;
}
}
}
}
}
Here’s the imported routes in inet.0 routing-table
inet.0: 14 destinations, 14 routes (14 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
1.1.1.1/32 *[OSPF/10] 00:55:29, metric 1
> to 10.0.13.1 via ge-0/0/1.0
2.2.2.2/32 *[OSPF/10]
00:02:04, metric 1
> to
10.0.23.2 via ge-0/0/2.0
3.3.3.3/32 *[Direct/0] 00:55:44
> via lo0.10
4.4.4.4/32 *[OSPF/10] 00:55:29, metric 1
> to 10.0.34.4 via
ge-0/0/3.0
10.0.12.0/24 *[OSPF/10] 00:55:29, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
10.0.13.0/24 *[Direct/0] 00:55:44
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:55:44
Local via ge-0/0/1.0
10.0.14.0/24 *[OSPF/10] 00:55:29, metric 2
to 10.0.13.1 via
ge-0/0/1.0
> to 10.0.34.4 via
ge-0/0/3.0
10.0.23.0/24 *[Direct/0] 00:16:19
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 00:16:19
Local via ge-0/0/2.0
10.0.24.0/24 *[OSPF/10] 00:55:29, metric 2
> to 10.0.34.4 via
ge-0/0/3.0
10.0.34.0/24 *[Direct/0] 00:55:44
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:55:44
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:55:46, metric 1
MultiRecv
R2.inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
2.2.2.2/32 *[OSPF/10] 00:02:04, metric 1
> to 10.0.23.2 via
ge-0/0/2.0
3.3.3.3/32 *[Direct/0] 00:25:40
> via lo0.10
10.0.13.0/24 *[Direct/0] 00:25:40
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:25:40
Local via ge-0/0/1.0
10.0.23.0/24 *[Direct/0] 00:55:44
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 00:55:44
Local via ge-0/0/2.0
10.0.34.0/24 *[Direct/0] 00:25:40
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:25:40
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 00:55:46, metric 1
MultiRecv
Looks pretty easy, now let’s import OSPF routes from
inet.0 to R2.inet.0
routing-options
{
interface-routes {
rib-group inet DIRECT-ROUTES;
}
rib-groups {
DIRECT-ROUTES {
import-rib [ inet.0 R2.inet.0 ];
}
R2-TO-GLOBAL {
import-rib [ R2.inet.0 inet.0 ];
}
GLOBAL-TO-R2 {
import-rib [
inet.0 R2.inet.0 ];
}
}
}
protocols
{
ospf {
rib-group
GLOBAL-TO-R2;
area 0.0.0.0 {
interface lo0.10;
interface ge-0/0/1.0;
interface ge-0/0/3.0;
}
}
}
Checking the R2.inet.0 routing table
root@R3>
show route
inet.0: 14 destinations, 14 routes (14 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
1.1.1.1/32 *[OSPF/10] 00:02:25, metric 1
> to 10.0.13.1 via
ge-0/0/1.0
2.2.2.2/32 *[OSPF/10] 00:16:38, metric 1
> to 10.0.23.2 via
ge-0/0/2.0
3.3.3.3/32 *[Direct/0] 01:10:18
> via lo0.10
4.4.4.4/32 *[OSPF/10] 00:02:25, metric 1
> to 10.0.34.4 via
ge-0/0/3.0
10.0.12.0/24 *[OSPF/10] 00:02:25, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
10.0.13.0/24 *[Direct/0] 01:10:18
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 01:10:18
Local via ge-0/0/1.0
10.0.14.0/24 *[OSPF/10] 00:02:25, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
to 10.0.34.4 via
ge-0/0/3.0
10.0.23.0/24 *[Direct/0] 00:30:53
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 00:30:53
Local via ge-0/0/2.0
10.0.24.0/24 *[OSPF/10] 00:02:25, metric 2
> to 10.0.34.4 via
ge-0/0/3.0
10.0.34.0/24 *[Direct/0] 01:10:18
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 01:10:18
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 01:10:20, metric 1
MultiRecv
R2.inet.0: 14 destinations, 14 routes (14 active, 0 holddown, 0
hidden)
+ = Active Route, - = Last Active, * = Both
1.1.1.1/32 *[OSPF/10]
00:02:25, metric 1
> to
10.0.13.1 via ge-0/0/1.0
2.2.2.2/32 *[OSPF/10] 00:16:38, metric 1
> to 10.0.23.2 via
ge-0/0/2.0
3.3.3.3/32 *[Direct/0]
00:40:14
> via
lo0.10
4.4.4.4/32 *[OSPF/10]
00:02:25, metric 1
> to
10.0.34.4 via ge-0/0/3.0
10.0.12.0/24 *[OSPF/10] 00:02:25, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
10.0.13.0/24 *[Direct/0] 00:40:14
> via ge-0/0/1.0
10.0.13.3/32 *[Local/0] 00:40:14
Local via ge-0/0/1.0
10.0.14.0/24 *[OSPF/10] 00:02:25, metric 2
> to 10.0.13.1 via
ge-0/0/1.0
to 10.0.34.4 via
ge-0/0/3.0
10.0.23.0/24 *[Direct/0] 01:10:18
> via ge-0/0/2.0
10.0.23.3/32 *[Local/0] 01:10:18
Local via ge-0/0/2.0
10.0.24.0/24 *[OSPF/10] 00:02:25, metric 2
> to 10.0.34.4 via
ge-0/0/3.0
10.0.34.0/24 *[Direct/0] 00:40:14
> via ge-0/0/3.0
10.0.34.3/32 *[Local/0] 00:40:14
Local via ge-0/0/3.0
224.0.0.5/32 *[OSPF/10] 01:10:20, metric 1
MultiRecv
Hopefully that managed to make it easy to understand how
to use RIB groups in JUNOS. In Part 2, we will be discussing route-leaking usingInstance Import command
THanks for this post.
ReplyDeleteI found a little mistake.
"If you need to import the OSPF routes from inet.0 to R2.inet.0 routing table" .
It should be the opposite , "from R2.inet.0 to inet.0" .
fixed!
DeleteWow! I've read several articles without coming close understanding. I understood yours after only reading once. You did a great job explaining. Thank you!
ReplyDeleteI agree with you on Juniper's reverse login when importing routes using interface routes. I had stop there for a second thinking that doesn't make sense. Glad you pointed it out.
Your post is very easy for understanding. Thank you.
ReplyDeleteI have learned so much from your example, thank you!
ReplyDeleteAnd how can you do it if BGP is used instead of OSPF? rib-groups command does not exist in "protocols bgp"
ReplyDelete