MPLS-TE via RSVP – Part 2 of 3 – Juniper JunOS

This is part 2 of my basic MPLS-TE RSVP series.

Part 1 – Cisco IOS
Part 2 – Juniper JunOS
Part 3 – Brocade Netiron XMR/MLX
Part 4 – Cisco IOS-XR

So now let’s move onto JunOS. Same topology used:

JunOS basic config

I’m pasting the relevant pieces of config here of CR1. CR2 and CR3 are going to be very similar:

interfaces {
    fe-0/0/1 {
        unit 13 {
            vlan-id 13;
            family inet {
                address 10.0.2.2/24;
            }
            family mpls;
        }
    }
    fe-0/0/2 {
        unit 13 {
            vlan-id 13;
            family inet {
                address 10.0.3.1/24;
            }
            family mpls;
        }
    }
    lo0 {
        unit 3 {
            family inet {
                address 3.3.3.3/32;
            }
        }
    }
}
protocols {
    rsvp {
        interface all;
    }
    mpls {
        interface all;
    }
    ospf {
        area 0.0.0.0 {
            interface all;
        }
    }
}

Again the actual core routers have a very vanilla configuration. In JunOS we need to enable RSVP on all transit interfaces, MPLS on all interfaces, and family mpls on the transit interfaces themselves. Some of you may be thinking why do we need to enable MPLS under both the interface and protocols stanza? Well any config on the interfaces is generally information for the data-plane, while the protocols config is for the control-plane. Basically enabling mpls under the protocols ensures MPLS actually runs on the interface, while the interface configuration ensures that the interface will actually accept labeled packets to begin with.

One thing to note is that I’m not actually enabling traffic-engineering under OSPF. At least not yet. More on that later…

Now for AR1’s config. This has the same config as above, plus a whole lot more:

interfaces {
    fe-0/0/0 {
        unit 13 {
            vlan-id 13;
            family inet {
                address 10.0.2.1/24;
            }
            family mpls;
        }
        unit 15 {
            vlan-id 15;
            family inet {
                address 10.0.5.1/24;
            }
            family mpls;
        }
    }
    lo0 {
        unit 1 {
            family inet {
                address 1.1.1.1/32;
                address 20.20.20.20/32;
            }
        }
    }
}
protocols {
    rsvp {
        interface all;
}
    mpls {
    no-cspf;
    label-switched-path AR1-to-AR3 {
        to 2.2.2.2;
    }
    interface all;
}
    }
    bgp {
        group INTERNAL {
            local-address 1.1.1.1;
            export LO_OUT;
            neighbor 2.2.2.2 {
                peer-as 13;
            }
        }
    }
    ospf {
        export export-ospf;
        area 0.0.0.0 {
            interface all;
            interface lo0.1 {
                disable;
            }
        }
    }
}
policy-options {
    prefix-list LOOP {
        20.20.20.20/32;
    }
    policy-statement LO_OUT {
        from {
            protocol direct;
            prefix-list LOOP;
        }
        then accept;
    }
    policy-statement export-ospf {
        from {
            protocol direct;
            route-filter 1.1.1.1/32 exact;
        }
        then accept;
    }
}
routing-options {
    autonomous-system 13;
}

So it has the same MPLS config. I’ve also configured BGP and OSPF so that it exports the first loopback address in OSPF and the second in BGP. I’ve also created an LSP to 2.2.2.2 – Notice that I’m still not running traffic-engineering extensions in OSPF. What this means is that the LSP will simply be signaled using the current shorted path OSPF route. No TE extensions required. This is a fundamental difference to IOS as IOS needs TE in your link state protocol in order for this to function.

Let’s now ping across:

darreno:AR3> ping 20.20.20.20 rapid
PING 20.20.20.20 (20.20.20.20): 56 data bytes
!!!!!
--- 20.20.20.20 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.068/3.046/10.511/3.735 ms

This does work, unlike IOS. With IOS we had to instruct the OS to actually consider the tunnel as a usable route-able interface. In JunOS, all LSP endpoints enter the inet.3 table. BGP uses this table first as a next-hop resolver. Let’s check this:

darreno:AR3> show route table inet.3

inet.3: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

1.1.1.1/32         *[RSVP/7/1] 00:24:18, metric 0
                    > to 10.0.3.1 via fe-0/0/3.13, label-switched-path AR3-to-AR1

darreno:AR3> show route 20.20.20.20

inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

