Blogs

Scripting How-To: Use show-bgp-policy to display all routing-policies in sequential order for a selected BGP peer

By Erdem posted 08-14-2015 15:42

  

Overview

Display all routing-policies in sequential order for a selected BGP peer. This applies to SLAX version 1.0 and higher.

Description

This script provides an easy way to study the complete policy chain of a BGP peer. With multiple BGP policies in an import or export policy chain, it can become troublesome to determine what action will be taken for a particular prefix because the policies will usually not appear in the desired order within the policy-options hierarchy in the configuration.

The configuration text for each policy in the policy chain for the selected peer is extracted by the script and then displayed to the console in the correct sequential order. Through use of this op script, a user can easily read the complete policy chain from start to finish.

Three are three command-line arguments:

  • neighbor - Specificy which BGP peer to view
  • direction - Choose the import or export direction
  • database - The policies can be viewed from either the committed database (the default), or the candidate database.

 

Minimum Junos Version: 8.2
Latest Script Version: 1.0
MD5 Checksum: 4b830f1cc024657d621d0668e4af092f
SHA-256 Checksum: 963dd0f98f7f15d8728343b77d37e07b202362a7c8f682c464600fefeec86787

Source Code

 

GitHub Links

 

The source code below is also available from GitHub at the following locations:

 

Example Output

01 [edit protocols bgp group test]
02 user@cli# run op show-bgp-policy neighbor 10.0.0.1 direction import database candidate
03 BGP Neighbor: 10.0.0.1 in group test
04 Import Policies: block-private block-local adjust-local-pref
05 Policy: block-private
06     policy-statement block-private {
07         from {
08             route-filter 192.168.0.0/16 orlonger;
09             route-filter 10.0.0.0/8 orlonger;
10             route-filter 172.16.0.0/12 orlonger;
11         }
12         then reject;
13     }
14 Policy: block-local
15     policy-statement block-local {
16         from {
17             route-filter 1.0.0.0/24 orlonger;
18         }
19         then reject;
20     }
21 Policy: adjust-local-pref
22     policy-statement adjust-local-pref {
23         then {
24             local-preference 90;
25         }
26     }   

SLAX Script Contents

 
001 /* 

002  * Author        : Curtis Call 

003  * Version       : 1.0 

004  * Last Modified : October 6, 2009 

005  * Platform      : all 

006  * JUNOS Release : 8.2 and above 

007  * License       : Public Domain 

008  * 

009  * This op script displays the full chain of policy configuration for a given 

010  * neighbor and import/export direction.  Either the candidate or the committed 

011  * database can be used, with the committed database used by default. 

012  * 

013  * Usage: op show-bgp-policy neighbor 10.0.0.1 direction import 

014  * 

015  */ 

016   

017 version 1.0; 

018   

019 ns junos = "http://xml.juniper.net/junos/*/junos"; 

020 ns xnm = "http://xml.juniper.net/xnm/1.1/xnm"; 

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

022   

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

024   

025 /* 

026  * The $arguments global variable is a special variable which JUNOS reads to build 

027  * the CLI help for the script.  The command-line arguments will appear within the help 

028  * along with their description as long as the following format is followed. 

029  */ 

030 var $arguments = { 

031     <argument> { 

032         <name> "neighbor"; 

033         <description> "Required: The BGP neighbor address"; 

034     } 

035     <argument> { 

036         <name> "direction"; 

037         <description> "Required: Policy direction, either import or export"; 

038     } 

039     <argument> { 

040         <name> "database"; 

041         <description> "Optional: Specify either the [committed] or candidate database"; 

042     } 

043 } 

044   

045 /* These global parameters are assigned based on their corresponding command-line arguments */ 

046 param $neighbor; 

047 param $direction; 

048 param $database="committed"; 

049   

