Junos Approach to BGP Cluster-ID and Originator-ID

Couple of days ago I wrote an article for IPexpert’s CCIE blog about BGP Cluster-ID and Originator-ID. When I did that, I got curious whether Junos is handling things any differently. Working assumptions is not, but I wanted to prove it and in the process practice my Junos-fu.

Before I dive into Junos aspects of the issue, please, go ahead and read the original article. I will assume you did. Here is the link: Understanding BGP Originator-ID and Cluster-ID

In this article, I will use slightly different network layout. For IPexpert article, I used ProctorLabs equipment and for this one, I used Junosphere. Here’re the diagram of the network for this post.

Naturally, Junos doesn’t support EIGRP, so I will run OSPF as my IGP of choice. Also, I will not use an additional lo0 unit, but I’ll install a static route with the reject next-hop. Here are the initial configurations for my four routers. Otherwise, setup is pretty much the same as in the original article.

R1:

interfaces {
    ge-0/0/4 {
        unit 0 {
            family inet {
                address 192.168.100.1/24;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 192.168.0.1/32;
            }
        }
    }
}
routing-options {
    static {
        route 10.1.0.0/24 reject;
    }
    router-id 192.168.0.1;
    autonomous-system 65000;
}
protocols {
    bgp {
        export STATIC-to-BGP;
        group RR {
            type internal;
            local-address 192.168.0.1;
            neighbor 192.168.0.2;
        }
    }
    ospf {
        area 0.0.0.0 {
            interface lo0.0;
            interface ge-0/0/4.0;
        }
    }
}
policy-options {
    policy-statement STATIC-to-BGP {
        from protocol static;
        then accept;
    }
}

R2:

interfaces {
    ge-0/0/3 {
        unit 0 {
            family inet {
                address 192.168.23.2/24;
            }
        }
    }
    ge-0/0/4 {
        unit 0 {
            family inet {
                address 192.168.100.2/24;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 192.168.0.2/32;
            }
        }
    }
}
routing-options {
    static {
        route 10.2.0.0/24 reject;
    }
    router-id 192.168.0.2;
    autonomous-system 65000;
}
protocols {
    bgp {
        export STATIC-to-BGP;
        group RR {
            type internal;
            local-address 192.168.0.2;
            neighbor 192.168.0.3;
        }
        group RRC {
            type internal;
            local-address 192.168.0.2;
            cluster 192.168.0.2;
            neighbor 192.168.0.1;
        }
    }
    ospf {
        area 0.0.0.0 {
            interface lo0.0;
            interface ge-0/0/4.0;
            interface ge-0/0/3.0 {
                interface-type p2p;
            }
        }
    }
}
policy-options {
    policy-statement STATIC-to-BGP {
        from protocol static;
        then accept;
    }
}

R3:

interfaces {
    ge-0/0/3 {
        unit 0 {
            family inet {
                address 192.168.23.3/24;
            }
        }
    }
    ge-0/0/4 {
        unit 0 {
            family inet {
                address 192.168.100.3/24;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 192.168.0.3/32;
            }
        }
    }
}
routing-options {
    static {
        route 10.3.0.0/24 reject;
    }
    router-id 192.168.0.3;
    autonomous-system 65000;
}
protocols {
    bgp {
        export STATIC-to-BGP;
        group RR {
            type internal;
            local-address 192.168.0.3;
            neighbor 192.168.0.4;
        }
        group RRC {
            type internal;
            local-address 192.168.0.3;
            cluster 192.168.0.3;
            neighbor 192.168.0.2;
        }
    }
    ospf {
        area 0.0.0.0 {
            interface lo0.0;
            interface ge-0/0/4.0;
            interface ge-0/0/3.0 {
                interface-type p2p;
            }
        }
    }
}
policy-options {
    policy-statement STATIC-to-BGP {
        from protocol static;
        then accept;
    }
}

R4:

interfaces {
    ge-0/0/4 {
        unit 0 {
            family inet {
                address 192.168.100.4/24;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 192.168.0.4/32;
            }
        }
    }
}
routing-options {
    static {
        route 10.4.0.0/24 reject;
    }
    router-id 192.168.0.4;
    autonomous-system 65000;
}
protocols {
    bgp {
        export STATIC-to-BGP;
        group RR {
            type internal;
            local-address 192.168.0.4;
            neighbor 192.168.0.3;
        }
    }
    ospf {
        area 0.0.0.0 {
            interface lo0.0;
            interface ge-0/0/4.0;
        }
    }
}
policy-options {
    policy-statement STATIC-to-BGP {
        from protocol static;
        then accept;
    }
}

