Tag Archives: routing instance

Layer-2 VPNs on Junos

Reading Time: 7 minutes

It has been a busy few weeks trying to stay ahead of all the new work that has been coming towards myself and the team, due to the in sourcing of the core network! Lucky enough for my team, we have finally got our hands onto full end-to-end connectivity! Fun times 😀

With that being said, I’ve been given a wee project to provision a circuit for a business customer between two sites for a Proof Of Concept. As this circuit is being using as a POC (for now), it was agreed that a Layer 2 VPN (L2VPN/pseudowire) will be best suited, because a simple point-to-point connection was needed between two PEs. As we have a MPLS enabled network, it was decided that would be the easiest way to get their POC up and running quickly, as we were under a bit of a hard deadline!

For me, it was good little project, even though I know what L2VPNs were and how they work, I had never configured one myself. You see where I’m going with this now?

This post will over note how to configure L2VPN with Junos 😀

L2VPN, also known as a pseudowire, is defined in RFC4665, where they are called Virtual Private Wire Service (VPWS):

The PE devices provide a logical interconnect such that a pair of CE devices appears to be connected by a single logical Layer 2 circuit. PE devices act as Layer 2 circuit switches. Layer 2 circuits are then mapped onto tunnels in the SP network. These tunnels can either be specific to a particular VPWS, or be shared among several services. VPWS applies for all services, including Ethernet, ATM, Frame Relay, etc. Each PE device is responsible for allocating customer Layer 2 frames to the appropriate VPWS and for proper forwarding to the intended destinations.

In essence, L2VPNs are virtual point-to-point circuit that use the underlying Transport Labels (LDP/RSVP) or a statically defined MPLS path to go between two PE’s, that allows the extension of a layer 2 broadcast domain. If you need multiple sites on the same layer 2 broadcast you will need to consider Virtual Private Lan Service (VPLS) or Ethernet VPN (EVPN).

Within Junos there are 3 ways of configuring L2VPNs, two are regarded as modern way and has been rectified with RFC’s with an additional legacy method. Kompella and Martini are regarded as the industry standard, with Circuit Cross-Connect (CCC) seen as legacy:

  • Circuit Cross-Connect: The Circuit Cross-Connect style of L2VPN uses a single Outer Label, also known as the Tunnel/Transport Label, to transport L2 payload from PE to PE. CCC can ONLY use RSVP as MPLS transport, in addition each CCC connection has its own dedicated RSVP-signalled LSP associated, the transport label cannot be shared between multiple connections. LSPs are manually created on each PE to determines which circuit the frame belongs to on the other end.
  • Martini: The Martini style of L2VPN has a pair of labels before the L2 frame. The Outer label is the transport mechanism that allows the frame from egress interface from the sending PE to ingress interface of the receiving PE. The Inner label, known as the VC Label, is the label that informs the receiving PE, where the L2VPN payload should go. It is important to note that if you are using the Martini style, although either LDP or RVSP can be used MPLS transport, that LDP is used for the signalling of the VC label. So if the RSVP is used as the MPLS transport, LDP will need to be enabled on the loopback address of both PE routers. A minimum of 2 LSPs will need to be set, as MPLS LSPs are unidirectional.
  • Kompella: The Kompella style of L2VPN is similar to Martini style as both use stacked labels before the Layer 2 payload and both can use LDP, RSVP or both as Transport Label. There difference comes in that unlike Martini, Kompella uses BGP signalling as its VC Label. This means you will need to have BGP enabled network, in addition, it’s not compulsory to send static LSPs as BGP provides a mechanism for autodiscovery of new point-to-point links similar to a VPLS. Although Kompella has a more complex configuration, because of its usage of BGP signalling it is regarded as the best option for large scale deployments as it will in-conjunction with other BGP families. RFC6624 has more details on L2VPN using BGP for Auto-Discovery and Signaling

In our network, we use the Kompella style of L2VPNs. The bulk and most depth of my testing was with that method… Although I was able to get a wee bit of naughty time after to configure the other methods 🙂

The topology I’ll be working with is a simple one. I’ve a got a single MX480 broken up into 3 Logical Systems.

L2VPN Topology


The underlying IGP is IS-IS with RSVP, LDP and BGP enabled. This is a mirror, of what we have in production. With all the L2VPNs the customer facing physical interface has to be set to the correct encapsulation. For my testing, as I wont be using VLANs, Bridging or Setting a VPLS. I used ethernet-ccc and had set the logical interface to family ccc, you can find out more about the different physical encapsulations here

