Uncategorized

JUNOScript – First attempt

So, there are many things that make Junos very robust and flexible.  One of the more rarely used, and more powerful is the built in scripting capabilities.  We’ve found a couple of situations where a script would come in very handy.

  1. By default, Juniper routers have all interfaces in an admin up state.  This is great, except for the fact that our NMS alarms on any interface that is admin up, but down, so this kicks off all kinds of alarms
  2. Every GigE port in our network has a single vlan that is used for management, and must be ‘bridged’ together.  Its really common to forget to add a newly configured interface to the bridge-group.

Interface-disable.slax

We’ve got this great script we’ve been using that transitively disables any unconfigured interface.  While I think its excellent to admin up interfaces by default, most NMS’s assume there is a problem with an interface in up/down status, so in order to avoid alarms, we’ve been using this script:

/*
 * This script transiently disables all unconfigured ge interfaces.
 */

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

    /* Get the current interface list  */
    var $interfaces = jcs:invoke( "get-interface-information" );

    /* Only ge and xe interfaces */
    var $ge-interfaces = $interfaces/physical-interface[starts-with(name, "ge-") or starts-with(name, "xe-")];

    var $interface-hierarchy = interfaces;

    /* Go through each ge interface, if it isn't within the configuration than transiently disable it */
    for-each( $ge-interfaces ) {

        if( jcs:empty( $interface-hierarchy/interface[name == current()/name ] ) ) {
            <transient-change> {
                <interfaces> {
                    <interface> {
                        <name> name;
                        <disable>;
                    }
                }
            }
        }
    }
}

This works really well, with one exception.  After a power failure, the transient change is lost, and all unconfigured interfaces are in up/down status until someone logs in and does a commit.  While I enjoy the clean looking config the transitive solution offers, we’ve had a need to ensure this initial alarming doesn’t happen, which means we need to change the config non-transitively.

Below is the config I will apply (I use the group so during configuration later, all child units are also disabled, which has more to do with our internal processes than anything technical) to each interface.

interfaces {
    <*> {
        disable;
        unit <*> {
            disable;
        }
    }
}

interfaces {

    ge-0/0/0 {

        apply-groups DISABLEIF;

    }

}

Here is the non-transitive script to use that will apply the DISABLEIF group to each interface:

/*
 * This script disables all unconfigured ge interfaces.
 */

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

    /* Get the current interface list  */
    var $interfaces = jcs:invoke( "get-interface-information" );

    /* Only ge and xe interfaces */
    var $ge-interfaces = $interfaces/physical-interface[starts-with(name, "ge-") or starts-with(name, "xe-")];

    var $interface-hierarchy = interfaces;

    /* Go through each ge interface, if it isn't within the configuration than apply-group DISABLEIF */
    for-each( $ge-interfaces ) {

        if( jcs:empty( $interface-hierarchy/interface[name == current()/name ] ) ) {
	     <xnm:warning> {
		<message> "Disabling unconfigured interface: " _ name;
	     }
	     <change> {
                <interfaces> {
                    <interface> {
                        <name> name;
                        <apply-groups> "DISABLEIF";
                    }
                }
	     }
        }
    }

}

You’ll have to store this file on the router’s hard drive in /var/db/scripts/commit/

Of course, you must tell your router to run this script on each commit:

set system script commit file "interface-disable.slax"

I’ll cover the bridge-domain update in another post!

Advertisements
Uncategorized

SSH Errors when connecting to a Juniper Netscreen SSG5-GT

Recently, I started working with Netscreens, which I haven’t done for 10 years or so. Things have changed a bit. As I’m learning ScreenOS, and trying to get around and configure these things, I’m getting really aggravated because while I’m RTFM’ing, the ssh session keeps disconnecting with this error:

buffer_get_ret: trying to get more bytes 4 than in buffer 0
buffer_get_int: buffer error

It only seems to happen after a very short period of inactivity though. Highly reproducible, and seems to happen from all my OSX clients I’ve tried. So, I try from a ubuntu box, and it doesn’t happen, which leads me to evaluate what is different between the two. Both are running the same OpenSSH version, but a different OpenSSL version. Oh, and the Ubuntu config is a stock vanilla config, while the OSX boxes all have a custom ~/.ssh/config that is used to set usernames and a few ssh options to make my life easier.

So, I renamed ~/.ssh/ on a OSX box, and the problem vanishes! This tells me it has to do with my ssh config. After a bit of troubleshooting, I isolated the problem in this portion of my ~/.ssh/config file:

Host *
ServerAliveInterval 30

