Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

We are now going to start building BYON. BYON is a service which allows you to spawn virtual networks in which each host is connected to every other host of that virtual network. Basically, each virtual network contains a full mesh of the hosts that make it up.

...

Lab 1: Importing and building an application

 FIXME We have downloaded some starter code in the ~/onos-byon directory. It contains a root pom.xml file for the project, as well as a initial implementation of the CLI bundle. We can start by importing the entire project into IntelliJ.

...

Next, we can return to a tutorial to build the project. 

 

Code Block
distributed@mininet
distributed@mininet-vm:~/onos-byon$ mci

[INFO]
Scanning 
 Scanning for
 
 projects...

...

[INFO] byon .............................................. SUCCESS [1.104s]

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time:
 
 6.719s

[INFO] Finished at: Fri
Dec 
 Dec 12
 
 14:28:16
 PST 2014
 PST 2014
[INFO] Final Memory: 30M/303M

[INFO] ------------------------------------------------------------------------
distributed@mininet

distributed@mininet-vm:~/onos-byon$

mci is an alias for mvn clean install. Now, that your project has successfully built your project let's push it up to the ONOS cluster..  

Code Block
distributed@mininet
distributed@mininet-vm:~/onos-byon$ onos-app $OC1 install target/byon-1.0-SNAPSHOT.oar

{"name":"org.onos.byon","id":37,"version":"1.0.SNAPSHOT",
"description":"Build Your Own Network App",
"origin":"Apps-R-Us LLC, Inc. GmbH","permissions":"[]",
"featuresRepo":"mvn:org.onos.byon/byon/1.0-SNAPSHOT/xml/features","features":"[byon]",
"state":"INSTALLED"}

 

The onos-app command will take the oar file that is generated during the build and push it into the specified ONOS instance. The command can also activate the application if you replace install with install! as well as separately activate, deactivate, and uninstall the application. Every time you update your code you simply need to run onos-app $OC1 reinstall! target/byon-1.0-SNAPSHOT.org and the new application will be loaded and started in the remote ONOS instances.

Let's check that everything works by heading into ONOS and running a couple commands:

 

Code Block
distributed@mininet
distributed@mininet-vm:~/onos-byon$ onos -w

Logging in as karaf

Welcome to Open Network Operating System (ONOS)!
     

     ____
 
  _
 
  ______
 
  ____
      /
  
    / __ \/ |/ / __ \/ __/
      /
   
   / /_/ /
   
    / /_/ /\
\         
 \      
   \____/_/|_/\____/___/
     
                              
Hit 
     
                              
Hit '<tab>'
 
 for
 
 a list of available commands
and 

and '[cmd] --help'
 
 for
 
 help on a specific command.
Hit 

Hit '<ctrl-d>'
 
 or
type 
 type 'system:shutdown'
 or 
 or 'logout'
 
 to shutdown ONOS.

onos> apps -s


...


 37 org.onos.byon 1.0.SNAPSHOT Build Your Own Network App

The application has been successfully installed, but it has not yet been activated. Next, we will activate it:

Code Block
onos> app activate org.onos.byon
onos> apps -s
...
* 37 org.onos.byon 1.0.SNAPSHOT Build Your Own Network App

The star next to the application indicates that it has been activated. We can try running the list-networks command to display the one fake network that is hard coded in the starter code.

...

Congratulations! You have successfully built, installed and activated the byon application.

TODO continue from here....

...

Lab 2: Connect the Manager to the Store

In this part, we are going to implement a trivial store for our network service as well as learn how to push intentssome of the NetworkManager's methods using the provided store. The store will be used to store the service's network state (duh!) while the intent framework will allow us to simply connect together every host in the virtual network we create. 

In order to be able to use the Intent Framework the caller must supply an Application ID. Application ID allow ONOS to identify who is consuming which resources as well as track applications. To achieve this, we have to add the following code to our NetworkManager class.

So first, we will need a reference to the CoreService, as it is the service that provides Application IDs. To do this add the follow code to the NetworkManager class.

; however, the implementation that is provided is not distributed. We will build a better store in a later part. 

The NetworkManager is going to have to use the store (that we are going to build) to store information therefore we are going to need a reference on a NetworkStore:

code
Code Block
languagejava
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreServiceNetworkStore coreServicestore;

This now gives you a reference to the CoreService at runtime. So let's pick up an application Id.

Code Block
languagejava
private ApplicationId appId;