Interface ConfigRSVPMPLSBGPIS-ISLDP
set interfaces xe-0/1/0 enable
set interfaces xe-0/1/0 encapsulation ethernet-ccc
set interfaces xe-0/1/0 unit 0 family ccc
set protocols rsvp interface xe-1/0/0.0
set protocols rsvp interface xe-1/0/2.0
set protocols mpls explicit-null
set protocols mpls ipv6-tunneling
set protocols mpls no-decrement-ttl
set protocols mpls interface xe-1/0/0.0
set protocols mpls interface xe-1/0/2.0
set protocols bgp group Master type internal
set protocols bgp group Master local-address 192.168.2.1
set protocols bgp group Master family inet unicast
set protocols bgp group Master family inet6 unicast
set protocols bgp group Master local-as 100
set protocols bgp group Master neighbor 192.168.2.2 
set protocols bgp group Master neighbor 192.168.2.3
set protocols isis reference-bandwidth 1000g
set protocols isis level 1 disable
set protocols isis level 2 wide-metrics-only
set protocols isis interface xe-1/0/0.0 ldp-synchronization
set protocols isis interface xe-1/0/0.0 point-to-point
set protocols isis interface xe-1/0/0.0 link-protection
set protocols isis interface xe-1/0/2.0 ldp-synchronization
set protocols isis interface xe-1/0/2.0 point-to-point
set protocols isis interface xe-1/0/2.0 link-protection
set protocols isis interface xe-1/0/3.0 ldp-synchronization
set protocols isis interface xe-1/0/3.0 point-to-point
set protocols isis interface xe-1/0/3.0 link-protection
set protocols isis interface lo0.0
sset protocols ldp track-igp-metric
set protocols ldp explicit-null
set protocols ldp transport-address router-id
set protocols ldp interface xe-1/0/0.0
set protocols ldp interface xe-1/0/2.0
set protocols ldp interface lo0.0

All configurations will be done on the Master and SiteA, and for my examples I will show work done on the Master Instance. With all that out of the way… Let’s get cracking 😀

Kompella

As stated before, BGP is used as the VPN signalling method, with that in mind, we will need to enable layer-2 signalling within MP-BGP. This is simply done by adding the command family l2vpn signaling with the BGP stanza. This can be added globally within BGP or under the specific neighbour.

set protocols bgp group Master family l2vpn signaling

With the signalling sorted we can go straight into the configuration of the L2VPN. Just like L3VPNs, L2VPNs configuration is done within the routing-instance stanza and uses the same parameters as L3VPN by having Route Distinguisher (RD) and Route-Target/vrf-target (RT). The RD has to be unique per device with RT matching on all devices within the L2VPN, this is important, so that traffic can be routed accordingly per site. In addition, routing-instance has to be set to l2vpn and the interface(s) have to be defined within the routing-instance as well.

set routing-instances Master instance-type l2vpn
set routing-instances Master interface xe-0/1/0.0
set routing-instances Master route-distinguisher 100:0001
set routing-instances Master vrf-target target:100:0000

Next the properties for that site within the L2VPN will need to configured under protocol l2vpn within the routing-instance. The encapsulation has to match all site that want to participate within the VPN. The Site identifier must be unique to the entire site within the L2VPN as the site ID is used to compute label values for site-to-site communications. The interface(s) have to be defined within l2vpn and l2vpn site stanzas.

set routing-instances Master protocols l2vpn encapsulation-type ethernet
set routing-instances Master protocols l2vpn interface xe-0/1/0.0
set routing-instances Master protocols l2vpn site Master site-identifier 1
set routing-instances Master protocols l2vpn site Master interface xe-0/1/0.0
Full Kompella Configuration
set routing-instances Master instance-type l2vpn
set routing-instances Master interface xe-0/1/0.0
set routing-instances Master route-distinguisher 100:0001
set routing-instances Master vrf-target target:100:0000
set routing-instances Master protocols l2vpn encapsulation-type ethernet
set routing-instances Master protocols l2vpn interface xe-0/1/0.0
set routing-instances Master protocols l2vpn site Master site-identifier 1
set routing-instances Master protocols l2vpn site Master interface xe-0/1/0.0
set protocols bgp group Master family l2vpn signaling

Verification

The primary command that will be used to check the status of a pseudowire would be show l2vpn connections. As Komplella signalling uses BGP, we will be able to do a show bgp summary and see a route being advertised within the l2vpn and routing instance tables show route table Master.l2vpn.0 or show route table bgp.l2vpn.0 respectfully. Additionally we will be able to mpls.0 table to confirm that the L2VPN incoming label and interface(s) for the pseudowire have made the routing table, by using show route table mpls.0.

Show l2vpn Connectionsshow bgp summaryshow route table Master.l2vpn.0show route table mpls.0
[email protected]> show l2vpn connections    
Layer-2 VPN connections:

Legend for connection status (St)   
EI -- encapsulation invalid      NC -- interface encapsulation not CCC/TCC/VPLS
EM -- encapsulation mismatch     WE -- interface and instance encaps not same
VC-Dn -- Virtual circuit down    NP -- interface hardware not present 
CM -- control-word mismatch      -> -- only outbound connection is up
CN -- circuit not provisioned    <- -- only inbound connection is up
OR -- out of range               Up -- operational
OL -- no outgoing label          Dn -- down                      
LD -- local site signaled down   CF -- call admission control failure      
RD -- remote site signaled down  SC -- local and remote site ID collision
LN -- local site not designated  LM -- local site ID not minimum designated
RN -- remote site not designated RM -- remote site ID not minimum designated
XX -- unknown connection status  IL -- no incoming label
MM -- MTU mismatch               MI -- Mesh-Group ID not available
BK -- Backup connection	         ST -- Standby connection
PF -- Profile parse failure      PB -- Profile busy
RS -- remote site standby	 SN -- Static Neighbor
LB -- Local site not best-site   RB -- Remote site not best-site
VM -- VLAN ID mismatch

Legend for interface status 
Up -- operational           
Dn -- down

Instance: Master
  Local site: Master (1)
    connection-site           Type  St     Time last up          # Up trans
    2                         rmt   Up     Jun  4 12:36:46 2016           2
      Remote PE: 192.168.2.2, Negotiated control-word: Yes (Null)
      Incoming label: 800001, Outgoing label: 800000
      Local interface: xe-0/1/0.0, Status: Up, Encapsulation: ETHERNET

[email protected]> show bgp summary 
Groups: 1 Peers: 2 Down peers: 0
Table          Tot Paths  Act Paths Suppressed    History Damp State    Pending
inet.0               
                       0          0          0          0          0          0
inet6.0              
                       0          0          0          0          0          0
bgp.l2vpn.0          
                       1          1          0          0          0          0
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
192.168.2.2             100       3234       3229       0       1  1d 0:19:17 Establ
  inet.0: 0/0/0/0
  inet6.0: 0/0/0/0
  Master.l2vpn.0: 1/1/1/0
  bgp.l2vpn.0: 1/1/1/0
192.168.2.3             100       5735       5724       0       1 1d 19:06:59 Establ
  inet.0: 0/0/0/0
  inet6.0: 0/0/0/0
  Master.l2vpn.0: 0/0/0/0
  bgp.l2vpn.0: 0/0/0/0/

[email protected]> show route table Master.l2vpn.0 

Master.l2vpn.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

100:1:1:1/96                
                   *[L2VPN/170/-101] 1d 20:37:12, metric2 1
                      Indirect
100:2:2:1/96                
                   *[BGP/170] 00:01:02, localpref 100, from 192.168.2.2
                      AS path: I, validation-state: unverified
                    > to 192.168.1.14 via xe-1/0/0.0, Push 0
                      to 192.168.1.6 via xe-1/0/2.0, Push 300000

[email protected]> show route table mpls.0 protocol l2vpn    

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

800001             *[L2VPN/7] 23:30:09
                    > via xe-0/1/0.0, Pop       Offset: 4
xe-0/1/0.0         *[L2VPN/7] 00:06:20, metric2 100
                    > to 192.168.1.14 via xe-1/0/0.0, Push 800000 Offset: 252
                      to 192.168.1.6 via xe-1/0/2.0, Push 800000, Push 300000(top) Offset: 252

From the end host point of view, we have end-to-end connectivity 😀

[email protected]:~$ ping -c 2 -q 192.168.137.3
PING 192.168.137.3 (192.168.137.3) 56(84) bytes of data.

--- 192.168.137.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.431/0.637/0.843/0.206 ms
Note
The route given from the show route table Master.l2vpn.0 is the Route Distinguisher of the other end of the pseudowire

Martini

Martini signalling uses LDP, as stated before, and with LDP enabled already, I will focus on the actual configuration, which is done within the protocol l2circuit stanza. Compared to Kompella, the configuration for Martini style of L2VPNs is much simpler. All that is needed is for:

  • The remote neighbour to be defined. In my example I will be using the loopback address SiteA as the remote neighbour
  • The customer facing interface connecting into the VPN
  • Set a circuit ID, that must match on both sides

All this can be done in one line!

set protocols l2circuit neighbor 192.168.2.2 interface xe-0/1/0.0 virtual-circuit-id 1

With that we have Martini style L2VPN configured 🙂

Verifications

To check the status of Martini style L2VPN, you will use show l2circuit connections, the output is near enough the same as show l2vpn connections. Martini, as discussed above, uses LDP for the signalling, we will be able to use show ldp neighbor to check that the neighbour relationship with the remote side has been successful and we will be able to check the LDP database by using show ldp database to verify that new labels associated with the pseudowire (L2CKT) has been installed into the database. Additionally you can check the inet.3 and mpls.0 routing tables, by using show route table inet.3 & show route table mpls.0

