Cisco vs Juniper: different eBGP behavior

Last week I had to troubleshoot a problem about eBGP peering with an external provider and I think my findings will be interesting for some of you out there.

Let me start with some background information. I have two locations, same ASN, both connected to the same provider network using eBGP as routing protocol. Due to the looping prevention mechanism, default behavior in eBGP peering between Cisco equipment, is not to accept in BGP table prefixes that have in the AS-Path the same ASN as the local BGP router. You can still accept these prefixes, if you use the “allowas-in” trick on Cisco routers:

neighbor x.x.x.x allowas-in

The above command will tell BGP protocol on Cisco routers to ignore the presence of its own ASN in the AS-Path and to accept the prefixes. If all other attributes are in good standing, the routes to those prefixes will be installed in the routing table.

As a short example, take the following tolopogy:

I have a typical eBGP peering configuration. On one of the edge Cisco routers I have a Lo0 interface with 5.5.5.5/32 IP address which I advertise into BGP. Checking the middle Cisco router (provider) I can see that the BGP table has the 5.5.5.5/32 prefix installed:

sh ip bgp 5.5.5.5
BGP routing table entry for 5.5.5.5/32, version 2
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Flag: 0x820
  Advertised to update-groups:
        1
  65082
    10.10.12.1 from 10.10.12.1 (10.10.12.1)
      Origin IGP, metric 0, localpref 100, valid, external, best

Next I check if the provider router does advertise this prefix to the next neighbor:

sh ip bgp neigh 10.10.13.1 advertised-routes | i 5.5.5.5
*> 5.5.5.5/32       10.10.12.1               0             0 65082 i

From this perspective everything is fine. On the edge Cisco router, I cannot see this prefix in the BGP table, which is normal due to the reasons I explained above:

R6#sh ip bgp 5.5.5.5
% Network not in table

As soon as I add the “allowas-in” configuration on the edge Cisco router, the BGP table will contain the prefix 5.5.5.5/32:

router bgp 65082
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.10.13.2 remote-as 65086
 neighbor 10.10.13.2 allowas-in
 no auto-summary
sh ip bgp 5.5.5.5    
BGP routing table entry for 5.5.5.5/32, version 2
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Flag: 0x820
  Not advertised to any peer
  65086 65082
    10.10.13.2 from 10.10.13.2 (10.10.13.2)
      Origin IGP, localpref 100, valid, external, best

Now let take the example when the provider is using Juniper technology. The eBGP peering is now between Cisco and Juniper devices:

I have configured the eBGP in the same way and I have advertised from one Cisco router the 5.5.5.5/32 prefix. 

On Juniper the BGP configuration looks like this:

yotis@J1# run show configuration protocols        
bgp {
    local-as 65086;
    group TST {
        peer-as 65082;
        neighbor 10.10.12.1;
        neighbor 10.10.13.1;
    }
}

Checking on the Juniper device I can see the prefix in the BGP table and routing table:

yotis@J1# run show route protocol bgp receive-protocol bgp 10.10.12.1    
 
inet.0: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
  Prefix		  Nexthop	       MED     Lclpref    AS path
* 5.5.5.5/32              10.10.12.1           0                  65082 I
 
__juniper_private2__.inet.0: 1 destinations, 1 routes (0 active, 0 holddown, 1 hidden)
yotis@J1# run show route 5.5.5.5                                         
 
inet.0: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
 
5.5.5.5/32         *[BGP/170] 01:19:15, MED 0, localpref 100
                      AS path: 65082 I
                    > to 10.10.12.1 via em1.0

On the second Cisco router, I did not change anything. The “allowas-in” command is still there:

router bgp 65082
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.10.13.2 remote-as 65086
 neighbor 10.10.13.2 allowas-in
 no auto-summary

Still the prefix is not in the BGP table:

R6#show ip bgp 5.5.5.5
% Network not in table

Here is a big difference on the way eBGP protocol behave on Cisco vs. Juniper. On Cisco devices, the eBGP will send the prefixes, no matter of the peer ASN and it’s the task of the peer to apply the default policy when its own ASN is present in the AS-Path and deny the prefixes to be installed in the BGP table.

With Juniper, eBGP protocol will not even announce the prefixes if the ASN of its peer is already present in the AS-Path.

According to http://www.juniper.net/techpubs/software/junos/junos94/swconfig-routing/disabling-suppression-of-route-advertisements.html#id-13255463

“The JUNOS software does not advertise the routes learned from one external BGP (EBGP) peer back to the same EBGP peer. In addition, the software does not advertise those routes back to any EBGP peers that are in the same AS as the originating peer, regardless of the routing instance.”

There is a solution to overcome this behavior and it’s pretty simple. You can set this configuration on global basis or per group in Junos BGP configuration:

[edit protocols bgp group TST]
yotis@J1# set advertise-peer-as

Now the BGP configuration looks like this:

yotis@J1# run show configuration protocols        
bgp {
    local-as 65086;
    group TST {
        advertise-peer-as;
        peer-as 65082;
        neighbor 10.10.12.1;
        neighbor 10.10.13.1;
    }
}

If I check now the Cisco BGP table, the 5.5.5.5/32 prefix will be there:

show ip bgp 5.5.5.5
BGP routing table entry for 5.5.5.5/32, version 4
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Flag: 0x820
  Not advertised to any peer
  65086 65082
    10.10.13.2 from 10.10.13.2 (10.10.12.2)
      Origin IGP, localpref 100, valid, external, best