20.20.20.20/32     *[BGP/170] 01:03:27, localpref 100, from 1.1.1.1
                      AS path: I
                    > to 10.0.3.1 via fe-0/0/3.13, label-switched-path AR3-to-AR1

The nice thing is that the route table shows the interface to actually be ‘label-switched-path AR3-to-AR1’

Only BGP will use this inet.3 table by default. This means that OSPF won’t use the LSP itself unless we tell it to:

darreno:AR3> show route 1.1.1.1

inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

1.1.1.1/32         *[OSPF/150] 00:26:18, metric 0, tag 0
                    > to 10.0.3.1 via fe-0/0/3.13

inet.3: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

1.1.1.1/32         *[RSVP/7/1] 00:26:14, metric 0
                    > to 10.0.3.1 via fe-0/0/3.13, label-switched-path AR3-to-AR1

My IGPs will use regular unlabeled packets, while BGP using 1.1.1.1 as a next-hop will use the LSP. You can see my regular traceroute below will use the OSPF unlabeled route while a trace to the BGP route will be labeled:

darreno:AR3> traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 40 byte packets
 1  10.0.3.1 (10.0.3.1)  1.133 ms  5.565 ms  0.808 ms
 2  1.1.1.1 (1.1.1.1)  1.078 ms  1.177 ms  1.064 ms

darreno:AR3> traceroute 20.20.20.20
traceroute to 20.20.20.20 (20.20.20.20), 30 hops max, 40 byte packets
 1  10.0.3.1 (10.0.3.1)  1.504 ms  1.302 ms  1.140 ms
     MPLS Label=299776 CoS=0 TTL=1 S=1
 2  20.20.20.20 (20.20.20.20)  1.105 ms  2.046 ms  1.260 ms

We can also dive a bit deeper into the forwarding table to seewhat will happen. This is similar to checking the CEF table on IOS

darreno:AR3> show route forwarding-table destination 20.20.20.20
Logical system: AR3
Routing table: default.inet
Internet:
Destination        Type RtRef Next hop           Type Index NhRef Netif
20.20.20.20/32     user     0                    indr 262142     2
                              10.0.3.1          Push 299776   832     2 fe-0/0/3.13

The forwarding table says that it will impose a label value of 299776 onto the frame, which is exactly what we saw in the traceroute earlier.

JunOS explicit paths

So let’s get our hands dirty with explicit paths. I’ll also be enabling OSPF-TE for this part (though it’s not actually required for explicit paths)