Show l2circuit Connectionsshow ldp neighborshow ldp databaseshow route table inet.3show route table mpls.0
[email protected]> show l2circuit connections 
Layer-2 Circuit Connections:

Legend for connection status (St)   
EI -- encapsulation invalid      NP -- interface h/w not present   
MM -- mtu mismatch               Dn -- down                       
EM -- encapsulation mismatch     VC-Dn -- Virtual circuit Down    
CM -- control-word mismatch      Up -- operational                
VM -- vlan id mismatch		 CF -- Call admission control failure
OL -- no outgoing label          IB -- TDM incompatible bitrate 
NC -- intf encaps not CCC/TCC    TM -- TDM misconfiguration 
BK -- Backup Connection          ST -- Standby Connection
CB -- rcvd cell-bundle size bad  SP -- Static Pseudowire
LD -- local site signaled down   RS -- remote site standby
RD -- remote site signaled down  HS -- Hot-standby Connection
XX -- unknown

Legend for interface status  
Up -- operational            
Dn -- down                   
Neighbor: 192.168.2.2 
    Interface                 Type  St     Time last up          # Up trans
    xe-0/1/0.0(vc 1)          rmt   Up     Jun  5 14:03:37 2016           1
      Remote PE: 192.168.2.2, Negotiated control-word: Yes (Null)
      Incoming label: 300000, Outgoing label: 300016
      Negotiated PW status TLV: No
      Local interface: xe-0/1/0.0, Status: Up, Encapsulation: ETHERNET
      Flow Label Transmit: No, Flow Label Receive: No

[email protected]> show ldp neighbor      
Address            Interface          Label space ID         Hold time
192.168.2.2        lo0.0              192.168.2.2:0            43
192.168.1.6        xe-1/0/2.0         192.168.2.3:0            14
192.168.1.14       xe-1/0/0.0         192.168.2.2:0            13

[email protected]> show ldp database                             
Input label database, 192.168.2.1:0--192.168.2.2:0
  Label     Prefix
 299984      192.168.2.1/32
      0      192.168.2.2/32
 300000      192.168.2.3/32
 300016      L2CKT CtrlWord ETHERNET VC 1

Output label database, 192.168.2.1:0--192.168.2.2:0
  Label     Prefix
      0      192.168.2.1/32
 299968      192.168.2.2/32
 299984      192.168.2.3/32
 300000      L2CKT CtrlWord ETHERNET VC 1

Input label database, 192.168.2.1:0--192.168.2.3:0
  Label     Prefix
 300016      192.168.2.1/32
 300000      192.168.2.2/32
      0      192.168.2.3/32

Output label database, 192.168.2.1:0--192.168.2.3:0
  Label     Prefix
      0      192.168.2.1/32
 299968      192.168.2.2/32
 299984      192.168.2.3/32

[email protected]> show route table inet.3 192.168.2.2 

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

192.168.2.2/32     *[LDP/9] 1d 21:16:06, metric 100
                    > to 192.168.1.14 via xe-1/0/0.0, Push 0
                      to 192.168.1.6 via xe-1/0/2.0, Push 300000
                    [RSVP/10/1] 1d 01:14:11, metric 100
                    > to 192.168.1.6 via xe-1/0/2.0, label-switched-path to-siteA

[email protected]> show route table mpls.0 protocol l2circuit 

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

300000             *[L2CKT/7] 00:05:13
                    > via xe-0/1/0.0, Pop       Offset: 4
xe-0/1/0.0         *[L2CKT/7] 00:05:13, metric2 100
                    > to 192.168.1.14 via xe-1/0/0.0, Push 300016 Offset: 252
                      to 192.168.1.6 via xe-1/0/2.0, Push 300016, Push 300000(top) Offset: 252

From the end host point of view, connectivity between the two is there 🙂

[email protected]:~$ ping -c 2 -q 192.168.137.3
PING 192.168.137.3 (192.168.137.3) 56(84) bytes of data.

--- 192.168.137.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.358/0.532/0.707/0.176 ms

Circuit Cross-Connect

As CCC doesn’t support stacked labels unlike Kompella and Martini, we will need to configure 2 static LSPs between the PE routers. CCC needs to have a LSP for to transmit and another to receive traffic. So firstly, we will need to get the LSPs configured. The received LSP will be configured on the remote PE, so under protocols mpls label-switched-path stanza, this is where we will define the LSP. I've used the loopback address of the remote end with the underlying IGP working out the best path.

set protocols mpls label-switched-path to-siteA to 192.168.2.2
set protocols mpls label-switched-path to-siteA no-cspf