Don’t forget to check my Juniper, first steps after power-on the device if you are new with Juniper products. You may be interested also in my older posts Cisco: BGP path selection for outgoing traffic and Cisco: BGP path selection for inbound traffic if you just start to work with external providers.


Juniper, first steps after power-on the device

As you know from my previous posts, I’m trying to find time to gain some Juniper knowledge. During this “quest” I will add here some basic things about how to start working with Juniper devices. For now I know only the basics of Juniper configuration, but I hope that soon you’ll find here some more challenging scenarios.

I have a basic topology that you’ll find below. The scenario is already prepare to have some tasks which suppose integration between Juniper and Cisco environment.

Let’s assume that I did power on the two boxes J1 and J2 and now I’m connected to J1 through a console cable. After the boot sequence I’m left with something like this:

Tue Jun 12 11:46:06 UTC 2012
 
Amnesiac (ttyd0)
 
login:

All platforms running the Junos OS have only the root user configured by default, without any password. Let’s introduce that username and see what’s happening:

login: root
Password:
 
--- JUNOS 9.4R2.9 built 2009-03-25 07:50:02 UTC
root@%

What I have now in front is actually the shell of the FreeBSD OS. JunOS is based on the FreeBSD OS. If you ever interacted with a Linux based system, then you can run here specific linux commands. For example:

root@% ls
.snap           boot            jail            modules         sbin
COPYRIGHT       config          kernel          opt             staging
altconfig       data            libexec         packages        tmp
altroot         dev             mfs             proc            usr
bin             etc             mnt             root            var
root@% 
root@% 
root@% 
root@% ps u
USER   PID %CPU %MEM   VSZ   RSS  TT  STAT STARTED      TIME COMMAND
root  1153  0.0  0.2  1492   936  v0  Is+  11:46AM   0:00.02 /usr/libexec/getty
root   941  0.0  0.4  2636  2176  d0- S    11:46AM   0:00.14 /usr/sbin/eventd -
root  1264  0.0  0.2  1676  1252  d0  Is   11:50AM   0:00.05 login [pam] (login
root  1265  0.0  0.5  3872  2744  d0  S    11:51AM   0:00.21 -csh (csh)
root  1289  0.0  0.2  1612   996  d0  R+   11:54AM   0:00.01 ps u

OK, you got my point. To get from the FreeBSD shell to JunOS CLI, you need to enter the following:

root@% cli
root>

What you see now is the Operational Mode. In this mode the user can run basic and troubleshooting commands (like traceroute, ping…). You can get a list of commands using the ? (question mark):

root> ?
Possible completions:
  clear                Clear information in the system
  configure            Manipulate software configuration information
  file                 Perform file operations
  help                 Provide help information
  monitor              Show real-time debugging information
  mtrace               Trace multicast path from source to receiver
  op                   Invoke an operation script
  ping                 Ping remote target
  quit                 Exit the management session
  request              Make system-level requests
  restart              Restart software process
  set                  Set CLI properties, date/time, craft interface message
  show                 Show system information
  ssh                  Start secure shell on another host
  start                Start shell
  telnet               Telnet to another host
  test                 Perform diagnostic debugging
  traceroute           Trace route to remote host

If you want to compare the Operational Mode is somehow like Privilege level 1 under Cisco CLI. Still I have the feeling that Operational Mode offer a wider area of commands and more powerful than Cisco CLI Privilege level 1. I may be mistaken.

All platforms running the Junos OS come with a factory-default configuration. All factory-default configurations
allow access using the root account without any password. Nevertheless to activate a configuration you have first to set the password root password.Factory-default configurations can vary from one platform family to another or even between the different models
within the same platform family.
My default configuration looks like:

root> show configuration 
version 9.4R2.9;
system {
    syslog {
        user * {
            any emergency;
        }
        file messages {
            any notice;
            authorization info;
        }
        file interactive-commands {
            interactive-commands any;
        }
    }
}

I this first post my target is to set the hostname of the Juniper devices. To accomplish this step, I need to go first into configuration mode:

root> configure 
Entering configuration mode
The configuration has been changed but not committed
 
[edit]
root#

and then set the hostname:

root# set system host-name J1 
 
[edit]

If I look at the system prompt, it still shows root#, so it doesn’t quite seems to work. This is because I have to commit to activate the configuration:

root# commit 
[edit]
  'system'
    Missing mandatory statement: 'root-authentication'
error: commit failed: (missing statements)
 
[edit]
root#

Well, this didn’t work as expected. The most important thing that I learned when I started with Juniper is that before I can activate any configuration (commit) I need to set the password for the root user:

root# set system root-authentication plain-text-password              
New password:
Retype new password:
 
[edit]
root#

Let me try to commit one more time, after setting the root password:

root# commit 
commit complete
 
[edit]
root@J1#

You can see that the prompt did change into root@HOSTNAME# (in my case this is root@J1#). If you look again to the system configuration. I will exist the Configuration Mode and have another look at my config file:

root@J1> show configuration 
## Last commit: 2012-06-12 12:38:22 UTC by root
version 9.4R2.9;
system {
    host-name J1;
    root-authentication {
        encrypted-password "$1$DKpYj/Nd$TVFTars5T2.oM3y5eyp520"; ## SECRET-DATA
    }
    syslog {
        user * {
            any emergency;
        }
        file messages {
            any notice;
            authorization info;
        }
        file interactive-commands {
            interactive-commands any;
        }
    }
}
 
root@J1>

The host-name and root password appears now in the active configuration.

That’s it for today. Until next post, I will add the basic configuration for J2 and the Cisco, so I can go to basic interface configuration and connectivity check.