Custom routing with Cisco OnePk

The following example will show how to modify routing through Cisco OnePk APIs. It’s a very simple topology for a static network topology:

Onepk_4_routers

The intent is show step by step how to interact with routers using OnePk APIs: by default R1 can reach R4’s loopback through R3, with the following OnePk application the Next Hop will be R2.

import com.cisco.onep.core.exception.*;
import com.cisco.onep.element.*;
import com.cisco.onep.interfaces.*;
import com.cisco.onep.routing.*;
import com.cisco.onep.routing.L3UnicastScope.*;
import com.cisco.onep.routing.RouteOperation.*;
import java.net.InetAddress;
import java.util.*;

public class OnePKRouting {
	public static void main( String args[] ) {
		try {
			// Define NetworlApplication Instance Name, required when more onep device are present
			NetworkApplication.getInstance().setName("OnePK Routing Test");

			// Define onep devices
			NetworkElement onep_R1 = NetworkApplication.getInstance().getNetworkElement(InetAddress.getByName("192.168.255.1"));
			NetworkElement onep_R2 = NetworkApplication.getInstance().getNetworkElement(InetAddress.getByName("192.168.255.2"));
			NetworkElement onep_R4 = NetworkApplication.getInstance().getNetworkElement(InetAddress.getByName("192.168.255.4"));

			// Connect to onep devices
			onep_R1.connect("admin", "cisco");
			onep_R2.connect("admin", "cisco");
			onep_R4.connect("admin", "cisco");

			// Define both source and destination network prefixes
			NetworkPrefix prefix_R1 = new NetworkPrefix(InetAddress.getByName("192.168.255.1"), 32);
			NetworkPrefix prefix_R4 = new NetworkPrefix(InetAddress.getByName("192.168.255.4"), 32);

			// Define all network interface needed for custom routing
			L3UnicastNextHop R1_e0_0 = new L3UnicastNextHop(onep_R1.getInterfaceByName("Ethernet0/0"), InetAddress.getByName("192.168.12.1"));
			L3UnicastNextHop R2_e0_0 = new L3UnicastNextHop(onep_R2.getInterfaceByName("Ethernet0/0"), InetAddress.getByName("192.168.12.2"));
			L3UnicastNextHop R2_e0_1 = new L3UnicastNextHop(onep_R2.getInterfaceByName("Ethernet0/1"), InetAddress.getByName("192.168.24.2"));
			L3UnicastNextHop R4_e0_1 = new L3UnicastNextHop(onep_R4.getInterfaceByName("Ethernet0/1"), InetAddress.getByName("192.168.24.4"));

			// Define all nextHops for R1-R2-R4 path
			Set<L3UnicastNextHop> nextHops_R1_to_R2 = new HashSet<L3UnicastNextHop>();
			nextHops_R1_to_R2.add(R2_e0_0);
			Set<L3UnicastNextHop> nextHops_R2_to_R4 = new HashSet<L3UnicastNextHop>();
			nextHops_R2_to_R4.add(R4_e0_1);

			// Define all nextHops for R4-R2-R1 path
			Set<L3UnicastNextHop> nextHops_R4_to_R2 = new HashSet<L3UnicastNextHop>();
			nextHops_R4_to_R2.add(R2_e0_1);
			Set<L3UnicastNextHop> nextHops_R2_to_R1 = new HashSet<L3UnicastNextHop>();
			nextHops_R2_to_R1.add(R1_e0_0);

			// Define all routes to R4
			L3UnicastRoute R1_to_R2 = new L3UnicastRoute(prefix_R4, nextHops_R1_to_R2);
			R1_to_R2.setAdminDistance(1);
			L3UnicastRoute R2_to_R4 = new L3UnicastRoute(prefix_R4, nextHops_R2_to_R4);
			R2_to_R4.setAdminDistance(1);

			// Define all routes to R1
			L3UnicastRoute R4_to_R2 = new L3UnicastRoute(prefix_R1, nextHops_R4_to_R2);
			R4_to_R2.setAdminDistance(1);
			L3UnicastRoute R2_to_R1 = new L3UnicastRoute(prefix_R1, nextHops_R2_to_R1);
			R2_to_R1.setAdminDistance(1);

			// Define add route operations
			List<RouteOperation> R1_op = new ArrayList<RouteOperation>();
			R1_op.add(new L3UnicastRouteOperation(RouteOperationType.ADD, R1_to_R2));
			List<RouteOperation> R2_op = new ArrayList<RouteOperation>();
			R2_op.add(new L3UnicastRouteOperation(RouteOperationType.ADD, R2_to_R1));
			R2_op.add(new L3UnicastRouteOperation(RouteOperationType.ADD, R2_to_R4));
			List<RouteOperation> R4_op = new ArrayList<RouteOperation>();
			R4_op.add(new L3UnicastRouteOperation(RouteOperationType.ADD, R4_to_R2));

			// Modifying routing table
			Routing R1_routing = Routing.getInstance(onep_R1);
			Routing R2_routing = Routing.getInstance(onep_R2);
			Routing R4_routing = Routing.getInstance(onep_R4);

			AppRouteTable RIB_R1 = R1_routing.getAppRouteTable();
			AppRouteTable RIB_R2 = R2_routing.getAppRouteTable();
			AppRouteTable RIB_R4 = R4_routing.getAppRouteTable();

			L3UnicastScope scope = new L3UnicastScope("", AFIType.IPV4, SAFIType.UNICAST, "");

			RIB_R1.updateRoutes(scope, R1_op);
			RIB_R2.updateRoutes(scope, R2_op);
			RIB_R4.updateRoutes(scope, R4_op);

			// Disconnect onep devices
			onep_R1.disconnect();
			onep_R2.disconnect();
			onep_R4.disconnect();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Let’s review the main steps:

  • a network application name must be defined;
  • all devices must be defined, and a connection established;
  • choose the prefixes who need a custom routing;
  • defines for each router all next hops to that prefixes;
  • apply new routing tables to each router;
  • finally disconnect from each device.

After the app is terminated, R1, R2 and R4 routing is altered:

R1#show ip route 192.168.255.4
Routing entry for 192.168.255.4/32
  Known via "application OnePK Routing Test:5951", distance 1, metric 0
  Last update from 192.168.12.2 on Ethernet0/0, 00:00:19 ago
  Routing Descriptor Blocks:
  * 192.168.12.2, from 0.0.0.0, 00:00:19 ago, via Ethernet0/0
      Route metric is 0, traffic share count is 1

Remind that this is just a static example. A OnePk software should be able to auto discover the network topology and manage routing and avoid routing loops.

In the example above, if the link between R2 and R4 will go down, a loop will occour:

R1#traceroute 192.168.255.4
Type escape sequence to abort.
Tracing the route to 192.168.255.4
VRF info: (vrf in name/id, vrf out name/id)
  1 192.168.12.2 5 msec 5 msec 1 msec
  2 192.168.12.1 5 msec 0 msec 5 msec
  3  *  *  *

R1 will send packets to R2 for R4, using the OnePk route, and R2 will send the packets back to R1 because of the OSPF route.

Posted on 30 Sep 2013 by Andrea.
  • Gmail icon
  • Twitter icon
  • Facebook icon
  • LinkedIN icon
  • Google+ icon