By just looking at these initial configurations, the first striking difference between IOS and Junos is apparent. When we’re configuring route-reflectors in IOS, we explicitly configure “neighbor route-reflector-client” statement, while in Junos we create a BGP group for which we define a Cluster-ID using the “cluster” keyword. I decided to start with different Cluster-IDs for my route-reflectors. You can see this configuration in RRC group definitions on R2 and R3.

At this point, my client router R1 should have the 10.4.0.0/24 route from R4.

R1:

markom@R1> show route protocol bgp 10.4 detail

inet.0: 14 destinations, 14 routes (14 active, 0 holddown, 0 hidden)
10.4.0.0/24 (1 entry, 1 announced)
        *BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 3
                Source: 192.168.0.2
                Next hop type: Router, Next hop index: 550
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09780 262144
                State: 
                Local AS: 65000 Peer AS: 65000
                Age: 25:43      Metric2: 1 
                Task: BGP_65000.192.168.0.2+179
                Announcement bits (2): 0-KRT 5-Resolve tree 1 
                AS path: I (Originator) Cluster list:  192.168.0.2 192.168.0.3
                AS path:  Originator ID: 192.168.0.4
                Accepted
                Localpref: 100
                Router ID: 192.168.0.2

I can see Originator ID and Cluster list. So far so good and I have no reason to suspect any differences on R2.

R2:

markom@R2> show route protocol bgp 10.4 detail

inet.0: 15 destinations, 15 routes (15 active, 0 holddown, 0 hidden)
10.4.0.0/24 (1 entry, 1 announced)
        *BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 3
                Source: 192.168.0.3
                Next hop type: Router, Next hop index: 554
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09780 262145
                State: 
                Local AS: 65000 Peer AS: 65000
                Age: 28:39      Metric2: 1 
                Task: BGP_65000.192.168.0.3+49931
                Announcement bits (3): 0-KRT 4-BGP RT Background 5-Resolve tree 1 
                AS path: I (Originator) Cluster list:  192.168.0.3
                AS path:  Originator ID: 192.168.0.4
                Accepted
                Localpref: 100
                Router ID: 192.168.0.3

As expected, Cluster-list at this point is one entry shorter, since the route R2 has in it’s inet.0 table is not the route it reflected itself. I’m seeing only a Cluster-ID of R3. Finally, lets’ check R3.

R3:

markom@R3> show route protocol bgp 10.4 detail

inet.0: 15 destinations, 15 routes (15 active, 0 holddown, 0 hidden)
10.4.0.0/24 (1 entry, 1 announced)
        *BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 3
                Source: 192.168.0.4
                Next hop type: Router, Next hop index: 556
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09690 262143
                State: 
                Local AS: 65000 Peer AS: 65000
                Age: 32:26      Metric2: 1 
                Task: BGP_65000.192.168.0.4+54539
                Announcement bits (3): 0-KRT 4-BGP RT Background 5-Resolve tree 1 
                AS path: I
                Accepted
                Localpref: 100
                Router ID: 192.168.0.4

A complete absence of both Cluster-list and Originator-ID here are expected too. This gives me confidence, because I have long been closed in IOS-only approach to these things that I expect to see differences everywhere. It’s good when things work the way I expect and can explain them.

Now, let me add redundant peerings between R1 and R3, as well as R4 and R2.

R1:

set protocols bgp group RR neighbor 192.168.0.3

R2:

set protocol bgp group RRC neighbor 192.168.0.4

R3:

set protocol bgp group RRC neighbor 192.168.0.1

R4:

set protocol bgp group RR neighbor 192.168.0.2

Let’s examine the BGP tables now.

R1:

markom@R1> show route protocol bgp 10.4 detail

inet.0: 14 destinations, 17 routes (14 active, 0 holddown, 0 hidden)
10.4.0.0/24 (2 entries, 1 announced)
        *BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 4
                Source: 192.168.0.2
                Next hop type: Router, Next hop index: 550
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09780 262144
                State: 
                Local AS: 65000 Peer AS: 65000
                Age: 1:48       Metric2: 1 
                Task: BGP_65000.192.168.0.2+179
                Announcement bits (2): 0-KRT 5-Resolve tree 1 
                AS path: I (Originator) Cluster list:  192.168.0.2
                AS path:  Originator ID: 192.168.0.4
                Accepted
                Localpref: 100
                Router ID: 192.168.0.2
         BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 4
                Source: 192.168.0.3
                Next hop type: Router, Next hop index: 550
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09780 262144
                State: 
                Inactive reason: Not Best in its group - Update source
                Local AS: 65000 Peer AS: 65000
                Age: 1:33       Metric2: 1 
                Task: BGP_65000.192.168.0.3+54084
                AS path: I (Originator) Cluster list:  192.168.0.3
                AS path:  Originator ID: 192.168.0.4
                Accepted
                Localpref: 100
                Router ID: 192.168.0.3