I use this command to keep from timing out on SSH servers that boot you for inactivity. It works fine for all the servers I’ve used, until now. Apparently when the SSH client detects 30 seconds of inactivity, it sends some sort of stay alive message, which the Netscreen fails to handle and decides to immediately disconnect.

To work around this, set this value to 0 (to disable) on your Netscreen hosts in the ~/.ssh/config file:

Host vpn*
ServerAliveInterval 0

All my Netscreens are in my hostfile and begin with vpn-

You need to put the hostname, IP address with or without the asterisk wildcard for your situation.

Hope you found this helpful. I was unable to find ANYTHING on the net that explains this.

EDIT: Michael Newton has had success in adding the following options as well to the Host entry in the ssh config:

Host ns5gt
TCPKeepAlive no
ServerAliveInterval 0
HostKeyAlgorithms ssh-dss

Uncategorized

EVPL vs E-TREE

Just finished watching a MEF webcast on ethernet backhaul for mobile wireless.

While this is interesting, MEF (as always) doesn’t give you any technical details about how it can be done.  Its refreshing to see that what I’ve been working on is 100% in line with MEF’s vague standards.  😉

On another note, I noticed that they are starting to more predominantly use the term ETREE instead of EVPL.  They should pick one and stick to it.  Also, the diagram for EVPL/ETREE uses a ‘Ethernet LAN’ symbol with dotted lines showing the ‘ROOT’ and ‘LEAF’ relationships.  Seems to me they expect EVPL to be a LAN with some mechanism to prevent LEAVES from seeing one another.

This deviates from what I’ve seen most folks do.  The problem I’ve seen with the EVPL/ETREE service, is most folks approach the problem by stacking multiple EVC’s on the same trunk handoff to a customer.  This breaks transparency and requires tag coordination w/the customer, and breaks L2protocol tunneling, and just causes general headaches for everyone involved.

I thought of an illustration of how to accomplish this at L2 that would help the engineers with more L2 experience.

Its essentially the same notion as Private VLAN’s (the community port is the root, and pvlan ports are leaves)

Roots and Leaves
Roots and Leaves

So, the idea is if the root sends a unknown unicast frame, the switch will tag it with 20 (incoming/outgoing in the diagram is from the switch port’s perspective).  20 can be accepted at the other root, and each of the leafs, so this frame will be flooded at all ports.

If a leaf sends an unknown unicast frame, the switch will tag it with 10.  The switch is configured to send VLAN 10 ONLY to the root ports, so this frame will be flooded at the two ROOT ports, and NOT the leaf ports.

The same principle applies to how we do this using VPLS on the Junipers.  The difference is we’re using the VRF-target to control what traffic is being sent to.  Using the same ID’s for the diagram above, for VPLS with a single root we’d do:

routing-instances Acme {
   // Root
   export target:11427:10;
   // Leaf
   import target:11427:20;
}

With multiple roots, it gets a little more complex if you want roots to speak to one another:

policy-options {
	//first we define a policy that will bgp tag traffic leaving the root
	policy-statement CUST-Acme_EXPORT {
		term 1 {
			from protocol bgp;
			then {
				community add CUST-Acme_Roots;
			}
		}
		term 2 {
			then reject;
		}
		then accept;
	}
	//next a policy that matches traffic from the other root and leaves (for a leaf site, we'd remove the 'Leafs' community here)
	policy-statement CUST-Acme_IMPORT {
		term 1 {
			from {
				protocol bgp;
				community [ CUST-Acme_Leafs CUST-Acme_Roots ];
			}
		}
	}
	community CUST_Acme_Roots members 123:10;
	community CUST_Acme_Leafs members 123:20;
}
routing - instances Acme {
	instance-type vpls;
	interface ge-0/0/0.200
	no-local-switching;
	vrf-import CUST-Acme_IMPORT;
	vrf-export CUST-Acme_EXPORT;
	protocols {
		vpls {
			vpls-id 1234;
		}
	}
}

All, very fun stuff and very flexible.

Uncategorized

Philosophy

Well, this notion of ‘blogging’ isn’t unfamiliar to me, but I’m certainly not experienced with it, so hang in there.  It’ll get better with time.  I intend to focus this primarily on Network Engineering, which is a topic I really love.  Coincidentally, I get paid to think about this stuff, so technically I’m a professional.  In reality though, I know that I understand a fraction of what is out there.  I hope to share my fraction in an effort to strengthen my own understanding, and I encourage you to reciprocate with ideas and knowledge you have that may compliment.

Continue reading “Philosophy”