Junos Versus Cisco IOS: MPLS and LDP
The comments igp2bgp and Tiziano Tofoni made to my LDP-IGP Synchronization in MPLS Networks post prompted me to look deeper into basic Junos MPLS configuration and LDP behavior. As expected, there are some significant differences between Cisco’s and Juniper’s LDP implementations (and, as is usually the case, they’re both strictly conformant with RFC 5036).
Configuration Details
When you configure mpls ip on an interface in a Cisco router, you implicitly start LDP. In Junos, you have to start LDP explicitly by creating protocols ldp and list all interfaces on which LDP should run with interface commands within protocol ldp. Even that’s not enough; you have to enable MPLS family on each interface listed in the protocols ldp section.
interface GigabitEthernet0/0/2
mpls ip
interface GigabitEthernet0/0/3
mpls ip
interface GigabitEthernet0/0/4
mpls ip
interface GigabitEthernet0/0/5
mpls ip
interfaces {
ge-0/0/2 {
unit 0 {
family mpls;
}
}
ge-0/0/3 {
unit 0 {
family mpls;
}
}
ge-0/0/4 {
unit 0 {
family mpls;
}
}
ge-0/0/5 {
unit 0 {
family mpls;
}
}
}
protocols {
ldp {
interface ge-0/0/2.0;
interface ge-0/0/3.0;
interface ge-0/0/4.0;
interface ge-0/0/5.0;
}
}
I am positive Junos approach has its benefits (and a very apparent verbosity drawback) and I’m not even trying to say which one is better – both CLIs are facts of life. And you don’t have to remind me there are commit scripts that can sync both parts of Junos configuration.
For whatever reason, during some of my tests LDP failed to start till I configured protocol ldp transport-address router-id. Reload might have helped ;)
Label Distribution Control Mode
Cisco IOS uses independent label distribution control – every LSR advertises a label for every IP prefix in its routing table that matches its label allocation policy (see also Label Allocation Rules below).
Junos uses ordered label distribution control – LSR allocates and advertises labels for prefixes configured with egress policy (see Label Allocation Rules below) and for prefixes in its IP routing table for which it’s already received a label mapping from the next-hop LSR.
In both cases, you can’t configure the label distribution control mode (more about whether that matters in a follow-up post).
Label Allocation Rules
Cisco IOS allocates an MPLS label for every non-BGP IP prefix in the IP routing table. You can change that behavior with allocate global prefix-list | host-routes global configuration command (introduced in 12.2SRC). You can also filter labels sent to LDP neighbors with the mpls ldp advertise-label global configuration command.
Junos allocates labels only for loopback interfaces. You can change the set of prefixes for which the local labels are allocated with the protocol ldp egress-policy (and outbound filters with the export policy).
Any IP prefix matched by the LDP egress policy will get a locally-originated label that will not be stitched with the label allocated by downstream LSR. Effectively, a Junos router becomes tail-end LSR for every prefix matched by the egress-policy.
To emulate Cisco IOS label allocation behavior on Junos, use the following configuration:
protocols {
ldp {
egress-policy connected;
interface ge-0/0/2.0;
interface ge-0/0/3.0;
interface ge-0/0/4.0;
}
}
policy-options {
policy-statement connected {
from protocol direct;
then accept;
}
}
FEC Aggregation
Cisco IOS allocates a different label to every IP prefix that deserves to get a label (see Label Allocation Rules).
Junos allocates a single label to all IP prefixes that have (A) the same IP next hop and (B) the same label advertised by the next-hop LSR. You can change that behavior with protocol ldp deaggregate command.
Does it matter?
In most well-designed networks, the differences between Cisco IOS and Junos are not significant (exception: in a BGP-free ISP core with external BGP next hops you have to allocate labels to external subnets).
Junos is way more conservative in its label allocation policy and will thus (with the default settings) generate fewer labels and consume fewer resources than Cisco IOS.
You can change most LDP parameters (apart from the label distribution control mode) and make Cisco IOS behave almost like Junos or vice versa.
So why does it matter? The only real reason is troubleshooting: you have to understand why you’re seeing fewer (or more) labels than you’d expect to see and why you don’t see a label for a prefix that should have one (hint: ordered label distribution control).
Disclosure
This post would never have been written without a gentle nudge from Tiziano and igp2bgp who’d tickled my curiosity. Thank you!
I did all the tests in Junosphere environment kindly provided by Juniper (thanks to @abnerg) ... but I never promised anyone I would write anything about Junosphere or Junos (and of course they knew I couldn’t possibly resist the temptation).
What I find is that if you wanto to setup an MPLS-TE VC you need to enable interfaces under [protocols mpls] (and under [protocols rsvp] also !), but not for LDP (at least in real J-series routers, and Olive) .
Frankly, from a conceptual point of view, I do not understand the need to specify interfaces under [protocols mpls] also when you want to enable LDP. LDP Hello messages start as soon as you commit configuration after enabling interfaces under [protocols ldp], and that is enough to start LDP sessions. I do not whether I am missing some points, but so far all LDP related configurations I made work fine.
Could you please avoid to use Twitter to post your interesting comments ? Thanks a lot.
But for whatever reason, if you forget to enable "family mpls" on an interface, on that interface you cannot have any LDP sessions, even if an LDP session does not require to be set up any MPLS packet. Probably the idea is that if you set up an LDP session on an interfacce, sometime in the future that interface will receive MPLS packets.
Concerning "transport-address" you have to be very careful, since by default JUNOS uses as RID for every protocols (OSPF, BGP, LDP) the IP address configured under [routing-options] stanza. While for BGP and OSPF this address may be arbitrary (even unreachable, or totally invented) for LDP it must be L3-reachable since it is used by default for the TCP connection. So the best-practice I use is to define the router-id equal to the loopback interface address.
This is different from IOS, where you can define different RID for each protocol. As a matter of fact, I use the same best prectice in Cisco IOS also. I usually define the RID of each protocol equal to the IP address of the Loopback 0 interface (and of course I advertise this interface in IGP !)
You're just begging for the JunOS fanboy trolls to come in, aren't you? :)
On a more serious note, thank you for clearing up some of the issues I was having.. expecting IOS behavior out of a Juniper router is hardly normal, but I had my own concerns with getting things functioning 100/100.
I'm positive it's just me, the negative energy I'm emitting, and my grumpy attitude.
I think I've just been sold on never even considering Junos switches and routers.
"commit full" <-- 'full' is hidden keyword, but it forces complete rebuild of config internal to routing-engine... fixes things sometimes.
The _huge_ difference, however, is that Junos assigns labels to /32s (loopbacks) whereas Cisco IOS assigns labels to all non-BGP prefixes.