With the LSPs configured, we will need to go under the protocol connections stanza. We need to define the customer facing interface(s) that will be connecting into the VPN, then set the transmit LSP and receive LSP, this will be the name of the LSP set on the remote end.

set protocols connections remote-interface-switch siteA interface xe-0/1/0.0
set protocols connections remote-interface-switch siteA transmit-lsp to-siteA
set protocols connections remote-interface-switch siteA receive-lsp to-Master

With that we are sorted!

Verifications

In regards with CCC there's less show commands, from what I’ve found (let me know if there's more please), but we can check the pseudowire's status by using show connections. We can confirm the Transmit (Ingress) and Receive (Egress) LSP using show mpls lsp and finally, we will be able to mpls.0 table to confirm that the L2VPN incoming label and interface(s) for the pseudowire have made the routing table, by using show route table mpls.0.

Show Connectionsshow mpls lspshow route table mpls.0
[email protected]> show connections 
CCC and TCC connections [Link Monitoring On]
Legend for status (St):             Legend for connection types:
 UN -- uninitialized                 if-sw:  interface switching
 NP -- not present                   rmt-if: remote interface switching
 WE -- wrong encapsulation           lsp-sw: LSP switching
 DS -- disabled                      tx-p2mp-sw: transmit P2MP switching
 Dn -- down                          rx-p2mp-sw: receive P2MP switching
 -> -- only outbound conn is up     Legend for circuit types:
 <- -- only inbound  conn is up      intf -- interface
 Up -- operational                   oif  -- outgoing interface
 RmtDn -- remote CCC down            tlsp -- transmit LSP
 Restart -- restarting               rlsp -- receive LSP


Connection/Circuit                Type        St      Time last up     # Up trans
siteA                             rmt-if      Up      Jun  3 12:42:55           1
  xe-0/1/0.0                        intf  Up
  to-siteA                          tlsp  Up
  to-Master                         rlsp  Up

[email protected]> show mpls lsp                           
Ingress LSP: 1 sessions
To              From            State Rt P     ActivePath       LSPname
192.168.2.2     192.168.2.1     Up     0 *     to-siteA         to-siteA
Total 1 displayed, Up 1, Down 0

Egress LSP: 1 sessions
To              From            State   Rt Style Labelin Labelout LSPname 
192.168.2.1     192.168.2.2     Up       0  1 FF  300080        - to-Master
Total 1 displayed, Up 1, Down 0

Transit LSP: 0 sessions
Total 0 displayed, Up 0, Down 0

[email protected]> show route table mpls.0 protocol ccc    

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

300080             *[CCC/7] 00:00:04
                    > via xe-0/1/0.0, Pop      
xe-0/1/0.0         *[CCC/10/1] 00:00:04, metric 100
                    > to 192.168.1.14 via xe-1/0/0.0, label-switched-path to-siteA

Finally to confirm end-to-end reachability between the end hosts

[email protected]:~$ ping -c 2 -q 192.168.137.3
PING 192.168.137.3 (192.168.137.3) 56(84) bytes of data.

--- 192.168.137.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.358/0.532/0.707/0.176 ms

I had planned to have a wee bit more to this post, with what I was actually testing ,however, this is getting a bit longer than I expected, so I'll make this into a two-part 😉

My next post will detail, how you can use traffic engineering to manipulate a L2VPN path between 2 PE routers! Hope to see you there 😀

References

Darren's Blog L2VPN in Junos
RFC4665
MPLS l2VPN
RFC6624
RFC6074
Vlan based CCC L2vpn

Share this:
Share

Leaking Routes into a Routing-Instance

Reading Time: 4 minutes

In a previous post I wrote about how I went about configuring a NTP server and setting NTP clients. A few days later, when speaking with my senior, the plan changed slightly and we weren’t configuring our own NTP server using Linux based OS, but get satellite feeds running our own LANTIME Stratum 1 Server o_O! In other words that previous post is now invalid haha!

For now I don’t know if I’ll be involved in that side of the project, I hope I am, but that’s for another day! Back to my actual point, because of the environment we run in our datacentres, our firewalls run with Virtual-Router Routing-Instances. A Virtual Router is similar than Cisco’s VRF concept however, with Juniper’s a Virtual Router is used for non-VPN related applications. So, I was asked to investigate if it was possible for our firewalls to be NTP clients to a NTP server via the master instance and also be able to act as a NTP server to attached clients within a routing-instance.

Note
You can get more detail about Juniper’s Routing-Instance Types on their TechLibrary Routing Instances Overview

Although it sounds a bit of a mouthful, the topology itself is quite straightforward. The diagram below shows the topology I’ll be testing with:

Routing