050 match / { 

051     <op-script-results> { 

052       

053         /* 

054          * The script first sanity checks the $neighbor and $direction command-line arguments.  If they 

055          * have not been set correctly then the script exits by using the <xsl:message> command element 

056          * and specifying that the script should end by setting the terminate attribute to "yes". 

057          */ 

058         if( jcs:empty( $neighbor ) or jcs:empty( $direction ) or 

059             ( $direction != "import" and $direction != "export" ) ) { 

060             <xsl:message terminate="yes"> "The neighbor address and policy direction must be specified."; 

061         } 

062           

063         /* 

064          * The database should be set to either "committed" or "candidate", if not then exit the script 

065          * with an error 

066          */ 

067         if( $database != "committed" and $database != "candidate" ) { 

068             <xsl:message terminate="yes"> "The database is not set correctly."; 

069         } 

070       

071         /* 

072          * This API element is used to retrieve the configuration.  Either the candidate or the committed 

073          * configuration can be used.  The choice is based on the $database command-line argument.  In 

074          * addition the inherit attribute has been set.  This is used to request that the configuration be 

075          * retrieved in inherited mode meaning that all configuration from configuration groups will be 

076          * inherited into its proper hierarchy level.  This is done so that the script has an accurate view 

077          * of the current BGP policy configuration. 

078          */ 

079         var $get-bgp-rpc =  <get-configuration database=$database inherit="inherit"> { 

080                                 <configuration> { 

081                                     <protocols> { 

082                                         <bgp>; 

083                                     } 

084                                 } 

085                             } 

086           

087         /* 

088          * The assembled API element is sent to JUNOS through jcs:invoke and the XML response stored in 

089          * $bgp-config 

090          */                    

091         var $bgp-config = jcs:invoke( $get-bgp-rpc ); 

092           

093         /* 

094          * The BGP neighbor is extracted from the configuration through a location path.  The last() 

095          * function is used to guarantee that only one element node will be returned.  It returns true 

096          * only if the node is the last in the node list so only one node can be selected and assigned to 

097          * $bgp-neighbor. 

098          */ 

099         var $bgp-neighbor = $bgp-config/protocols/bgp//neighbor[name == $neighbor ][last()]; 

100           

101         /* 

102          * Error check, if the $bgp-neighbor is missing than jcs:empty() will return true and the script 

103          * will be terminated with an error message. 

104          */ 

105         if( jcs:empty( $bgp-neighbor ) ) { 

106             <xsl:message terminate="yes"> "BGP Neighbor " _ $neighbor _ " isn't configured."; 

107         } 

108           

109         /* 

110          * Begin the output.  The BGP neighbor will be shown first as well as the BGP group it is in. 

111          */ 

112         <output> "BGP Neighbor: " _ $neighbor _ " in group " _ $bgp-neighbor/../name; 

113           

114         /* 

115          * The BGP policy list will now be retrieved.  To do this the jcs:first-of() function is used. 

116          * This is necessary because a BGP peers policy can be configured at up to three different 

117          * hierarchy levels: the neighbor level, the group level, or the bgp level.  The peer uses the 

118          * policy configuration at the most specific level.  jcs:first-of() works by checking multiple 

119          * node-set arguments.  The first node-set that is not empty will be returned.  So in this case 

120          * three separate location paths are provided (each of which results in a node-set).  The first 

121          * location path refers to any policies at the neighbor level, the second pulls policies at the 

122          * group level, and the last pulls policies at the bgp level. 

123          */ 

124         var $policy-list = jcs:first-of( $bgp-neighbor/*[name()==$direction], 

125                                          $bgp-neighbor/../*[name()==$direction], 

126                                          $bgp-neighbor/../../*[name()==$direction] ); 

127           

128         /* 

129          * Error check, if there are no policies then the script can terminate. 

130          */ 

131         if( jcs:empty( $policy-list ) ) { 

132             <xsl:message terminate="yes"> "There are no " _ $direction _ " policies for " _ $neighbor; 

133         } 

134           

135         /* 

136          * The policy chain is now output to the console.  This is done all within one line by writing 

137          * the text strings to a single <output> element through the expr statement. 

138          */ 

139         <output> { 

140             if( $direction == "import" ) { 

141                 expr "Import Policies:"; 

142             } 

143             else { 

144                 expr "Export Policies:"; 

145             } 

146             for-each( $policy-list ) { 

147                 expr " " _ .; 

148             } 

149         } 

150           

151         /* A for-each will now loop through each policy individually to allow them to be displayed */ 

152         for-each( $policy-list ) { 

153           

154             /* Output the policy name */ 

155             <output> "\nPolicy: " _ .; 

156               

157             /* 

158              * The script must retrieve the text version of each policy one by one.  By default the 

159              * returned configuration is always in XML format.  To see the configuration in text format 

160              * use the format attribute and set it to "text". 

161              */ 

162             var $get-policy-rpc = <get-configuration format="text" database=$database inherit="inherit"> { 

163                                       <configuration> { 

164                                           <policy-options> { 

165                                               <policy-statement> { 

166                                                   <name> .; 

167                                               } 

168                                           } 

169                                       } 

170                                   } 

171               

172             /* Send assembled API element to JUNOS through jcs:invoke(); */                        

173             var $policy-text = jcs:invoke( $get-policy-rpc ); 

174               

175             /* 

176              * The returned configuration will include the entire hierarchy including the policy-options 

177              * statement and enclosing brackets.  This is extra clutter that is not needed so it is removed 

178              * by using the substring-after and substring functions to remove all the unnecessary characters.  

179              * After which the complete text policy is output to the console. 

180              */ 

181             var $cropped-text =substring-after( $policy-text, "policy-options {" ); 

182             <output> substring( $cropped-text, 1, string-length( $cropped-text )-2 ); 

183         } 

184     } 

185 } 

XML Script Contents

 
01 <?xml version="1.0"?>
02 <script>
03   <title>show-bgp-policy.slax</title>
04   <author>curtisstephencall</author>
05   <synopsis>
06     Display all routing-policies in sequential order for a selected BGP peer
07   </synopsis>
08   <coe>op</coe>
09   <type>display</type>
10  
11   <description><![CDATA[
12 This script provides an easy way to study the complete policy chain of a BGP peer. With multiple BGP policies in an
13 import or export policy chain, it can become troublesome to determine what action will be taken for a particular
14 prefix because the policies will usually not appear in the desired order within the policy-options hierarchy in the
15 configuration.
16  
17 The configuration text for each policy in the policy chain for the selected peer is extracted by the script and then
18 displayed to the console in the correct sequential order.  Through use of this op script, a user can easily read the
19 complete policy chain from start to finish.
20  
21 Three are three command-line arguments:
22 * neighbor - Specificy which BGP peer to view
23 * direction - Choose the import or export direction
24 * database - The policies can be viewed from either the committed database (the default), or the candidate database.
25  
26 Minimum JUNOS Version: 8.2
27 Latest Script Version: 1.0
28 MD5 Checksum: 4b830f1cc024657d621d0668e4af092f
29 SHA-256 Checksum: 963dd0f98f7f15d8728343b77d37e07b202362a7c8f682c464600fefeec86787
30 ]]>
31 </description>
32  
33   <keyword>slax</keyword>
34   <keyword>bgp</keyword>
35   <keyword>peers</keyword>
36   <keyword>policy</keyword>
37   <keyword>routing</keyword>
38   <example>
39     <title>Example</title>
40     <description><![CDATA[
41 [edit protocols bgp group test]
42 user@cli# run op show-bgp-policy neighbor 10.0.0.1 direction import database candidate
43 BGP Neighbor: 10.0.0.1 in group test
44 Import Policies: block-private block-local adjust-local-pref
45 Policy: block-private
46     policy-statement block-private {
47         from {
48             route-filter 192.168.0.0/16 orlonger;
49             route-filter 10.0.0.0/8 orlonger;
50             route-filter 172.16.0.0/12 orlonger;
51         }
52         then reject;
53     }
54 Policy: block-local
55     policy-statement block-local {
56         from {
57             route-filter 1.0.0.0/24 orlonger;
58         }
59         then reject;
60     }
61 Policy: adjust-local-pref
62     policy-statement adjust-local-pref {
63         then {
64             local-preference 90;
65         }
66     }   
67     ]]>
68     </description>
69   </example>
70  
71   <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
72                 src="../../../../../web/leaf.js"
73             type="text/javascript"/>
74 </script>

#ScriptingHow-To
#opscript
#BGP
#Slax
#How-To