// in activate method
appId = coreService.registerApplication("org.onos.byon");

Make sure to store the Application Id in a class field.

The NetworkManager is going to have to use the store (that we are going to build) to store information therefore we are going to need a reference on a NetworkStore:

Code Block
languagejava
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NetworkStore store;

Notice that at this point IntelliJ is not happy because the NetworkStore class does not exist. Well, let's crerate it!

Code Block
languagejava
public interface NetworkStore {
    /**
     * Create a named network.
     *
     * @param network network name
     */
    void putNetwork(String network);

    /**
     * Removes a named network.
     *
     * @param network network name
     */
    void removeNetwork(String network);

    /**
     * Returns a set of network names.
     *
     * @return a set of network names
     */
    Set<String> getNetworks();


    /**
     * Adds a host to the given network.
     *
     * @param network network name
     * @param hostId host id
     * @return updated set of hosts in the network (or an empty set if the host
     *         has already been added to the network)
     */
    Set<HostId> addHost(String network, HostId hostId);

    /**
     * Removes a host from the given network.
     *
     * @param network network name
     * @param hostId host id
     */
    void removeHost(String network, HostId hostId);

    /**
     * Returns all the hosts in a network.
     *
     * @param network network name
     * @return set of host ids
     */
    Set<HostId> getHosts(String network);

	/**
     * Adds a set of intents to a network
     *
     * @param network network name
     * @param intents set of intents
     */
    void addIntents(String network, Set<Intent> intents);

    /**
     * Returns a set of intents given a network and a host.
     *
     * @param network network name
     * @param hostId host id
     * @return set of intents
     */
    Set<Intent> removeIntents(String network, HostId hostId);

    /**
     * Returns a set of intents given a network.
     * @param network network name
     * @return set of intents
     */
    Set<Intent> removeIntents(String network);
	
}

Alright so now you have an interface for the NetworkStore, that makes IntelliJ happy. But someone should implement that interface right? Let's create a new class which implements the NetworkStore interface.

Code Block
languagejava
@Component(immediate = true, enabled = true)
@Service
public class SimpleNetworkStore
        implements NetworkStore {

    private static Logger log = LoggerFactory.getLogger(SimpleNetworkStore.class);

    private final Map<String, Set<HostId>> networks = Maps.newHashMap();
    private final Map<String, Set<Intent>> intentsPerNet = Maps.newHashMap();

    @Activate
    protected void activate() {
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        log.info("Stopped");
    }
}

Now as an exercise you must implement the methods of SimpleNetworkStore. Don't hesitate to ask questions here!

Add some Intents

Now that we have a simple store implementation, let's have byon program the network when hosts are added. For this we are going to need the intent framework, so let's grab a reference  to it in the network manager.

Code Block
languagejava
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentService intentService;

And we will need the following code to implement the mesh of the hosts in each virtual network.

There are six methods in the NetworkManager that should make calls to the network store. They are marked with "TODO Lab 2" in the starter code.

For example in the getNetworks() method, we will want to replace:

Code Block
return ImmutableSet.of("my-network"); // TODO remove this line before starting lab 2

with a call to the store:

Code Block
return store.getNetworks();

Next, let's verify that everything works.

First, you will need to compile byon again with mci and run onos-app $OC1 reinstall! target/byon-1.0-SNAPSHOT.oar again to get your latest bundle loaded into the ONOS docker instances.

Now at an ONOS shell, let's try some of the commands.

Code Block
onos> list-networks 
onos> create-network test
Created network test    
onos> add-host test 00:00:00:00:00:01/-1
Added host 00:00:00:00:00:01/-1 to test   
onos> add-host test 00:00:00:00:00:02/-1
Added host 00:00:00:00:00:02/-1 to test
onos> list-networks 
test
	00:00:00:00:00:01/-1
	00:00:00:00:00:02/-1

Lab 3: Add intents to allow traffic to flow in the virtual networks

In order to be able to use many of ONOS' services, the caller must supply an Application ID. An application ID allow ONOS to identify who is consuming which resources as well as track applications. To achieve this, we ask the CoreService for an application ID in the activate method. You should use the appId when constructing the intents for this part.

We will also need to get a reference to the IntentService. The reference will automatically be injected when the application is loaded after you uncomment the two lines near the top of the NetworkManager.

When addHost() is called, we will need to create an intent between the host and all other hosts that already exist in the network.

Info

