Jonathan Hart

Implemented CLI commands to show SDN-IP routes

...@@ -48,6 +48,20 @@ ...@@ -48,6 +48,20 @@
48 </dependency> 48 </dependency>
49 49
50 <dependency> 50 <dependency>
51 + <groupId>org.onlab.onos</groupId>
52 + <artifactId>onos-cli</artifactId>
53 + <version>${project.version}</version>
54 + </dependency>
55 + <dependency>
56 + <groupId>org.apache.karaf.shell</groupId>
57 + <artifactId>org.apache.karaf.shell.console</artifactId>
58 + </dependency>
59 + <dependency>
60 + <groupId>org.osgi</groupId>
61 + <artifactId>org.osgi.core</artifactId>
62 + </dependency>
63 +
64 + <dependency>
51 <groupId>org.easymock</groupId> 65 <groupId>org.easymock</groupId>
52 <artifactId>easymock</artifactId> 66 <artifactId>easymock</artifactId>
53 <scope>test</scope> 67 <scope>test</scope>
......
...@@ -62,10 +62,8 @@ public class Router implements RouteListener { ...@@ -62,10 +62,8 @@ public class Router implements RouteListener {
62 62
63 private static final Logger log = LoggerFactory.getLogger(Router.class); 63 private static final Logger log = LoggerFactory.getLogger(Router.class);
64 64
65 - // Store all route updates in a InvertedRadixTree. 65 + // Store all route updates in a radix tree.
66 - // The key in this Tree is the binary sting of prefix of route. 66 + // The key in this tree is the binary string of prefix of the route.
67 - // The Ip4Address is the next hop address of route, and is also the value
68 - // of each entry.
69 private InvertedRadixTree<RouteEntry> bgpRoutes; 67 private InvertedRadixTree<RouteEntry> bgpRoutes;
70 68
71 // Stores all incoming route updates in a queue. 69 // Stores all incoming route updates in a queue.
...@@ -102,7 +100,7 @@ public class Router implements RouteListener { ...@@ -102,7 +100,7 @@ public class Router implements RouteListener {
102 * Class constructor. 100 * Class constructor.
103 * 101 *
104 * @param intentService the intent service 102 * @param intentService the intent service
105 - * @param proxyArp the proxy ARP service 103 + * @param hostService the host service
106 * @param configInfoService the configuration service 104 * @param configInfoService the configuration service
107 * @param interfaceService the interface service 105 * @param interfaceService the interface service
108 */ 106 */
...@@ -441,8 +439,8 @@ public class Router implements RouteListener { ...@@ -441,8 +439,8 @@ public class Router implements RouteListener {
441 /** 439 /**
442 * Processes adding a route entry. 440 * Processes adding a route entry.
443 * <p/> 441 * <p/>
444 - * Put new route entry into InvertedRadixTree. If there was an existing 442 + * Put new route entry into the radix tree. If there was an existing
445 - * nexthop for this prefix, but the next hop was different, then execute 443 + * next hop for this prefix, but the next hop was different, then execute
446 * deleting old route entry. If the next hop is the SDN domain, we do not 444 * deleting old route entry. If the next hop is the SDN domain, we do not
447 * handle it at the moment. Otherwise, execute adding a route. 445 * handle it at the moment. Otherwise, execute adding a route.
448 * 446 *
...@@ -623,8 +621,8 @@ public class Router implements RouteListener { ...@@ -623,8 +621,8 @@ public class Router implements RouteListener {
623 /** 621 /**
624 * Executes deleting a route entry. 622 * Executes deleting a route entry.
625 * <p/> 623 * <p/>
626 - * Removes prefix from InvertedRadixTree, if success, then try to delete 624 + * Removes prefix from radix tree, and if successful, then try to delete
627 - * the relative intent. 625 + * the related intent.
628 * 626 *
629 * @param routeEntry the route entry to delete 627 * @param routeEntry the route entry to delete
630 */ 628 */
...@@ -690,9 +688,9 @@ public class Router implements RouteListener { ...@@ -690,9 +688,9 @@ public class Router implements RouteListener {
690 public void arpResponse(IpAddress ipAddress, MacAddress macAddress) { 688 public void arpResponse(IpAddress ipAddress, MacAddress macAddress) {
691 log.debug("Received ARP response: {} => {}", ipAddress, macAddress); 689 log.debug("Received ARP response: {} => {}", ipAddress, macAddress);
692 690
693 - // We synchronize on this to prevent changes to the InvertedRadixTree 691 + // We synchronize on this to prevent changes to the radix tree
694 - // while we're pushing intent. If the InvertedRadixTree changes, the 692 + // while we're pushing intents. If the tree changes, the
695 - // InvertedRadixTree and intent could get out of sync. 693 + // tree and intents could get out of sync.
696 synchronized (this) { 694 synchronized (this) {
697 695
698 Set<RouteEntry> routesToPush = 696 Set<RouteEntry> routesToPush =
...@@ -709,14 +707,14 @@ public class Router implements RouteListener { ...@@ -709,14 +707,14 @@ public class Router implements RouteListener {
709 log.debug("Pushing prefix {} next hop {}", 707 log.debug("Pushing prefix {} next hop {}",
710 routeEntry.prefix(), routeEntry.nextHop()); 708 routeEntry.prefix(), routeEntry.nextHop());
711 // We only push prefix flows if the prefix is still in the 709 // We only push prefix flows if the prefix is still in the
712 - // InvertedRadixTree and the next hop is the same as our 710 + // radix tree and the next hop is the same as our
713 // update. 711 // update.
714 // The prefix could have been removed while we were waiting 712 // The prefix could have been removed while we were waiting
715 // for the ARP, or the next hop could have changed. 713 // for the ARP, or the next hop could have changed.
716 addRouteIntentToNextHop(prefix, ipAddress, macAddress); 714 addRouteIntentToNextHop(prefix, ipAddress, macAddress);
717 } else { 715 } else {
718 log.debug("Received ARP response, but {}/{} is no longer in" 716 log.debug("Received ARP response, but {}/{} is no longer in"
719 - + " InvertedRadixTree", routeEntry.prefix(), 717 + + " the radix tree", routeEntry.prefix(),
720 routeEntry.nextHop()); 718 routeEntry.nextHop());
721 } 719 }
722 } 720 }
......
...@@ -2,14 +2,18 @@ package org.onlab.onos.sdnip; ...@@ -2,14 +2,18 @@ package org.onlab.onos.sdnip;
2 2
3 import static org.slf4j.LoggerFactory.getLogger; 3 import static org.slf4j.LoggerFactory.getLogger;
4 4
5 +import java.util.Collection;
6 +
5 import org.apache.felix.scr.annotations.Activate; 7 import org.apache.felix.scr.annotations.Activate;
6 import org.apache.felix.scr.annotations.Component; 8 import org.apache.felix.scr.annotations.Component;
7 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
8 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
9 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.apache.felix.scr.annotations.Service;
10 import org.onlab.onos.net.host.HostService; 13 import org.onlab.onos.net.host.HostService;
11 import org.onlab.onos.net.intent.IntentService; 14 import org.onlab.onos.net.intent.IntentService;
12 import org.onlab.onos.sdnip.RouteUpdate.Type; 15 import org.onlab.onos.sdnip.RouteUpdate.Type;
16 +import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
13 import org.onlab.onos.sdnip.bgp.BgpSessionManager; 17 import org.onlab.onos.sdnip.bgp.BgpSessionManager;
14 import org.onlab.onos.sdnip.config.SdnIpConfigReader; 18 import org.onlab.onos.sdnip.config.SdnIpConfigReader;
15 import org.onlab.packet.IpAddress; 19 import org.onlab.packet.IpAddress;
...@@ -17,10 +21,11 @@ import org.onlab.packet.IpPrefix; ...@@ -17,10 +21,11 @@ import org.onlab.packet.IpPrefix;
17 import org.slf4j.Logger; 21 import org.slf4j.Logger;
18 22
19 /** 23 /**
20 - * Placeholder SDN-IP component. 24 + * Component for the SDN-IP peering application.
21 */ 25 */
22 @Component(immediate = true) 26 @Component(immediate = true)
23 -public class SdnIp { 27 +@Service
28 +public class SdnIp implements SdnIpService {
24 29
25 private final Logger log = getLogger(getClass()); 30 private final Logger log = getLogger(getClass());
26 31
...@@ -64,4 +69,14 @@ public class SdnIp { ...@@ -64,4 +69,14 @@ public class SdnIp {
64 protected void deactivate() { 69 protected void deactivate() {
65 log.info("Stopped"); 70 log.info("Stopped");
66 } 71 }
72 +
73 + @Override
74 + public Collection<BgpRouteEntry> getBgpRoutes() {
75 + return bgpSessionManager.getBgpRoutes();
76 + }
77 +
78 + @Override
79 + public Collection<RouteEntry> getRoutes() {
80 + return router.getRoutes();
81 + }
67 } 82 }
......
1 +package org.onlab.onos.sdnip;
2 +
3 +import java.util.Collection;
4 +
5 +import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
6 +
7 +/**
8 + * Service interface exported by SDN-IP.
9 + */
10 +public interface SdnIpService {
11 + /**
12 + * Gets the BGP routes.
13 + *
14 + * @return the BGP routes
15 + */
16 + public Collection<BgpRouteEntry> getBgpRoutes();
17 +
18 + /**
19 + * Gets all the routes known to SDN-IP.
20 + *
21 + * @return the SDN-IP routes
22 + */
23 + public Collection<RouteEntry> getRoutes();
24 +}
1 +package org.onlab.onos.sdnip.cli;
2 +
3 +import org.apache.karaf.shell.commands.Command;
4 +import org.onlab.onos.cli.AbstractShellCommand;
5 +import org.onlab.onos.sdnip.SdnIpService;
6 +import org.onlab.onos.sdnip.bgp.BgpConstants;
7 +import org.onlab.onos.sdnip.bgp.BgpRouteEntry;
8 +
9 +/**
10 + * Command to show the routes learned through BGP.
11 + */
12 +@Command(scope = "onos", name = "bgp-routes",
13 + description = "Lists all routes received from BGP")
14 +public class BgpRoutesListCommand extends AbstractShellCommand {
15 +
16 + private static final String FORMAT =
17 + "prefix=%s, nexthop=%s, origin=%s, localpref=%s, med=%s, aspath=%s, bgpid=%s";
18 +
19 + @Override
20 + protected void execute() {
21 + SdnIpService service = get(SdnIpService.class);
22 +
23 + for (BgpRouteEntry route : service.getBgpRoutes()) {
24 + printRoute(route);
25 + }
26 + }
27 +
28 + private void printRoute(BgpRouteEntry route) {
29 + if (route != null) {
30 + print(FORMAT, route.prefix(), route.nextHop(),
31 + originToString(route.getOrigin()), route.getLocalPref(),
32 + route.getMultiExitDisc(), route.getAsPath(),
33 + route.getBgpSession().getRemoteBgpId());
34 + }
35 + }
36 +
37 + private static String originToString(int origin) {
38 + String originString = "UNKNOWN";
39 +
40 + switch (origin) {
41 + case BgpConstants.Update.Origin.IGP:
42 + originString = "IGP";
43 + break;
44 + case BgpConstants.Update.Origin.EGP:
45 + originString = "EGP";
46 + break;
47 + case BgpConstants.Update.Origin.INCOMPLETE:
48 + originString = "INCOMPLETE";
49 + break;
50 + default:
51 + break;
52 + }
53 +
54 + return originString;
55 + }
56 +
57 +}
1 +package org.onlab.onos.sdnip.cli;
2 +
3 +import org.apache.karaf.shell.commands.Command;
4 +import org.onlab.onos.cli.AbstractShellCommand;
5 +import org.onlab.onos.sdnip.RouteEntry;
6 +import org.onlab.onos.sdnip.SdnIpService;
7 +
8 +/**
9 + * Command to show the list of routes in SDN-IP's routing table.
10 + */
11 +@Command(scope = "onos", name = "routes",
12 + description = "Lists all routes known to SDN-IP")
13 +public class RoutesListCommand extends AbstractShellCommand {
14 +
15 + private static final String FORMAT =
16 + "prefix=%s, nexthop=%s";
17 +
18 + @Override
19 + protected void execute() {
20 + SdnIpService service = get(SdnIpService.class);
21 +
22 + for (RouteEntry route : service.getRoutes()) {
23 + printRoute(route);
24 + }
25 + }
26 +
27 + private void printRoute(RouteEntry route) {
28 + if (route != null) {
29 + print(FORMAT, route.prefix(), route.nextHop());
30 + }
31 + }
32 +}
1 +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
2 +
3 + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
4 + <command>
5 + <action class="org.onlab.onos.sdnip.cli.BgpRoutesListCommand"/>
6 + </command>
7 + <command>
8 + <action class="org.onlab.onos.sdnip.cli.RoutesListCommand"/>
9 + </command>
10 + </command-bundle>
11 +</blueprint>