How to Specify the Routing Instance in Python 3 Applications on Devices Running Junos OS Evolved
Understanding the libpyvrf Module
A routing instance is a collection of routing tables, interfaces,
and routing protocol parameters. Each routing instance has a unique
name and a corresponding IP unicast table, which can be used to separate
traffic for that instance from other traffic. For example, on devices
running Junos OS Evolved, you can enable a dedicated management virtual
routing and forwarding (VRF) instance, mgmt_junos
, which
uses a separate administrative routing table dedicated to management
tasks.
Routing instances enable you to isolate traffic traversing the
network without using multiple devices to segment your network. When
you use routing instances to isolate traffic, network utilities like ping
and ssh
must reference
the correct routing instance in order to send traffic to a destination
that is reachable through that instance.
The Junos OS Evolved image runs natively on Linux, providing direct access to all the Linux
utilities and operations, including the Python libraries that are part of the base
image. The Python 3 library on devices running Junos OS Evolved also includes the
Juniper Networks libpyvrf
module, which enables Python 3
applications that are executed in the shell to specify the routing instance to use
for specific processes and network utilities.
Table 1 outlines the libpyvrf
functions that you can use in Python 3 applications
that are executed in the Linux shell. You can use the functions to
instruct a process to use a specific routing instance. If the same
process requires multiple routing instances, you can also set the
routing instance context for a specific socket, which does not affect
the context for the process itself. Packets through the socket then
use the routing table associated with that instance. When you set
the routing instance for a process or socket, the libpyvrf
module sets the context to the Linux VRF that corresponds to the
Junos OS routing instance.
|
Description |
---|---|
|
Return the Linux VRF corresponding to a Junos OS routing instance. |
|
Return the index of the routing table associated with the specified routing instance. |
|
Return the routing instance associated with the specified task. Note:
This function is deprecated starting in Junos OS Evolved Release 22.1R1. |
|
Return the routing instance associated with the current process. |
|
Set the routing instance for the specified socket. |
|
Set the routing instance for the specified process. Note:
This function is deprecated starting in Junos OS Evolved Release 22.1R1. |
|
Set the routing instance for the current process. |
Functions in the libpyvrf
module
can raise the following exceptions depending on the function and error:
libpyvrf.error
—Generated whenlibvrf
returns an error.libpyvrf.evo_not_ready
—Generated when the Junos OS Evolved network stack is not ready, for example when the device is booting.libpyvrf.invalid_table
—Generated when the specified routing instance or table ID is invalid.
The following sample Python script attempts to ping a host that
is only reachable through the mgmt_junos
routing instance. The script initially pings the host before calling
the set_vrf()
function. The script then
calls the set_vrf()
function to associate
the mgmt_junos
routing instance with the current process
and pings the host again.
[vrf:none] user@host:~# cat libpyvrf-ping.py import libpyvrf as vrf import subprocess command = [ 'ping', '-c', '3', 'host1.example.com' ] try: # Ping the host before setting the routing instance subprocess.call(command) == 0 # Set the routing instance vrf.set_vrf("mgmt_junos") print ("\nUsing routing instance:", vrf.get_vrf()) # Ping the host after setting the routing instance subprocess.call(command) == 0 except vrf.invalid_table as e: print ("Invalid Table") except vrf.evo_not_ready as e : print ("Junos OS Evolved network stack is not ready") except vrf.error as e : print ("Generic libvrf error")
When you execute the script, the first ping command fails, because
the process uses the default routing instance in this case, and the
host is only reachable through the mgmt_junos
routing instance.
The second ping command, which uses the mgmt_junos
routing
instance, succeeds.
[vrf:none] user@host:~# python3 libpyvrf-ping.py ping: unknown host host1.example.net Using routing instance: mgmt_junos PING host1.example.com (198.51.100.10) 56(84) bytes of data. 64 bytes from host1.example.com (198.51.100.10): icmp_seq=1 ttl=60 time=1.02 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=2 ttl=60 time=0.672 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=3 ttl=60 time=0.741 ms --- host1.example.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.876/0.946/1.001/0.063 ms
You can reset the routing instance back to the default routing instance association in a Python application by specifying an empty string for the routing instance name. For example:
vrf.set_vrf("")
If an application does not specify a routing instance, the default
routing instance association depends on the environment of the process.
If the environment preloads the libsi.so library, then by default, the application uses the default routing
instance and table, default.inet
. Otherwise, there is no
default routing instance associated with the process or sockets.
To determine if the environment preloads the libsi.so library, verify that value of the LD_PRELOAD
environment variable includes the path to
the library.
[vrf:none] user@host:~# env | grep LD_PRELOAD LD_PRELOAD=libsi.so
If the LD_PRELOAD
variable
does not include the libsi.so library
path, you can use the commands appropriate for your shell to add it,
for example:
[vrf:none] user@host:~# export LD_PRELOAD="/path/to/libsi.so" [vrf:none] user@host:~# env | grep LD_PRELOAD LD_PRELOAD=libsi.so
get_host_vrf_name() Function
Syntax
host_vrf_name get_host_vrf_name(vrf_name)
Description
Return the Linux VRF corresponding to a Junos OS routing instance.
Parameters
vrf_name |
Name of a Junos OS routing instance. |
Return Value
host_vrf_name | Name of the Linux VRF corresponding to the Junos OS routing instance. |
Usage Examples
The following example prints the Linux VRF corresponding to several Junos OS routing instances:
[vrf:none] user@host:~# cat libpyvrf-get-host-vrf-name.py import libpyvrf as vrf try: print ("mgmt_junos VRF:", vrf.get_host_vrf_name("mgmt_junos")) print ("default VRF:", vrf.get_host_vrf_name("default")) print ("L3VPN-1 VRF:", vrf.get_host_vrf_name("L3VPN-1")) except vrf.invalid_table as e: print ("Invalid Table")
[vrf:none] user@host:~# python3 libpyvrf-get-host-vrf-name.py mgmt_junos VRF: mgmt_junos default VRF: vrf0 L3VPN-1 VRF: vrf52
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.
get_table_id() Function
Syntax
table_id get_table_id(vrf_name)
Description
Return the index of the routing table associated with the specified routing instance. If the routing instance is not defined, the function returns -1.
Parameters
vrf_name |
Name of a Junos OS routing instance. |
Return Value
table_id | Index of the routing table for the given routing instance. |
Usage Examples
The following example retrieves and prints the
table index for the mgmt_junos
routing instance and an
undefined routing instance foo
.
user@host> show route forwarding-table extensive table mgmt_junos Routing table: mgmt_junos.inet [Index 36738] Internet: ... Routing table: mgmt_junos.inet6 [Index 36738] Internet6: ...
[vrf:none] user@host:~# cat libpyvrf-get-table-id.py import libpyvrf as vrf try: print (vrf.get_table_id("mgmt_junos")) print (vrf.get_table_id("foo")) except vrf.evo_not_ready as e: print ("Junos OS Evolved network stack is not ready") except vrf.error as e: print ("Generic libvrf error")
The script returns the table index for the mgmt_junos
instance and returns -1 for the undefined instance.
[vrf:none] user@host:~# python3 libpyvrf-get-table-id.py 36738 -1
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.
get_task_vrf() Function
Syntax
vrf_name get_task_vrf(tid)
Description
Return the Junos OS routing instance associated with the specified process ID.
Parameters
tid |
Process ID for which to retrieve the associated routing instance. |
Return Value
vrf_name | Name of the routing instance associated with the process ID. |
Usage Examples
The following example retrieves the process ID
for the current process and associates the mgmt_junos
routing
instance with that process. When the script calls the get_task_vrf()
function to request the routing instance
for that process ID, it returns the mgmt_junos
routing
instance.
[vrf:none] user@host:~# cat libpyvrf-set-task-vrf.py import libpyvrf as vrf import os, subprocess command = [ 'ping', '-c', '3', 'host1.example.com' ] try: pid = os.getpid() vrf.set_task_vrf(pid, "mgmt_junos") print ("Using routing instance:", vrf.get_task_vrf(pid)) subprocess.call(command) == 0 except vrf.invalid_table as e: print ("Invalid Table") except vrf.evo_not_ready as e: print ("Junos OS Evolved network stack is not ready") except vrf.error as e: print ("Generic libvrf error")
[vrf:none] user@host:~# python3 libpyvrf-set-task-vrf.py Using routing instance: mgmt_junos PING host1.example.com (198.51.100.10) 56(84) bytes of data. 64 bytes from host1.example.com (198.51.100.10): icmp_seq=1 ttl=60 time=1.02 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=2 ttl=60 time=0.672 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=3 ttl=60 time=0.741 ms --- host1.example.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.876/0.946/1.001/0.063 ms
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.
Function deprecated in Junos OS Evolved Release 22.1R1.
get_vrf() Function
Syntax
vrf_name get_vrf()
Description
Return the Junos OS routing instance associated with the current process.
Return Value
vrf_name |
Name of the routing instance associated with the current process. |
Usage Examples
The following example associates the mgmt_junos
routing instance with the current process. When the script calls
the get_vrf()
function to request the routing
instance for the current process, it returns the mgmt_junos
routing instance.
[vrf:none] user@host:~# cat libpyvrf-set-vrf.py import libpyvrf as vrf import subprocess command = [ 'ping', '-c', '3', 'host1.example.com' ] try: vrf.set_vrf("mgmt_junos") print ("Using routing instance:", vrf.get_vrf()) subprocess.call(command) == 0 except vrf.invalid_table as e: print ("Invalid Table") except vrf.evo_not_ready as e: print ("Junos OS Evolved network stack is not ready") except vrf.error as e: print ("Generic libvrf error")
[vrf:none] user@host:~# python3 libpyvrf-set-vrf.py Using routing instance: mgmt_junos PING host1.example.com (198.51.100.10) 56(84) bytes of data. 64 bytes from host1.example.com (198.51.100.10): icmp_seq=1 ttl=60 time=1.02 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=2 ttl=60 time=0.672 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=3 ttl=60 time=0.741 ms --- host1.example.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.876/0.946/1.001/0.063 ms
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.
set_socket_vrf() Function
Syntax
set_socket_vrf(socket_fd, vrf_name)
Description
Set the routing instance used by the specified socket. Setting the routing instance for a socket is useful when multiple sockets within the same application need to use different routing instances. You can set the routing instance context for each socket individually without affecting the routing instance context for the process or application.
Parameters
socket_fd |
Socket’s file descriptor. |
vrf_name |
Name of a Junos OS routing instance.
|
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.
set_task_vrf() Function
Syntax
set_task_vrf(tid, vrf_name)
Description
Set the routing instance that the process with the specified process ID will use to perform operations.
Whereas set_vrf()
sets the routing
instance for the current process, set_task_vrf()
sets the routing instance for the process with the specified process
ID.
Parameters
tid |
Process ID for the process that will use the specified routing instance. |
vrf_name |
Name of a Junos OS routing instance.
|
Usage Examples
The following sample Python script retrieves
the process ID for the current process and associates the mgmt_junos
routing instance with that process. The script then pings a host
that is only reachable through that routing instance.
[vrf:none] user@host:~# cat libpyvrf-set-task-vrf.py import libpyvrf as vrf import os, subprocess command = [ 'ping', '-c', '3', 'host1.example.com' ] try: pid = os.getpid() vrf.set_task_vrf(pid, "mgmt_junos") print ("Using routing instance:", vrf.get_task_vrf(pid)) subprocess.call(command) == 0 except vrf.invalid_table as e: print ("Invalid Table") except vrf.evo_not_ready as e: print ("Junos OS Evolved network stack is not ready") except vrf.error as e: print ("Generic libvrf error")
[vrf:none] user@host:~# python3 libpyvrf-set-task-vrf.py Using routing instance: mgmt_junos PING host1.example.com (198.51.100.10) 56(84) bytes of data. 64 bytes from host1.example.com (198.51.100.10): icmp_seq=1 ttl=60 time=1.02 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=2 ttl=60 time=0.672 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=3 ttl=60 time=0.741 ms --- host1.example.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.876/0.946/1.001/0.063 ms
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.
Function deprecated in Junos OS Evolved Release 22.1R1.
set_vrf() Function
Syntax
set_vrf(vrf_name)
Description
Set the routing instance that the current process will use to perform operations. Future lookups will use this routing instance.
To associate a routing instance with a specific process instead
of the current process, use the set_task_vrf()
function.
Parameters
vrf_name |
Name of a Junos OS routing instance.
|
Usage Examples
The following sample Python script associates
the mgmt_junos
routing instance with the current process.
The script then pings a host that is only reachable through that routing
instance.
import libpyvrf as vrf import subprocess command = [ 'ping', '-c', '3', 'host1.example.com' ] try: vrf.set_vrf("mgmt_junos") print ("Using routing instance:", vrf.get_vrf()) subprocess.call(command) == 0 except vrf.invalid_table as e: print ("Invalid Table") except vrf.evo_not_ready as e: print ("Junos OS Evolved network stack is not ready") except vrf.error as e: print ("Generic libvrf error")
[vrf:none] user@host:~# python3 libpyvrf-set-vrf.py Using routing instance: mgmt_junos PING host1.example.com (198.51.100.10) 56(84) bytes of data. 64 bytes from host1.example.com (198.51.100.10): icmp_seq=1 ttl=60 time=1.02 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=2 ttl=60 time=0.672 ms 64 bytes from host1.example.com (198.51.100.10): icmp_seq=3 ttl=60 time=0.741 ms --- host1.example.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.876/0.946/1.001/0.063 ms
Release Information
Function introduced in Junos OS Evolved Release 20.3R1.