You should only to add the intents if this is the first time that the host is added, so be sure to check the store's return value. true indicates that the add was successful i.e. this is the first time.

For this exercise, we will be using HostToHostIntents and you can build one like this:

Code Block
Intent intent = HostToHostIntent.builder()
                                .appId(appId)
                                .key(generateKey(network, src, dst))
                                .one(src)
  
Code Block
languagejava
    private Set<Intent> addToMesh(HostId src, Set<HostId> existing) {
    if (existing.isEmpty()) {
        return Collections.emptySet();
    }
    Set<Intent> submitted = new HashSet<>();
    existing.forEach(dst -> {
        if (!src.equals(dst)) {
            Intent intent = new HostToHostIntent(appId, src, dst);
            submitted.addtwo(intentdst);
            intentService.submit(intent);
         }
    });
    return submitted;
}

private void removeFromMesh.build(Set<Intent> intents) {
    intents.forEach(i -> intentService.withdraw(i));
}

Verify that everything works

So make sure you compile byon again with mci and run byon-push-bits again to get your latest bundles loaded into the ONOS docker instances.

Now at an ONOS shell, play around with byon. and you should be able to forward traffic in mininet.

;
intentService.submit(intent);

Make sure to submit a HostToHostIntent between the newly added host, and all other hosts that are already in the virtual network.

It's time to make sure that everything works; build with mci and run onos-app $OC1 reinstall! target/byon-1.0-SNAPSHOT.oar 

Code Block
Code Block
onos> list-networks 
onos> create-network testtest2
Created network testtest2    
onos> add-host testtest2 00:00:00:00:00:01/-1
Added host 00:00:00:00:00:01/-1 to test   
onos> add-host testtest2 00:00:00:00:00:02/-1 #fixme
Added host 00:00:00:00:00:02/-1 to test
onos> list-networks 
testtest2
	00:00:00:00:00:01/-1
	00:00:00:00:00:02/-1
onos> intents
id=0x0, state=INSTALLED, type=HostToHostIntent, appId=org.onos.byon
    constraints=[LinkTypeConstraint{inclusive=false, types=[OPTICAL]}]

Now check in mininet that you can actually communicated between the two hosts that you added to your virtual network.

 

Code Block
mininet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=21.4 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.716 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.073 ms

Part 3: Flesh Out the CLI

 icmp_seq=3 ttl=64 time=0.073 ms

Lab 4: Implementing removal of hosts from a virtual network

When a host is removed from a network or a network is removed entirely, we need to remove the intent related to that host or network from the IntentService. There are Lab 4 TODOs in the removeHost() and removeNetwork() methods. The starter code also contains a removeIntents() method that you will need to complete. In this method, you will need to get the intents from the IntentService, filter the relevant ones to remove, and then instruct the IntentService to withdrawn them. Note: For your convenience, we have provided a helper method, matches(), that can be used to filter the relevant intents.

Next, we will need to construct some CLI commands so that you can test your work, specifically, one command to remove hosts and another to remove networks.

Ok so the CLI allows you to add networks and hosts but not remove them. In part you will learn how to create CLI commands in ONOS. Start by creating two files in the byon-cli package "RemoveHostCommand.java" and "RemoveNetworkCommand.java". These CLI commands are simple and very similar to the add CLI commands, so do this now as an exercise. When you have written these commands, you will need to add the following XML to the 'shell-config.xml' under resources.

Code Block
<command>
	<action class="org.onos.byon.cli.RemoveHostCommand"/>
    <completers>
		<ref component-id="networkCompleter"/>
        <ref component-id="hostIdCompleter"/>
        <null/>
	</completers>
</command>
<command>
	<action class="org.onos.byon.cli.RemoveNetwork"/>
	<completers>
		<ref component-id="networkCompleter"/>
        <null/>
    </completers>
</command>

...

 Once again if you recompile your code and use byon-push-bits you will onos-app update your bundles application on the ONOS instances. You should now be able to add and remove networks as well as hosts. Try it out!

Now, you should have a fairly complete implementation of the BYON app, but it will only work from one instance. (Try running list-networks on another instance!

...

It will not show you any networks.)

Lab 5: TODO

Lab 5: Network Events

 In order to be able to communicate between ONOS instances we are going to make use of events. These events will be fired by the distributed store and caught by the manager in the peer ONOS instance. At this point the peer manager will notify any local listeners of the network event. 

...