As the diagram shows, I’ll be using a standalone Juniper SRX220h and two ESXi Ubuntu 14.04LTS servers. The SRX will be a NTP client of the NTP server (km-vm4) via the master inet.0 table. The second client km-vm1 will be located within the Routing-Instance “test” and will be using the SRX220 as its NTP server. Security policies will need to be defined, as the stateful functionalities of the SRX will still be in use. Without creating security between the zones all traffic will be dropped.

Note
The Base configuration used in this topology is below. (I using this SRX for IPv6 testing as well, so ignore the vlan name lol)
Base Config
set interfaces ge-0/0/0 enable
set interfaces ge-0/0/0 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members internal-v6
set interfaces ge-0/0/1 enable
set interfaces ge-0/0/1 unit 0 family ethernet-switching port-mode access
set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members ntp-server
set interfaces vlan unit 100 family inet address 192.168.1.1/24
set interfaces vlan unit 101 family inet address 192.168.2.1/24

set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp match source-address any
set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp match destination-address any
set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp match application junos-ntp
set security policies from-zone vlan100 to-zone vlan101 policy allow-ntp then permit

set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp match source-address any
set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp match destination-address any
set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp match application junos-ntp
set security policies from-zone vlan101 to-zone vlan100 policy allow-ntp then permit

set security zones security-zone vlan100 interfaces vlan.100 host-inbound-traffic system-services any-service
set security zones security-zone vlan101 interfaces vlan.101 host-inbound-traffic system-services any-service

set routing-instances test instance-type virtual-router
set routing-instances test interface vlan.100

set vlans internal-v6 vlan-id 100
set vlans internal-v6 l3-interface vlan.100
set vlans ntp-server vlan-id 101
set vlans ntp-server l3-interface vlan.101

With this setup, the overall goal of this testing is to see if it’s possible to advertise specific routes from the inet.0 table to another routing table, to allow end to end connectivity between routing instances.

This post will not show/explain how the stateful functionalities of the SRX series firewall works. That will be in another post :p

With all that talk and background out of the way… Let’s get cracking 🙂

With the NTP server already configured, the SRX need to set as an NTP client. This configuration is done under system ntp stanza. We set the remote server, ntp version and preference. In addition, I set two other statements; one is optional and the other had to be set. The statements, boot-server and source-address, Juniper defines these statements as:

  • boot-server: When the router or switch boots, it immediately synchronizes with the boot server even if the NTP process is explicitly disabled or if the time difference between the client and the boot server exceeds the threshold value of 1000 seconds.
  • source-address: This is statement useful for controlling which source address NTP will use to access your network when it is either responding to an NTP client request from your network or when it itself is sending NTP requests to your network.

As described above, and in a nutshell, by adding the source-address this will allow other clients/devices to set an IP address that’s located on the SRX as their remote NTP server. Thus providing a /32 address that can be advertised. For my example the address 192.168.2.1, the gateway address for the ntp server, will be the address used as the source address.

[email protected]# show system ntp 
boot-server 192.168.2.100;
server 192.168.2.100 version 4 prefer;
source-address 192.168.2.1;

We can verify the NTP association by using the command show ntp assocication.

[email protected]# run show ntp associations                      
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.2.100   43.255.190.16    3 -  148  256  377    2.313    0.748   0.063

With NTP verified on the SRX, we have to leak the NTP source address for the SRX 192.168.2.1 from the inet.0 table to the test.inet.0 table. As we can see, when we look at the routing instance’s routing table, we don’t have the route installed into the table:

[email protected]# run show route table test.inet.0      

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

192.168.1.0/24     *[Direct/0] 04:02:28
                    > via vlan.100
192.168.1.1/32     *[Local/0] 06:31:31
                      Local via vlan.100

To get the route installed into the test.inet.0 table, we’ll need to leak the 192.168.2.1/32 route into the test.inet.0 table, and we’ll do this by creating two policy statements. For my example I’ve named them master and instance just for ease!

  • Master: This statement allows all routes from routing instance test to be accepted into the master routing table.
  • Instance: This statement has two terms. Term 1 only allows the exact route 192.168.2.1/32 from the master instance to be accepted. Term 2 denies all other routes from master instance.
[email protected]# show policy-options 
policy-statement master {
    from instance test;
    then accept;
}
policy-statement instance {
    term 1 {
        from {
            instance master;
            route-filter 192.168.2.1/32 exact;
        }
        then accept;
    }
    term 2 {
        then reject;
    }
}

Now we’ll need to import the relevant policy into each instance, under the routing-options stanza for the inet.0 table and routing-instance test routing-options for the test.inet.0 table.

Master Instance Routing-OptionsRouting-Instance Routing-Options
[email protected]# show routing-options 
static {
    route 0.0.0.0/0 {
        next-hop 10.1.0.1;
        no-readvertise;
    }
}
instance-import master;
[email protected]# show routing-instances test routing-options 
instance-import instance;

