{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction to Route Computation and Analysis using Batfish"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Network engineers routinely need to validate routing and forwarding in the network. They often do that by connecting to multiple network devices and executing a series of `show route` commands. This distributed debugging is highly complex even in a moderately-sized network. Batfish makes this task extremely simple by providing an easy-to-query, centralized view of routing tables in the network. \n",
"\n",
"In this notebook, we will look at how you can extract routing information from Batfish.\n",
"\n",
"Check out a video demo of this notebook [here](https://www.youtube.com/watch?v=AutkFa0xUxg)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# Import packages\n",
"%run startup.py\n",
"bf = Session(host=\"localhost\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initializing the Network and Snapshot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`SNAPSHOT_PATH` below can be updated to point to a custom snapshot directory, see the [Batfish instructions](https://github.com/batfish/batfish/wiki/Packaging-snapshots-for-analysis) for how to package data for analysis.
\n",
"More example networks are available in the [networks](https://github.com/batfish/batfish/tree/master/networks) folder of the Batfish repository."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'example_snapshot'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Initialize a network and snapshot\n",
"NETWORK_NAME = \"example_network\"\n",
"SNAPSHOT_NAME = \"example_snapshot\"\n",
"\n",
"SNAPSHOT_PATH = \"networks/example\"\n",
"\n",
"bf.set_network(NETWORK_NAME)\n",
"bf.init_snapshot(SNAPSHOT_PATH, name=SNAPSHOT_NAME, overwrite=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The network snapshot that we initialized above is illustrated below. You can download/view devices' configuration files [here](https://github.com/batfish/pybatfish/tree/master/jupyter_notebooks/networks/example).\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All of the information we will show you in this notebook is dynamically computed by Batfish based on the configuration files for the network devices."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### View Routing Tables for ALL devices and ALL VRFs\n",
"Batfish makes **all** routing tables in the network easily accessible. Let's take a look at how you can retrieve the specific information you want."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Get routing tables for all nodes and VRFs\n",
"routes_all = bf.q.routes().answer().frame()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We are not going to print this table as it has a large number of entries. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### View Routing Tables for default VRF on AS1 border routers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There are 2 ways that we can get the desired subset of data: "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Option 1) Only request that information from Batfish by passing in parameters into the `routes()` question. This is useful to do when you need to reduce the amount of data being returned, but is limited to regex filtering based on VRF, Node, Protocol and Network."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Option 2) Filter the output of the `routes()` question using the Pandas [APIs](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.filter.html)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"?bf.q.routes"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# Get the routing table for the 'default' VRF on border routers of as1\n",
"# using BF parameters\n",
"routes_as1border = bf.q.routes(nodes=\"/as1border/\", vrfs=\"default\").answer().frame()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Node | \n",
" VRF | \n",
" Network | \n",
" Next_Hop | \n",
" Next_Hop_IP | \n",
" Next_Hop_Interface | \n",
" Protocol | \n",
" Metric | \n",
" Admin_Distance | \n",
" Tag | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" as1border1 | \n",
" default | \n",
" 1.0.1.0/24 | \n",
" interface GigabitEthernet0/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet0/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 1 | \n",
" as1border1 | \n",
" default | \n",
" 1.0.1.1/32 | \n",
" interface GigabitEthernet0/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet0/0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 2 | \n",
" as1border1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" interface GigabitEthernet0/0 ip 1.0.1.2 | \n",
" 1.0.1.2 | \n",
" GigabitEthernet0/0 | \n",
" ospf | \n",
" 2 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 3 | \n",
" as1border1 | \n",
" default | \n",
" 1.1.1.1/32 | \n",
" interface Loopback0 | \n",
" AUTO/NONE(-1l) | \n",
" Loopback0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 4 | \n",
" as1border1 | \n",
" default | \n",
" 1.2.2.2/32 | \n",
" interface GigabitEthernet0/0 ip 1.0.1.2 | \n",
" 1.0.1.2 | \n",
" GigabitEthernet0/0 | \n",
" ospf | \n",
" 3 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 5 | \n",
" as1border1 | \n",
" default | \n",
" 1.10.1.1/32 | \n",
" interface GigabitEthernet0/0 ip 1.0.1.2 | \n",
" 1.0.1.2 | \n",
" GigabitEthernet0/0 | \n",
" ospf | \n",
" 2 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 6 | \n",
" as1border1 | \n",
" default | \n",
" 2.128.0.0/16 | \n",
" ip 10.12.11.2 | \n",
" 10.12.11.2 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 7 | \n",
" as1border1 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 8 | \n",
" as1border1 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 9 | \n",
" as1border1 | \n",
" default | \n",
" 10.12.11.0/24 | \n",
" interface GigabitEthernet1/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet1/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 10 | \n",
" as1border1 | \n",
" default | \n",
" 10.12.11.1/32 | \n",
" interface GigabitEthernet1/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet1/0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 11 | \n",
" as1border1 | \n",
" default | \n",
" 10.13.22.0/24 | \n",
" interface GigabitEthernet0/0 ip 1.0.1.2 | \n",
" 1.0.1.2 | \n",
" GigabitEthernet0/0 | \n",
" ospfE2 | \n",
" 20 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 12 | \n",
" as1border1 | \n",
" default | \n",
" 10.14.22.0/24 | \n",
" interface GigabitEthernet0/0 ip 1.0.1.2 | \n",
" 1.0.1.2 | \n",
" GigabitEthernet0/0 | \n",
" ospfE2 | \n",
" 20 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 13 | \n",
" as1border2 | \n",
" default | \n",
" 1.0.1.0/24 | \n",
" interface GigabitEthernet1/0 ip 1.0.2.2 | \n",
" 1.0.2.2 | \n",
" GigabitEthernet1/0 | \n",
" ospf | \n",
" 2 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 14 | \n",
" as1border2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" interface GigabitEthernet1/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet1/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 15 | \n",
" as1border2 | \n",
" default | \n",
" 1.0.2.1/32 | \n",
" interface GigabitEthernet1/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet1/0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 16 | \n",
" as1border2 | \n",
" default | \n",
" 1.1.1.1/32 | \n",
" interface GigabitEthernet1/0 ip 1.0.2.2 | \n",
" 1.0.2.2 | \n",
" GigabitEthernet1/0 | \n",
" ospf | \n",
" 3 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 17 | \n",
" as1border2 | \n",
" default | \n",
" 1.2.2.2/32 | \n",
" interface Loopback0 | \n",
" AUTO/NONE(-1l) | \n",
" Loopback0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 18 | \n",
" as1border2 | \n",
" default | \n",
" 1.10.1.1/32 | \n",
" interface GigabitEthernet1/0 ip 1.0.2.2 | \n",
" 1.0.2.2 | \n",
" GigabitEthernet1/0 | \n",
" ospf | \n",
" 2 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 19 | \n",
" as1border2 | \n",
" default | \n",
" 2.128.0.0/16 | \n",
" ip 10.12.11.2 | \n",
" 10.12.11.2 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 20 | \n",
" as1border2 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 21 | \n",
" as1border2 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 22 | \n",
" as1border2 | \n",
" default | \n",
" 10.12.11.0/24 | \n",
" interface GigabitEthernet1/0 ip 1.0.2.2 | \n",
" 1.0.2.2 | \n",
" GigabitEthernet1/0 | \n",
" ospfE2 | \n",
" 20 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 23 | \n",
" as1border2 | \n",
" default | \n",
" 10.13.22.0/24 | \n",
" interface GigabitEthernet0/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet0/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 24 | \n",
" as1border2 | \n",
" default | \n",
" 10.13.22.1/32 | \n",
" interface GigabitEthernet0/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet0/0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 25 | \n",
" as1border2 | \n",
" default | \n",
" 10.14.22.0/24 | \n",
" interface GigabitEthernet2/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet2/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 26 | \n",
" as1border2 | \n",
" default | \n",
" 10.14.22.1/32 | \n",
" interface GigabitEthernet2/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet2/0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Node VRF Network \\\n",
"0 as1border1 default 1.0.1.0/24 \n",
"1 as1border1 default 1.0.1.1/32 \n",
"2 as1border1 default 1.0.2.0/24 \n",
"3 as1border1 default 1.1.1.1/32 \n",
"4 as1border1 default 1.2.2.2/32 \n",
"5 as1border1 default 1.10.1.1/32 \n",
"6 as1border1 default 2.128.0.0/16 \n",
"7 as1border1 default 3.0.1.0/24 \n",
"8 as1border1 default 3.0.2.0/24 \n",
"9 as1border1 default 10.12.11.0/24 \n",
"10 as1border1 default 10.12.11.1/32 \n",
"11 as1border1 default 10.13.22.0/24 \n",
"12 as1border1 default 10.14.22.0/24 \n",
"13 as1border2 default 1.0.1.0/24 \n",
"14 as1border2 default 1.0.2.0/24 \n",
"15 as1border2 default 1.0.2.1/32 \n",
"16 as1border2 default 1.1.1.1/32 \n",
"17 as1border2 default 1.2.2.2/32 \n",
"18 as1border2 default 1.10.1.1/32 \n",
"19 as1border2 default 2.128.0.0/16 \n",
"20 as1border2 default 3.0.1.0/24 \n",
"21 as1border2 default 3.0.2.0/24 \n",
"22 as1border2 default 10.12.11.0/24 \n",
"23 as1border2 default 10.13.22.0/24 \n",
"24 as1border2 default 10.13.22.1/32 \n",
"25 as1border2 default 10.14.22.0/24 \n",
"26 as1border2 default 10.14.22.1/32 \n",
"\n",
" Next_Hop Next_Hop_IP \\\n",
"0 interface GigabitEthernet0/0 AUTO/NONE(-1l) \n",
"1 interface GigabitEthernet0/0 AUTO/NONE(-1l) \n",
"2 interface GigabitEthernet0/0 ip 1.0.1.2 1.0.1.2 \n",
"3 interface Loopback0 AUTO/NONE(-1l) \n",
"4 interface GigabitEthernet0/0 ip 1.0.1.2 1.0.1.2 \n",
"5 interface GigabitEthernet0/0 ip 1.0.1.2 1.0.1.2 \n",
"6 ip 10.12.11.2 10.12.11.2 \n",
"7 ip 10.13.22.3 10.13.22.3 \n",
"8 ip 10.13.22.3 10.13.22.3 \n",
"9 interface GigabitEthernet1/0 AUTO/NONE(-1l) \n",
"10 interface GigabitEthernet1/0 AUTO/NONE(-1l) \n",
"11 interface GigabitEthernet0/0 ip 1.0.1.2 1.0.1.2 \n",
"12 interface GigabitEthernet0/0 ip 1.0.1.2 1.0.1.2 \n",
"13 interface GigabitEthernet1/0 ip 1.0.2.2 1.0.2.2 \n",
"14 interface GigabitEthernet1/0 AUTO/NONE(-1l) \n",
"15 interface GigabitEthernet1/0 AUTO/NONE(-1l) \n",
"16 interface GigabitEthernet1/0 ip 1.0.2.2 1.0.2.2 \n",
"17 interface Loopback0 AUTO/NONE(-1l) \n",
"18 interface GigabitEthernet1/0 ip 1.0.2.2 1.0.2.2 \n",
"19 ip 10.12.11.2 10.12.11.2 \n",
"20 ip 10.13.22.3 10.13.22.3 \n",
"21 ip 10.13.22.3 10.13.22.3 \n",
"22 interface GigabitEthernet1/0 ip 1.0.2.2 1.0.2.2 \n",
"23 interface GigabitEthernet0/0 AUTO/NONE(-1l) \n",
"24 interface GigabitEthernet0/0 AUTO/NONE(-1l) \n",
"25 interface GigabitEthernet2/0 AUTO/NONE(-1l) \n",
"26 interface GigabitEthernet2/0 AUTO/NONE(-1l) \n",
"\n",
" Next_Hop_Interface Protocol Metric Admin_Distance Tag \n",
"0 GigabitEthernet0/0 connected 0 0 None \n",
"1 GigabitEthernet0/0 local 0 0 None \n",
"2 GigabitEthernet0/0 ospf 2 110 None \n",
"3 Loopback0 connected 0 0 None \n",
"4 GigabitEthernet0/0 ospf 3 110 None \n",
"5 GigabitEthernet0/0 ospf 2 110 None \n",
"6 dynamic bgp 50 20 None \n",
"7 dynamic ibgp 50 200 None \n",
"8 dynamic ibgp 50 200 None \n",
"9 GigabitEthernet1/0 connected 0 0 None \n",
"10 GigabitEthernet1/0 local 0 0 None \n",
"11 GigabitEthernet0/0 ospfE2 20 110 None \n",
"12 GigabitEthernet0/0 ospfE2 20 110 None \n",
"13 GigabitEthernet1/0 ospf 2 110 None \n",
"14 GigabitEthernet1/0 connected 0 0 None \n",
"15 GigabitEthernet1/0 local 0 0 None \n",
"16 GigabitEthernet1/0 ospf 3 110 None \n",
"17 Loopback0 connected 0 0 None \n",
"18 GigabitEthernet1/0 ospf 2 110 None \n",
"19 dynamic ibgp 50 200 None \n",
"20 dynamic bgp 50 20 None \n",
"21 dynamic bgp 50 20 None \n",
"22 GigabitEthernet1/0 ospfE2 20 110 None \n",
"23 GigabitEthernet0/0 connected 0 0 None \n",
"24 GigabitEthernet0/0 local 0 0 None \n",
"25 GigabitEthernet2/0 connected 0 0 None \n",
"26 GigabitEthernet2/0 local 0 0 None "
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Get the routing table for the 'default' VRF on border routers of as1\n",
"# using Pandas filtering\n",
"routes_as1border = routes_all[(routes_all['Node'].str.contains('as1border')) & (routes_all['VRF'] == 'default')]\n",
"routes_as1border"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### View BGP learnt routes for default VRF on AS1 border routers"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Getting BGP routes in the routing table for the 'default' VRF on border routers of as1\n",
"# using BF parameters\n",
"routes_as1border_bgp = bf.q.routes(nodes=\"/as1border/\", vrfs=\"default\", protocols=\"bgp\").answer().frame()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Node | \n",
" VRF | \n",
" Network | \n",
" Next_Hop | \n",
" Next_Hop_IP | \n",
" Next_Hop_Interface | \n",
" Protocol | \n",
" Metric | \n",
" Admin_Distance | \n",
" Tag | \n",
"
\n",
" \n",
" \n",
" \n",
" | 6 | \n",
" as1border1 | \n",
" default | \n",
" 2.128.0.0/16 | \n",
" ip 10.12.11.2 | \n",
" 10.12.11.2 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 20 | \n",
" as1border2 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 21 | \n",
" as1border2 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Node VRF Network Next_Hop Next_Hop_IP \\\n",
"6 as1border1 default 2.128.0.0/16 ip 10.12.11.2 10.12.11.2 \n",
"20 as1border2 default 3.0.1.0/24 ip 10.13.22.3 10.13.22.3 \n",
"21 as1border2 default 3.0.2.0/24 ip 10.13.22.3 10.13.22.3 \n",
"\n",
" Next_Hop_Interface Protocol Metric Admin_Distance Tag \n",
"6 dynamic bgp 50 20 None \n",
"20 dynamic bgp 50 20 None \n",
"21 dynamic bgp 50 20 None "
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Geting BGP routes in the routing table for the 'default' VRF on border routers of as1\n",
"# using Pandas filtering\n",
"routes_as1border_bgp = routes_all[(routes_all['Node'].str.contains('as1border')) & (routes_all['VRF'] == 'default') & (routes_all['Protocol'] == 'bgp')]\n",
"routes_as1border_bgp"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### View BGP learnt routes for ALL VRFs on ALL routers with Metric >=50\n",
"We cannot pass in `metric` as a parameter to Batfish, so this task is best handled with the Pandas API."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Node | \n",
" VRF | \n",
" Network | \n",
" Next_Hop | \n",
" Next_Hop_IP | \n",
" Next_Hop_Interface | \n",
" Protocol | \n",
" Metric | \n",
" Admin_Distance | \n",
" Tag | \n",
"
\n",
" \n",
" \n",
" \n",
" | 6 | \n",
" as1border1 | \n",
" default | \n",
" 2.128.0.0/16 | \n",
" ip 10.12.11.2 | \n",
" 10.12.11.2 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 20 | \n",
" as1border2 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 21 | \n",
" as1border2 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 10.13.22.3 | \n",
" 10.13.22.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 40 | \n",
" as2border1 | \n",
" default | \n",
" 1.0.1.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 41 | \n",
" as2border1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 106 | \n",
" as2border2 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 10.23.21.3 | \n",
" 10.23.21.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 107 | \n",
" as2border2 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 10.23.21.3 | \n",
" 10.23.21.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 182 | \n",
" as2dept1 | \n",
" default | \n",
" 1.0.1.0/24 | \n",
" ip 2.34.101.3 | \n",
" 2.34.101.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 183 | \n",
" as2dept1 | \n",
" default | \n",
" 1.0.1.0/24 | \n",
" ip 2.34.201.3 | \n",
" 2.34.201.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 184 | \n",
" as2dept1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 2.34.101.3 | \n",
" 2.34.101.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 185 | \n",
" as2dept1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 2.34.201.3 | \n",
" 2.34.201.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 195 | \n",
" as2dept1 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 2.34.101.3 | \n",
" 2.34.101.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 196 | \n",
" as2dept1 | \n",
" default | \n",
" 3.0.1.0/24 | \n",
" ip 2.34.201.3 | \n",
" 2.34.201.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 197 | \n",
" as2dept1 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 2.34.101.3 | \n",
" 2.34.101.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 198 | \n",
" as2dept1 | \n",
" default | \n",
" 3.0.2.0/24 | \n",
" ip 2.34.201.3 | \n",
" 2.34.201.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 226 | \n",
" as2dist1 | \n",
" default | \n",
" 2.128.0.0/24 | \n",
" ip 2.34.101.4 | \n",
" 2.34.101.4 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 227 | \n",
" as2dist1 | \n",
" default | \n",
" 2.128.1.0/24 | \n",
" ip 2.34.101.4 | \n",
" 2.34.101.4 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 261 | \n",
" as2dist2 | \n",
" default | \n",
" 2.128.0.0/24 | \n",
" ip 2.34.201.4 | \n",
" 2.34.201.4 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 262 | \n",
" as2dist2 | \n",
" default | \n",
" 2.128.1.0/24 | \n",
" ip 2.34.201.4 | \n",
" 2.34.201.4 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 271 | \n",
" as3border1 | \n",
" default | \n",
" 2.128.0.0/16 | \n",
" ip 10.23.21.2 | \n",
" 10.23.21.2 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 281 | \n",
" as3border2 | \n",
" default | \n",
" 1.0.1.0/24 | \n",
" ip 10.13.22.1 | \n",
" 10.13.22.1 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 282 | \n",
" as3border2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.13.22.1 | \n",
" 10.13.22.1 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Node VRF Network Next_Hop Next_Hop_IP \\\n",
"6 as1border1 default 2.128.0.0/16 ip 10.12.11.2 10.12.11.2 \n",
"20 as1border2 default 3.0.1.0/24 ip 10.13.22.3 10.13.22.3 \n",
"21 as1border2 default 3.0.2.0/24 ip 10.13.22.3 10.13.22.3 \n",
"40 as2border1 default 1.0.1.0/24 ip 10.12.11.1 10.12.11.1 \n",
"41 as2border1 default 1.0.2.0/24 ip 10.12.11.1 10.12.11.1 \n",
"106 as2border2 default 3.0.1.0/24 ip 10.23.21.3 10.23.21.3 \n",
"107 as2border2 default 3.0.2.0/24 ip 10.23.21.3 10.23.21.3 \n",
"182 as2dept1 default 1.0.1.0/24 ip 2.34.101.3 2.34.101.3 \n",
"183 as2dept1 default 1.0.1.0/24 ip 2.34.201.3 2.34.201.3 \n",
"184 as2dept1 default 1.0.2.0/24 ip 2.34.101.3 2.34.101.3 \n",
"185 as2dept1 default 1.0.2.0/24 ip 2.34.201.3 2.34.201.3 \n",
"195 as2dept1 default 3.0.1.0/24 ip 2.34.101.3 2.34.101.3 \n",
"196 as2dept1 default 3.0.1.0/24 ip 2.34.201.3 2.34.201.3 \n",
"197 as2dept1 default 3.0.2.0/24 ip 2.34.101.3 2.34.101.3 \n",
"198 as2dept1 default 3.0.2.0/24 ip 2.34.201.3 2.34.201.3 \n",
"226 as2dist1 default 2.128.0.0/24 ip 2.34.101.4 2.34.101.4 \n",
"227 as2dist1 default 2.128.1.0/24 ip 2.34.101.4 2.34.101.4 \n",
"261 as2dist2 default 2.128.0.0/24 ip 2.34.201.4 2.34.201.4 \n",
"262 as2dist2 default 2.128.1.0/24 ip 2.34.201.4 2.34.201.4 \n",
"271 as3border1 default 2.128.0.0/16 ip 10.23.21.2 10.23.21.2 \n",
"281 as3border2 default 1.0.1.0/24 ip 10.13.22.1 10.13.22.1 \n",
"282 as3border2 default 1.0.2.0/24 ip 10.13.22.1 10.13.22.1 \n",
"\n",
" Next_Hop_Interface Protocol Metric Admin_Distance Tag \n",
"6 dynamic bgp 50 20 None \n",
"20 dynamic bgp 50 20 None \n",
"21 dynamic bgp 50 20 None \n",
"40 dynamic bgp 50 20 None \n",
"41 dynamic bgp 50 20 None \n",
"106 dynamic bgp 50 20 None \n",
"107 dynamic bgp 50 20 None \n",
"182 dynamic bgp 50 20 None \n",
"183 dynamic bgp 50 20 None \n",
"184 dynamic bgp 50 20 None \n",
"185 dynamic bgp 50 20 None \n",
"195 dynamic bgp 50 20 None \n",
"196 dynamic bgp 50 20 None \n",
"197 dynamic bgp 50 20 None \n",
"198 dynamic bgp 50 20 None \n",
"226 dynamic bgp 50 20 None \n",
"227 dynamic bgp 50 20 None \n",
"261 dynamic bgp 50 20 None \n",
"262 dynamic bgp 50 20 None \n",
"271 dynamic bgp 50 20 None \n",
"281 dynamic bgp 50 20 None \n",
"282 dynamic bgp 50 20 None "
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"routes_filtered = routes_all[(routes_all['Protocol'] == 'bgp') & (routes_all['Metric'] >= 50)]\n",
"routes_filtered"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### View the routing entries for network 1.0.2.0/24 on ALL routers in ALL VRFs"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# grab the route table entry for network 1.0.2.0/24 from all routers in all VRFs\n",
"# using BF parameters\n",
"routes_filtered = bf.q.routes(network=\"1.0.2.0/24\").answer().frame()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Node | \n",
" VRF | \n",
" Network | \n",
" Next_Hop | \n",
" Next_Hop_IP | \n",
" Next_Hop_Interface | \n",
" Protocol | \n",
" Metric | \n",
" Admin_Distance | \n",
" Tag | \n",
"
\n",
" \n",
" \n",
" \n",
" | 2 | \n",
" as1border1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" interface GigabitEthernet0/0 ip 1.0.1.2 | \n",
" 1.0.1.2 | \n",
" GigabitEthernet0/0 | \n",
" ospf | \n",
" 2 | \n",
" 110 | \n",
" None | \n",
"
\n",
" \n",
" | 14 | \n",
" as1border2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" interface GigabitEthernet1/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet1/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 29 | \n",
" as1core1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" interface GigabitEthernet0/0 | \n",
" AUTO/NONE(-1l) | \n",
" GigabitEthernet0/0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 41 | \n",
" as2border1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 77 | \n",
" as2border2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 113 | \n",
" as2core1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 148 | \n",
" as2core2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 184 | \n",
" as2dept1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 2.34.101.3 | \n",
" 2.34.101.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 185 | \n",
" as2dept1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 2.34.201.3 | \n",
" 2.34.201.3 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 200 | \n",
" as2dist1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 235 | \n",
" as2dist2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.12.11.1 | \n",
" 10.12.11.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 270 | \n",
" as3border1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.13.22.1 | \n",
" 10.13.22.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
" | 282 | \n",
" as3border2 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.13.22.1 | \n",
" 10.13.22.1 | \n",
" dynamic | \n",
" bgp | \n",
" 50 | \n",
" 20 | \n",
" None | \n",
"
\n",
" \n",
" | 294 | \n",
" as3core1 | \n",
" default | \n",
" 1.0.2.0/24 | \n",
" ip 10.13.22.1 | \n",
" 10.13.22.1 | \n",
" dynamic | \n",
" ibgp | \n",
" 50 | \n",
" 200 | \n",
" None | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Node VRF Network Next_Hop \\\n",
"2 as1border1 default 1.0.2.0/24 interface GigabitEthernet0/0 ip 1.0.1.2 \n",
"14 as1border2 default 1.0.2.0/24 interface GigabitEthernet1/0 \n",
"29 as1core1 default 1.0.2.0/24 interface GigabitEthernet0/0 \n",
"41 as2border1 default 1.0.2.0/24 ip 10.12.11.1 \n",
"77 as2border2 default 1.0.2.0/24 ip 10.12.11.1 \n",
"113 as2core1 default 1.0.2.0/24 ip 10.12.11.1 \n",
"148 as2core2 default 1.0.2.0/24 ip 10.12.11.1 \n",
"184 as2dept1 default 1.0.2.0/24 ip 2.34.101.3 \n",
"185 as2dept1 default 1.0.2.0/24 ip 2.34.201.3 \n",
"200 as2dist1 default 1.0.2.0/24 ip 10.12.11.1 \n",
"235 as2dist2 default 1.0.2.0/24 ip 10.12.11.1 \n",
"270 as3border1 default 1.0.2.0/24 ip 10.13.22.1 \n",
"282 as3border2 default 1.0.2.0/24 ip 10.13.22.1 \n",
"294 as3core1 default 1.0.2.0/24 ip 10.13.22.1 \n",
"\n",
" Next_Hop_IP Next_Hop_Interface Protocol Metric Admin_Distance Tag \n",
"2 1.0.1.2 GigabitEthernet0/0 ospf 2 110 None \n",
"14 AUTO/NONE(-1l) GigabitEthernet1/0 connected 0 0 None \n",
"29 AUTO/NONE(-1l) GigabitEthernet0/0 connected 0 0 None \n",
"41 10.12.11.1 dynamic bgp 50 20 None \n",
"77 10.12.11.1 dynamic ibgp 50 200 None \n",
"113 10.12.11.1 dynamic ibgp 50 200 None \n",
"148 10.12.11.1 dynamic ibgp 50 200 None \n",
"184 2.34.101.3 dynamic bgp 50 20 None \n",
"185 2.34.201.3 dynamic bgp 50 20 None \n",
"200 10.12.11.1 dynamic ibgp 50 200 None \n",
"235 10.12.11.1 dynamic ibgp 50 200 None \n",
"270 10.13.22.1 dynamic ibgp 50 200 None \n",
"282 10.13.22.1 dynamic bgp 50 20 None \n",
"294 10.13.22.1 dynamic ibgp 50 200 None "
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# grab the route table entry for network 1.0.2.0/24 from all routers in all VRFs\n",
"# using Pandas filtering\n",
"routes_filtered = routes_all[routes_all['Network'] == \"1.0.2.0/24\"]\n",
"routes_filtered"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using Panda's filtering it is easy to retrieve the list of nodes which have the network in the routing table for at least 1 VRF. This type of processing should always be done using the Pandas APIs."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['as1border1', 'as1border2', 'as1core1', 'as2border1', 'as2border2', 'as2core1', 'as2core2', 'as2dept1', 'as2dist1', 'as2dist2', 'as3border1', 'as3border2', 'as3core1']\n"
]
}
],
"source": [
"# Get the list of nodes that have the network 1.0.2.0/24 in at least 1 VRF\n",
"# the .unique function removes duplicate entries that would have been returned if the network was in multiple VRFs on a node or there were\n",
"# multiple route entries for the network (ECMP)\n",
"print(sorted(routes_filtered[\"Node\"].unique()))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we will retrieve the list of nodes that do NOT have this prefix in their routing table. This is easy to do with the Pandas [groupby](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html) and [filter](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.DataFrameGroupBy.filter.html) functions."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['host1', 'host2']\n"
]
}
],
"source": [
"# Group all routes by Node and filter for those that don't have '1.0.2.0/24'\n",
"routes_filtered = routes_all.groupby('Node').filter(lambda x: all(x['Network'] != '1.0.2.0/24'))\n",
"\n",
"# Get the unique node names and sort the list\n",
"print(sorted(routes_filtered[\"Node\"].unique()))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The only devices that do not have a route to **1.0.2.0/24** are the 2 hosts in the snapshot. This is expected, as they should just have a default route. Let's verify that."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Node | \n",
" VRF | \n",
" Network | \n",
" Next_Hop | \n",
" Next_Hop_IP | \n",
" Next_Hop_Interface | \n",
" Protocol | \n",
" Metric | \n",
" Admin_Distance | \n",
" Tag | \n",
"
\n",
" \n",
" \n",
" \n",
" | 309 | \n",
" host1 | \n",
" default | \n",
" 0.0.0.0/0 | \n",
" interface eth0 ip 2.128.0.1 | \n",
" 2.128.0.1 | \n",
" eth0 | \n",
" static | \n",
" 0 | \n",
" 1 | \n",
" None | \n",
"
\n",
" \n",
" | 310 | \n",
" host1 | \n",
" default | \n",
" 2.128.0.0/24 | \n",
" interface eth0 | \n",
" AUTO/NONE(-1l) | \n",
" eth0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 311 | \n",
" host1 | \n",
" default | \n",
" 2.128.0.101/32 | \n",
" interface eth0 | \n",
" AUTO/NONE(-1l) | \n",
" eth0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 312 | \n",
" host2 | \n",
" default | \n",
" 0.0.0.0/0 | \n",
" interface eth0 ip 2.128.1.1 | \n",
" 2.128.1.1 | \n",
" eth0 | \n",
" static | \n",
" 0 | \n",
" 1 | \n",
" None | \n",
"
\n",
" \n",
" | 313 | \n",
" host2 | \n",
" default | \n",
" 2.128.1.0/24 | \n",
" interface eth0 | \n",
" AUTO/NONE(-1l) | \n",
" eth0 | \n",
" connected | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
" | 314 | \n",
" host2 | \n",
" default | \n",
" 2.128.1.101/32 | \n",
" interface eth0 | \n",
" AUTO/NONE(-1l) | \n",
" eth0 | \n",
" local | \n",
" 0 | \n",
" 0 | \n",
" None | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Node VRF Network Next_Hop \\\n",
"309 host1 default 0.0.0.0/0 interface eth0 ip 2.128.0.1 \n",
"310 host1 default 2.128.0.0/24 interface eth0 \n",
"311 host1 default 2.128.0.101/32 interface eth0 \n",
"312 host2 default 0.0.0.0/0 interface eth0 ip 2.128.1.1 \n",
"313 host2 default 2.128.1.0/24 interface eth0 \n",
"314 host2 default 2.128.1.101/32 interface eth0 \n",
"\n",
" Next_Hop_IP Next_Hop_Interface Protocol Metric Admin_Distance Tag \n",
"309 2.128.0.1 eth0 static 0 1 None \n",
"310 AUTO/NONE(-1l) eth0 connected 0 0 None \n",
"311 AUTO/NONE(-1l) eth0 local 0 0 None \n",
"312 2.128.1.1 eth0 static 0 1 None \n",
"313 AUTO/NONE(-1l) eth0 connected 0 0 None \n",
"314 AUTO/NONE(-1l) eth0 local 0 0 None "
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"routes_all[routes_all['Node'].str.contains('host')]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With Batfish and Pandas you can easily retrieve the exact information you are looking for from the routing tables on ANY or ALL network devices for ANY or ALL VRFs."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This concludes the notebook. To recap, in this notebook we covered the foundational tasks for route analysis:\n",
"\n",
"1. How to get routes at all nodes in the network or only at a subset of them\n",
"2. How to retrieve routing entries that match a specific protocol or metric\n",
"3. How to find which nodes have an entry for a prefix or which ones do not\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We hope you found this notebook useful and informative. Future notebooks will dive into more advanced topics like path analysis, debugging ACLs and firewall rules, validating routing policy, etc.. so stay tuned! "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Want to know more? "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reach out to us through [Slack](https://join.slack.com/t/batfish-org/shared_invite/enQtMzA0Nzg2OTAzNzQ1LTcyYzY3M2Q0NWUyYTRhYjdlM2IzYzRhZGU1NWFlNGU2MzlhNDY3OTJmMDIyMjQzYmRlNjhkMTRjNWIwNTUwNTQ`) or [GitHub](https://github.com/batfish/batfish) to learn more, or send feedback."
]
}
],
"metadata": {
"hide_input": false,
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.11"
}
},
"nbformat": 4,
"nbformat_minor": 2
}