Obviously, we have two routes. One learned from R2 and the other one from R3, with the one learned from R2 being the active one. At this point, I absolutely love Junos! Look at the highlighted line! It even tells me why the route that is not active is not active. Fantastic! At this point, we should be seeing duplicate information on R2.

R2:

markom@R2> show route protocol bgp 10.4 detail

inet.0: 15 destinations, 17 routes (15 active, 0 holddown, 0 hidden)
10.4.0.0/24 (2 entries, 1 announced)
        *BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 4
                Source: 192.168.0.4
                Next hop type: Router, Next hop index: 554
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09780 262145
                State: 
                Local AS: 65000 Peer AS: 65000
                Age: 6:23       Metric2: 1 
                Task: BGP_65000.192.168.0.4+179
                Announcement bits (3): 0-KRT 4-BGP RT Background 5-Resolve tree 1 
                AS path: I
                Accepted
                Localpref: 100
                Router ID: 192.168.0.4
         BGP    Preference: 170/-101
                Next hop type: Indirect
                Next-hop reference count: 4
                Source: 192.168.0.3
                Next hop type: Router, Next hop index: 554
                Next hop: 192.168.100.4 via ge-0/0/4.0, selected
                Protocol next hop: 192.168.0.4
                Indirect next hop: 8f09780 262145
                State: 
                Inactive reason: Not Best in its group - Cluster list length
                Local AS: 65000 Peer AS: 65000
                Age: 44:08      Metric2: 1 
                Task: BGP_65000.192.168.0.3+49931
                AS path: I (Originator) Cluster list:  192.168.0.3
                AS path:  Originator ID: 192.168.0.4
                Accepted
                Localpref: 100
                Router ID: 192.168.0.3

I can see the route learned directly from R4, as well as the one reflected from R3. The reflected route is not chosen because of the Cluster-list length, which is also the behavior I expected to see. Finally, I want to see if R4 is rejecting the incoming updates.

Inexperience
At this point, an experienced Junos network engineer would fire up traceoptions, alas I’m still in an exploratory learning phase. If I don’t see the route, I’ll know why.

R4:

markom@R4> show route protocol bgp 10.4 detail

inet.0: 14 destinations, 17 routes (14 active, 0 holddown, 0 hidden)

I’m both excited and disappointed at the same time. I wanted to do some heavy research, but it appears that all the behavior so far is in sync with what I’ve expected. Let’s move on. The next step from the original article was making sure our route-reflectors share the Cluster-ID, with the idea of de-duplicating the data shared between them.

R2 & R3:

set protocols bgp group RRC cluster 192.168.100.0

I will check if the route exists on R1. I should be seeing two copies of this route, one from R2 and the other one from R3.

R1:

markom@R1> show route protocol bgp 10.4

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

10.4.0.0/24        *[BGP/170] 00:01:33, localpref 100, from 192.168.0.2
                      AS path: I
                    > to 192.168.100.4 via ge-0/0/4.0
                    [BGP/170] 00:01:33, localpref 100, from 192.168.0.3
                      AS path: I
                    > to 192.168.100.4 via ge-0/0/4.0

On the other hand, R2 and R3 should only have a single route each.

R2:

markom@R2> show route protocol bgp 10.4

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

10.4.0.0/24        *[BGP/170] 00:02:31, localpref 100, from 192.168.0.4
                      AS path: I
                    > to 192.168.100.4 via ge-0/0/4.0

R3:

markom@R3> show route protocol bgp 10.4

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

10.4.0.0/24        *[BGP/170] 00:02:36, localpref 100, from 192.168.0.4
                      AS path: I
                    > to 192.168.100.4 via ge-0/0/4.0

I’m happy! :-)

She may not be as happy though. I’ve been away for almost two weeks now teaching in RTP, while she was alone back home.

  1. Randy Landrand

    Very nice write-up!

    Correct me if I’m wrong, but it looks to me like your configs for the cluster-id value is inconsistent and perhaps incorrect on routers R2 and R3.

    On R2, you define the cluster id on the BGP group RRC which has R1 as the rr client.

    On R3 you define the cluster-id on the BGP group RR where the neighbor is the other RR (R2) rather than the rr client R4.

  2. A handy (Junos) knob to combine with RR configs is ‘allow’. It permits connections from any client in the specified prefix.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>