Having committed the policy statements, when we check both routing tables we can see the 192.168.1.0/24 route have been leaked into the inet.0 table, and that only the 192.168.2.1/32 route has been installed into the test.inet.0 table. All other routes have not been leaked.

inet.0 tabletest.inet.0 table
[email protected]> show route table inet.0 

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


0.0.0.0/0          *[Static/5] 1w2d 09:40:34
                    > to 10.1.0.1 via ge-0/0/7.0
10.1.0.0/24        *[Direct/0] 1w2d 09:40:34
                    > via ge-0/0/7.0
10.1.0.158/32      *[Local/0] 1w2d 09:40:39
                      Local via ge-0/0/7.0
192.168.1.0/24     *[Direct/0] 2d 04:15:32
                    > via vlan.100
192.168.1.1/32     *[Local/0] 2d 04:15:32
                      Local via vlan.100
192.168.2.0/24     *[Direct/0] 2d 07:20:32
                    > via vlan.101
192.168.2.1/32     *[Local/0] 3d 08:44:24
                      Local via vlan.101
[email protected]> show route table test.inet.0   

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

192.168.1.0/24     *[Direct/0] 09:32:22
                    > via vlan.100
192.168.1.1/32     *[Local/0] 12:01:25
                      Local via vlan.100
192.168.2.1/32     *[Local/0] 05:28:32
                      Local via vlan.101

Finally, on the client we’ll need to set a static route so that the host knows if it wants to get the 192.168.2.0/24 subnet it will need to use the gateway 192.168.1.1 via eth1

[email protected]:~$ sudo route add -net 192.168.2.0/24 gw 192.168.1.1 dev eth1
[email protected]:~$ ip route
default via 10.1.0.1 dev eth0 
10.1.0.0/24 dev eth0  proto kernel  scope link  src 10.1.0.137 
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.100 
192.168.2.0/24 via 192.168.1.1 dev eth1

Once that route has been installed we can see that the host has now become a NTP client to the SRX by running the command ntpq -p. In addition on the SRX, we can see the flow session between inet.0 and test.inet.0 routing tables.

NTP AssociationSRX flow Session
[email protected]:~$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*192.168.2.1     192.168.2.100    4 u   15   64    3    2.086   -0.094   0.109
[email protected]> show security flow session destination-prefix 192.168.2.1 
Session ID: 21218, Policy name: allow-ntp/4, Timeout: 40, Valid
  In: 192.168.1.100/123 --> 192.168.2.1/123;udp, If: vlan.100, Pkts: 7, Bytes: 532
  Out: 192.168.2.1/123 --> 192.168.1.100/123;udp, If: .local..5, Pkts: 7, Bytes: 532
Total sessions: 1

And with that we’ve been able to route between routing instances! The most important thing that I found whilst do this testing is that you need to remember to add the static route on the host or device that is directly connected to router with the routing-instance. This same setup would work with a switch in between the SRX and end host, just have the static route and you’ll be sorted. In addition to having the right security policies, as they’ll bite you in the bum as well :p

I’ve included the set commands that I used in my example below, if you wanted to give it a try for yourself 🙂

Set Commands
set system ntp boot-server 192.168.2.100
set system ntp server 192.168.2.100 version 4
set system ntp server 192.168.2.100 prefer
set system ntp source-address 192.168.2.1

set routing-options instance-import p1

set policy-options policy-statement p1 from instance test
set policy-options policy-statement p1 then accept

set policy-options policy-statement p2 term 1 from instance master
set policy-options policy-statement p2 term 1 from route-filter 192.168.2.1/32 exact
set policy-options policy-statement p2 term 1 then accept
set policy-options policy-statement p2 term 2 then reject

set routing-instances test routing-options instance-import p2

Reference

Juniper Knowledge Base: NTP over routing-instance on EX-series switches
Juniper TechLibrary: NTP Configuring

Share this:
Share

SNMP Polling over a Routing Instance

Reading Time: 3 minutes

Polling SNMP over a Routing Instance is quite straightforward once you understand the syntax necessary to specify that you want to poll the routing-instance. But when I tried this the first time, I didn’t have a clue why it didn’t work!

For a bit of background, we had a request from another team who’s network we manage, asking if they could SNMP details so they could poll an edge pair of SRX240’s. We use a routing instance to keep the management traffic separate from production traffic, so configured a SMNPv2 community and asked them to test it, but and they said it wasn’t working… BALLS :S

I set this up in the lab for testing; I used a Juniper SRX220 with Routing-Instance that had a Ubuntu 14.04LTS host directly connected to poll SNMP

I had configured SNMPv2 and enabled it to allow the relevant routing-instance to have access under the community stanza and enabled routing instance access under the overall stanza as well, thinking that this would be enough:

[edit]
[email protected]# show snmp 
community test {
    authorization read-only;
    routing-instance test {
        clients {
            192.168.1.0/24;
        }
    }
}
routing-instance-access;

However, when I did a snmpwalk….. I got nothing :/

[email protected]:~$ snmpwalk -v2c -ctest 192.168.1.1
^C

Not Good 🙁

I messed about with the configuration and asked a few colleagues and a senior, but none of them could see the issue. So, as you do when you don’t have a clue…. Time to Google! From my searches managed to find Juniper KB page that explained the different variations of syntax when polling SNMPv1/v2c with Routing Instances

There are 3 variations:

  • community string – which works if the user polls directly from inet.0
  • [email protected] string – which polls information for specific routing instance
  • [email protected] string – which allows polling information about inet.0 only

In essence when I was tried to SNMP poll the SRX with the syntax snmpwalk -v2c -ctest 192.168.1.1, it wasn’t referencing the routing instance because snmpwalk was trying to poll the master instance, which routing-instance had no access to.

For the syntax, I should have been using was snmpwalk -v2c [email protected] 192.168.1.1. By referencing the routing instance I was able to SNMP poll the SRX and all the interfaces that were within the routing-instance:

[email protected]:~$ snmpwalk -v2c [email protected] 192.168.1.1
\iso.3.6.1.2.1.1.1.0 = STRING: "Juniper Networks, Inc. srx220h2 internet router, kernel JUNOS 12.1X47-D30.4 #0: 2015-11-13 14:16:02 UTC     [email protected]:/volume/build/junos/12.1/service/12.1X47-D30.4/obj-octeon/junos/bsd/kernels/JSRXNLE/kernel Build date: 2015-11-13 15:4"

SNMPv3 Polling

For SNMPv3 when configuring your user, under snmp v3 access group stanza, the context-prefix HAS to be the same name as the Routing-Instance

[email protected]# show snmp 
v3 {
    usm {
        local-engine {
            user keeran {
                authentication-sha {
                    authentication-key "$9$WS8LdbYgojk.aJDkqmF3Ap01cyevWXNdleZUDjq.hSyKLx-VwoaUbwgJGU.m1RESrvXxdsYohSvLxNY2z3n/p0REylvW1IxN-VY2JGDk5Q/Ct01RUjqfzFAt8XxdYgDikf5FGU69CA0OLx7NdsUjHTFniHmTznCA8Xx7s2aJDmPQjiCt0ORE-VbsYo"; ## SECRET-DATA
                }
                privacy-des {
                    privacy-key "$9$qmz3/CtIhSpu1hcyW8-Vw2JGjHqPTzDj0B1IcSaZGimfQFntpB3nCuOBSy24oZUHPfz6/taZHmfT/9M8LxVw4oGDHq2gfTQF/9uO1hevxNdw24BIclMW-d.Pfz/C1RhleWOBX7N-wsmf5Tz6BIEKWLREyKMLN-.Pf569pu1yrvIRNdws4oQF36/t"; ## SECRET-DATA
                }
            }
        }
    }
    vacm {
        security-to-group {
            security-model usm {
                security-name keeran {
                    group view-all;
                }
            }
        }
        access {                        
            group view-all {
                context-prefix test {
                    security-model usm {
                        security-level privacy {
                            read-view view-all;
                            notify-view view-all;
                        }
                    }
                }
            }
        }
    }
}
view view-all {
    oid .1 include;
}
routing-instance-access;

Then when you run the snmpwalk you’ll need to add the flag -n to specify the context name, which will be the routing-instance. If you’ve used the same authentication and privacy types as me, your syntax should look something like this: snmpwalk -v 3 -u keeran -l authPriv -a SHA -A test1234 -x DES -X test1234 -n test 192.168.1.1

snmpwalk -v 3 -u keeran -l authPriv -a SHA -A test1234 -x DES -X test1234 -n test 192.168.1.1
iso.3.6.1.2.1.1.1.0 = STRING: "Juniper Networks, Inc. srx220h2 internet router, kernel JUNOS 12.1X47-D30.4 #0: 2015-11-13 14:16:02 UTC     [email protected]:/volume/build/junos/12.1/service/12.1X47-D30.4/obj-octeon/junos/bsd/kernels/JSRXNLE/kernel Build date: 2015-11-13 15:4"

This was pretty frustrating as there was no clear reason why it wasn’t working, and something that should have taken a few moments took days! So I’m hoping this will help you so that you don’t end up in a bit of a rage like I was lol

References

Juniper Knowledge Base: SNMP Polling SNMPv1/v2c via Routing Instance
Juniper Knowledge: SNMP Polling SNMPv3 via Routing Instance
Snmpwalk Man Page
snmpwalk -h

Share this:
Share