AR3
label-switched-path AR3-to-AR1 {
    to 1.1.1.1;
    primary through-CR3-CR2;
}
path through-CR3-CR2 {
    10.0.7.1 strict;
    10.0.6.1 strict;
    10.0.5.1 strict;

darreno:AR3> show configuration protocols ospf
traffic-engineering;

Very similar to IOS. We specify the explicit next hops along the path and ensure the LSP is using this named path as a primary. Now we should see a traceroute go over 2 labeled hops:

darreno:AR3> traceroute 20.20.20.20
traceroute to 20.20.20.20 (20.20.20.20), 30 hops max, 40 byte packets
 1  10.0.7.1 (10.0.7.1)  1.448 ms  1.543 ms  1.181 ms
     MPLS Label=299792 CoS=0 TTL=1 S=1
 2  10.0.6.1 (10.0.6.1)  1.195 ms  1.346 ms  1.209 ms
     MPLS Label=299792 CoS=0 TTL=1 S=1
 3  20.20.20.20 (20.20.20.20)  10.419 ms  1.272 ms  1.144 ms

Which is exactly what we see.

JunOS Type-10 OSPF LSA

We’ve also enabled OSPF TE so let’s take a look at the OSPF database:

darreno:AR1> show ospf database | match opa
OpaqArea*1.0.0.1          1.1.1.1          0x80000003   326  0x22 0x2cf8  28
OpaqArea 1.0.0.1          2.2.2.2          0x80000002   328  0x22 0x32eb  28
OpaqArea 1.0.0.1          3.3.3.3          0x80000002   327  0x22 0x36df  28
OpaqArea 1.0.0.1          4.4.4.4          0x80000002   327  0x22 0x3ad3  28
OpaqArea 1.0.0.1          5.5.5.5          0x80000002   328  0x22 0x3ec7  28
OpaqArea*1.0.0.3          1.1.1.1          0x80000003   326  0x22 0x4f8d 124
OpaqArea 1.0.0.3          2.2.2.2          0x80000002   328  0x22 0x3699 124
OpaqArea 1.0.0.3          3.3.3.3          0x80000002   327  0x22 0x33a1 124
OpaqArea 1.0.0.3          4.4.4.4          0x80000002   327  0x22 0xab1f 124
OpaqArea 1.0.0.3          5.5.5.5          0x80000002   328  0x22 0xbd07 124
OpaqArea*1.0.0.4          1.1.1.1          0x80000003   326  0x22 0xdbf9 124
OpaqArea 1.0.0.4          2.2.2.2          0x80000002   328  0x22 0x6373 124
OpaqArea 1.0.0.4          3.3.3.3          0x80000002   327  0x22 0x27ac 124
OpaqArea 1.0.0.4          4.4.4.4          0x80000002   327  0x22 0xb513 124
OpaqArea 1.0.0.4          5.5.5.5          0x80000002   328  0x22 0xb50e 124

And again if we dig deeper into the LSA we can see actual bandwidths, priorities, and reservations:

darreno:AR1> show ospf database opaque-area advertising-router 3.3.3.3 extensive

    OSPF database, Area 0.0.0.0
 Type       ID               Adv Rtr           Seq      Age  Opt  Cksum  Len
OpaqArea 1.0.0.1          3.3.3.3          0x80000002   401  0x22 0x36df  28
  Area-opaque TE LSA
  RtrAddr (1), length 4: 3.3.3.3
  Aging timer 00:53:18
  Installed 00:06:38 ago, expires in 00:53:19, sent 00:06:36 ago
  Last changed 00:09:54 ago, Change count: 1
OpaqArea 1.0.0.3          3.3.3.3          0x80000002   401  0x22 0x33a1 124
  Area-opaque TE LSA
  Link (2), length 100:
    Linktype (1), length 1:
      2
    LinkID (2), length 4:
      10.0.2.2
    LocIfAdr (3), length 4:
      10.0.2.2
    RemIfAdr (4), length 4:
      0.0.0.0
    TEMetric (5), length 4:
      1
    MaxBW (6), length 4:
      100Mbps
    MaxRsvBW (7), length 4:
      100Mbps
    UnRsvBW (8), length 32:
        Priority 0, 100Mbps
        Priority 1, 100Mbps
        Priority 2, 100Mbps
        Priority 3, 100Mbps
        Priority 4, 100Mbps
        Priority 5, 100Mbps
        Priority 6, 100Mbps
        Priority 7, 100Mbps
    Color (9), length 4:
      0
  Aging timer 00:53:18
  Installed 00:06:38 ago, expires in 00:53:19, sent 00:06:36 ago
  Last changed 00:09:54 ago, Change count: 1
OpaqArea 1.0.0.4          3.3.3.3          0x80000002   401  0x22 0x27ac 124
  Area-opaque TE LSA
  Link (2), length 100:
    Linktype (1), length 1:
      2
    LinkID (2), length 4:
      10.0.3.1
    LocIfAdr (3), length 4:
      10.0.3.1
    RemIfAdr (4), length 4:
      0.0.0.0
    TEMetric (5), length 4:
      1
    MaxBW (6), length 4:
      100Mbps
    MaxRsvBW (7), length 4:
      100Mbps
    UnRsvBW (8), length 32:
        Priority 0, 100Mbps
        Priority 1, 100Mbps
        Priority 2, 100Mbps
        Priority 3, 100Mbps
        Priority 4, 100Mbps
        Priority 5, 100Mbps
        Priority 6, 100Mbps
        Priority 7, 100Mbps
    Color (9), length 4:
      0
  Aging timer 00:53:18
  Installed 00:06:38 ago, expires in 00:53:19, sent 00:06:36 ago
  Last changed 00:09:54 ago, Change count: 1

The biggest difference here is that the JunOS default behavior is far more relevant to what a lot of ISP cores would actually be like. Basically I would generally only want my BGP next-hop to be labeled. The majority of regular MPLS/L3 MPLS/VPLS etc all use BGP and hence all traffic over those technologies will be labeled, while regular IP traffic internal to the network continues to operate as regular IP traffic.

IOS is a lot more label happy and will create loads of labels for all kinds of prefixes. You can of course change the behavior from both vendors.

I think it’s also a lot easier in JunOS to troubleshoot as you have a separate route table specifically used as a BGP next-hop resolver.

© 2009-2020 Darren O'Connor All Rights Reserved -- Copyright notice by Blog Copyright