Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

VincentJahjah's profile - activity

2017-12-09 01:13:08 -0800 received badge  Famous Question (source)
2017-11-17 03:07:34 -0800 received badge  Notable Question (source)
2017-10-27 09:23:40 -0800 received badge  Popular Question (source)
2017-10-24 01:27:54 -0800 received badge  Self-Learner (source)
2017-10-24 01:25:53 -0800 received badge  Popular Question (source)
2017-10-16 12:00:58 -0800 received badge  Popular Question (source)
2017-10-10 10:13:24 -0800 answered a question How to get the Ip Address of a host node?

Answering my own question.

My problem stemmed from using the wrong "side" of the yang model. Here is code from my reverse-engineering test, showing what I was trying to "get" from the dataBroker:

NodeConnector nc =  new NodeConnectorBuilder().setId(new NodeConnectorId(ncIdStr))
                        .addAugmentation(AddressCapableNodeConnector.class, 
                            new AddressCapableNodeConnectorBuilder()
                            .setAddresses(Arrays.asList(new AddressesBuilder()
                                .setIp(ip).build())).build()).build();

Whereas I wanted to get hostNode objects, which is what l2switch uses to store its addresses:

org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.
network.topology.topology.NodeBuilder nb = 
     new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.
         network.topology.topology.NodeBuilder();

    nb.setNodeId(MDSalAccessUtils.makeNewNodeId("garbl"))
      .addAugmentation(HostNode.class,
              new HostNodeBuilder().setAddresses(Arrays.asList(
                      new AddressesBuilder().setIp(ip)
                      .build())).build());

Here's what I do to get the addresses (the process begins on 'link' notification events, which are themselves generated by DataTreeModification events):

public void newLink(Link link) {
    // openflow switch nodes have ids that begin with "openflow:".
    // Host nodes (aka service nodes) have ids that begin with the mac address of the node.
    Optional<HostNode> host = Optional.absent();
    NodeConnectorId altNc = null;
    if (!link.getSource().getSourceTp().getValue().contains("openflow:")) {
        host = MDSalAccessUtils.sourceHostNode(link, dataBroker);
        altNc = new NodeConnectorId(link.getDestination().getDestTp().getValue());
    } else if (!link.getDestination().getDestTp().getValue().contains("openflow:")) {
        host = MDSalAccessUtils.destHostNode(link, dataBroker);
        altNc = new NodeConnectorId(link.getSource().getSourceTp().getValue());
    }
    if (host.isPresent()) {
        for (Addresses addresses : host.get().getAddresses()) {
            realNodeAddresses.put(altNc, addresses.getIp());
        }
    }
}

public void updatedLink(Link oldLink, Link newLink) {
    removedLink(oldLink);
    newLink(newLink);
}

public void removedLink(Link link) {
    realNodeAddresses.remove(new NodeConnectorId( link.getDestination().getDestTp().getValue() ) );
    realNodeAddresses.remove(new NodeConnectorId( link.getSource().getSourceTp().getValue() ) );
}

MDSalAccessUtils is a custom utility class. The method used here is a simple read from databroker using a NetworkTopology --- Topology "flow:1" --- Node "nodeId" path.

2017-10-10 07:04:45 -0800 asked a question How to get the Ip Address of a host node?

I have tried with no avail to make my controller automatically detect which ip addresses are linked to which host nodes.

More precisely, I want to create a Map object associating NodeConnector(s) (or TerminationPoint) to IpAddress(es) of the host nodes at the other end of the Link.

I have installed l2switch and know that it is actively learning the ip address of host nodes, as when I query network-topology, I obtain juicy information:

"node-id": "host:06:03:09:94:c4:e7",
"termination-point": [
{
    "tp-id": "host:06:03:09:94:c4:e7"
}],
"host-tracker-service:attachment-points": [
{
    "tp-id": "openflow:7:5",
    "corresponding-tp": "host:06:03:09:94:c4:e7",
    "active": true
}],
"host-tracker-service:addresses": [
{
    "id": 5,
    "ip": "10.0.2.1",
    "first-seen": 1507640107999,
    "last-seen": 1507640107999,
    "mac": "06:03:09:94:c4:e7"
}

So there is clearly a way to access the information. I know that either l2switch's AddressTracker, or HostTracker, or both are responsible for providing this information.

I'm just not clear on how best to access it inside the Java code (which classes these informations are mapped to, etc.).

2017-10-09 14:50:19 -0800 received badge  Popular Question (source)
2017-10-09 14:50:19 -0800 received badge  Notable Question (source)
2017-10-09 09:16:19 -0800 commented answer Is there any way to get the ports from a given node (switch)?

Oh, sorry. It didn't expire, it's just that if a link ends a comment on this site, the "/p" tag gets included in the link... Just remove the "/p" in the link, or copy it directly

2017-10-07 05:35:20 -0800 answered a question Sending end user parameters to the controller

You can make getters and setters via RPC in the yang files of your projects:

rpc set-polling-frequency {
    description "Sets the amount of seconds between each poll instance";
    input {
        leaf nb-of-seconds {
            type uint32;
            default "20";
            description "Number of seconds between each poll instance";
        }
    }
}

rpc get-polling-frequency {
    description "Gets the amount of seconds between each poll instance";
    output {
        leaf nb-of-seconds {
            type uint32;
            default "20";
            description "Number of seconds between each poll instance";
        }
    }
}

And in your code:

... implements [PluginName]Service ...

@Override
public Future<RpcResult<Void>> setPollingFrequency(SetPollingFrequencyInput input) {
    if (input == null || input.getNbOfSeconds() == null) {
        return Futures.immediateFuture(RpcResultBuilder.<Void> failed().withError(
               ErrorType.APPLICATION, "oops").build());
    }
    pollingFrequency.set(input.getNbOfSeconds());
    return Futures.immediateFuture(RpcResultBuilder.<Void> success().build());
}

@Override
public Future<RpcResult<GetPollingStartThresholdOutput>> getPollingStartThreshold() {
    BigInteger value = BigInteger.valueOf(pollingStartThreshold.get());
    GetPollingStartThresholdOutput output = new GetPollingStartThresholdOutputBuilder()
                                                .setNbOfBytes(value).build();
    return Futures.immediateFuture(RpcResultBuilder.success(output).build());
}

Afterwards you will be able to make REST requests (e.g. via YangMan), or RPC-calls between your plugins. An added bonus is that they are easy to unit test.

2017-10-06 18:07:00 -0800 commented answer No implementation of RPC AbsoluteSchemaPath{path=[(PACKAGE)METHOD]} available)

I encountered this problem again, and as far as I can tell, it was because I put ANY code under the yang "model" projects. Moving the code to a separate project fixed the problem.

2017-10-06 13:26:46 -0800 commented answer Application composition : Changing table-ID for L2 Switch.

Ah, yes. I assumed the classes would be visible, but they aren't declared in the blueprint...

2017-10-06 09:22:54 -0800 commented answer Is there any way to get the ports from a given node (switch)?

To get all nodes, you can query the class Nodes (which has a getNode() method returning a list of Node). There were some query examples in my answer to your previous question, one of which involved querying a node using an id, from DataBroker: https://pastebin.com/uMsjEHAb

2017-10-06 07:32:57 -0800 received badge  Teacher (source)
2017-10-06 07:11:27 -0800 answered a question Is there any way to get the ports from a given node (switch)?

You mean, like this?

Node node = ...
List<NodeConnector> nodeConnectors = node.getNodeConnector();
for (NodeConnector nodeConnector : nodeConnectors) {
    nodeConnector.getId();
}

NodeConnectors are mapped to switch ports, so they are essentially the same.

Later versions of ODL use TerminationPoint instead of NodeConnector, but they are interchangeable (you can refer to a NodeConnector with a TerminationPoint's id, and vice versa).

You can even refer to OpenFlow's special ports in the following way (these ports exist for all switches, except for the optional ports which may not be supported by your openflow hardware):

// reserved ports (openflow 1.1+)
public final static NodeConnectorId INGRESS_PORT = new NodeConnectorId("0xfffffff8");
public final static NodeConnectorId TABLE_PORT = new NodeConnectorId("0xfffffff9");
public final static NodeConnectorId NORMAL_PORT = new NodeConnectorId("0xfffffffa"); // optional
public final static NodeConnectorId FLOOD_PORT = new NodeConnectorId("0xfffffffb"); // optional
public final static NodeConnectorId ALL_PORT = new NodeConnectorId("0xfffffffc");
public final static NodeConnectorId CONTROLLER_PORT = new NodeConnectorId("0xfffffffd");
public final static NodeConnectorId LOCAL_PORT = new NodeConnectorId("0xfffffffe");
public final static NodeConnectorId ANY_PORT = new NodeConnectorId("0xffffffff");
2017-10-06 06:57:19 -0800 commented question ItemLifeCycleListener in openflowplugin

A commit was made 8 agos to "Remove ItemLifeCycle" ... I don't know what that entails, or even if it's a total removal. https://github.com/opendaylight/openflowplugin/commit/0e1f602f7118e6dd7c7e53da1320c8e58d5cace4 I can't make sense of the commit message, sadly.

2017-10-06 06:50:53 -0800 answered a question Application composition : Changing table-ID for L2 Switch.

The pattern in l2switch appears to be the following: a provider class creates instances of flow-installing classes, and injects the configurations (e.g. the table id) via setters (e.g. setFlowTableId).

Take for instance l2switch-main:

private final DataBroker dataService;
private final NotificationProviderService notificationService;
private final SalFlowService salFlowService;
private final L2switchConfig mainConfig;

public L2SwitchMainProvider(final DataBroker dataBroker,
        final NotificationProviderService notificationService,
        final SalFlowService salFlowService, final L2switchConfig config) {
    this.dataService = dataBroker;
    this.notificationService = notificationService;
    this.salFlowService = salFlowService;
    this.mainConfig = config;
}

public void init() {
    // Setup FlowWrtierService
    FlowWriterServiceImpl flowWriterService = new FlowWriterServiceImpl(salFlowService);
    flowWriterService.setFlowTableId(mainConfig.getReactiveFlowTableId());
    flowWriterService.setFlowPriority(mainConfig.getReactiveFlowPriority());
    flowWriterService.setFlowIdleTimeout(mainConfig.getReactiveFlowIdleTimeout());
    flowWriterService.setFlowHardTimeout(mainConfig.getReactiveFlowHardTimeout());
    ...

And elsewhere, you have :

public void setFlowTableId(short flowTableId) {
    this.flowTableId = flowTableId;
}

The configs are injected on init() of l2switch. Even if you imported L2SwitchConfig in your project, it appears that config objects don't have setters, so that's definitely not an option. And even if you somehow modified the configs from your application, you would likely have to reboot the concerned l2switch plugins (I don't know how to trigger a reboot via application).

Use YangMan

YangMan contains a user-friendly interface that allows you to modify the configs of plugins installed in ODL. This should be your go-to for now. It should show up in your DLUX menu if you've installed it. I don't know exactly in which ODL bundle Yangman exists, but after installing the following, it shows up for me (I suspect it's odl-dluxapps-yangutils):

feature:install odl-dlux-core odl-dluxapps-applications odl-dluxapps-yangutils

If you REALLY want to do this via application...

A viable hack would be to inject all the flow-installing projects in your blueprint, and then use the "setFlowTableId" to set the tableId, without having to reboot ODL. I think this is pretty tedious, but I believe it should work. It won't work if l2switch begins installing rules before your plugins have the time to change the tableId, but I doubt this would happen.

2017-10-06 06:00:14 -0800 answered a question How to delete all flows for testing.

I have a few suggestions, but what you're trying to do feels a bit like going "against" l2switch's intended use case, so it may be a bit tedious.

Configuring l2switch

I know from this page that the l2switch plugins can be told to install rules or not (drop all flows and routing flows), although I think even on the "dumbest" settings, l2switch will still install some rules. Also, if you're relying on those rules, disabling them in l2switch could result in a broken network forwarding layer.

Removing all flows

You can query every openflow table on the network from MDSal. The query pattern looks like this:

query Nodes.class --- getNode() --- for each node --- query all tables (table ids range from 0 to 255, but your rules are probably all installed on table 0) --- for each table --- getFlow() --- for each flow --- remove the flow

This should allow you to remove every rule, as you want. Note that a rule is uninstalled if the given flow definition matches in the following way:

It has the same flowID (the same string), the same nodeId, and the same tableId.

Making it work afterwards

I have a pretty strong feeling that once you uninstall l2swtich's rules, it won't reinstall them. That is, l2switch installs its rules in a pretty straightforward way: if a new node appears on the topology, it installs rules on it. All that l2switch does in certain sections, is listen to node creation. There's pretty straightforward code about it in the l2switch modules that handle rule installation, like here.

The main issue to me is that l2switch's "InitialFlowWriter" classes (there's 3 of them iirc) don't even listen to node deletion; only node creation.

What would cause l2switch to reinstall its rules would then be to take down the entire topology (e.g. shut down mininet) and then bring it all up again (boot mininet again). In principle, shutting down ODL will not change the configuration of your network, so it shouldn't do anything in matters of "uninstalling flow rules".

If shutting down mininet is not a viable option, then there's one thing I believe MIGHT work:

  • Delete all nodes from MDSal "artifically" (but memorize them on the side)
  • Delete all flows from MDSal (maybe?)
  • Redadvertise all nodes on MDSAL (by using the nodes you memorized)

That way, you will have deleted all nodes, and then by re-advertising the nodes on MDSal, you will cause l2switch to re-install its rules, by making it assume that these are all new nodes.

What I DON'T know is whether you can uninstall flow rules even after the nodes are removed from MDSal. I also don't know if deleting a node from MDSal results in the flow rules being uninstalled (but I suspect not, as it requires the intervention of another plugin).

It's possible that l2switch only installs certain rules once, meaning that you can uninstall all flow rules, then delete all nodes ... (more)

2017-10-03 05:13:37 -0800 received badge  Famous Question (source)
2017-10-03 03:44:33 -0800 received badge  Popular Question (source)
2017-10-03 03:44:33 -0800 received badge  Notable Question (source)
2017-10-02 07:59:39 -0800 commented answer Where are the java files of NodeConnectorRef?

I did some tests and updated my answer. Does that answer your questions?

2017-10-01 19:12:52 -0800 commented question ./karaf: command not found

karaf is supposed to be found inside the {your odl distribution folder}/bin/assembly folder. Which are you looking into?

2017-10-01 19:11:54 -0800 commented question I setup Open vSwitch/Opendaylight. What is the next step?

Some of my past questions/answers may contain interesting information, if you're looking to experiment with openflow https://ask.opendaylight.org/question/27515/updating-examples-to-carbon/#27755 https://ask.opendaylight.org/question/27505/how-can-connect-my-odl-project-to-mininet/#27513

2017-10-01 19:10:23 -0800 commented question I setup Open vSwitch/Opendaylight. What is the next step?

... as well as l2switch Git Pages (which has branches for the various releases). Looking for the maven repositories nexus can also help if you're looking at whether specific release versions exist. I managed to achieve most things by blatantly copying l2switch's infrastructure and pom files.

2017-10-01 19:09:14 -0800 commented question I setup Open vSwitch/Opendaylight. What is the next step?

A couple of months ago I was in the same position, but I've managed to answer some questions since then. While I don't use the Carbon release ( I use more recent releases), I've managed to do most I wanted with Openflow+ODL. For reference, I recommend looking at the MD-SAL wiki pages...

2017-10-01 11:48:42 -0800 commented question Data Structure and ID relationships.

I can confirm that there are some very detailed IETF drafts on the IETF's website, and they appear to have some plain-text diagrams, for what it's worth. I'm not 100% how to read through them, or how they relate to ODL yet, or how to know which version is relevant.

2017-10-01 11:42:26 -0800 commented question Data Structure and ID relationships.

This is no uml diagram, but this page contains a list of the *.yang used across ODL projects. https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Model_Reference All relevant information should be in there. They appear to be linked with IETF standards, so maybe IETF have better docs?

2017-09-30 10:35:35 -0800 commented question No Flows appear in OpenDaylight Node Tab

I think you need plugins to "learn" the topology from the packets being sent across the network. You seem to have most of the main plugins, but maybe you could try installing odl-l2switch-all (iirc) instead of only installing odl-l2switch-switch. l2switch does a lot of the basic learning.

2017-09-29 07:59:56 -0800 edited answer Where are the java files of NodeConnectorRef?

For any classes whose imports look like

org.opendaylight.yang.gen.v1.urn.[...].revYYMMDD.[...]

You're looking at yang auto-generated code. Search yang files and you should fine them, but do note that classes like "...Ref", "...Key" and "...Id" are generally all generated together, so what you want to look for is NodeConnector, not NodeConnectorRef. Also, note that classes named in Yang are formatted something-like-this, and not SomethingLikeThis.

So, to answer you more explicitly, I googled node.yang, 4th result on google. All the classes you want are defined here.

All yang-generated classes are often quite empty, so you won't learn much from them. Essentially, a yang-generated class will have an unique ID object, which is its key (the key is made of an ID, and that's pretty much it). The "Ref" is the URI version of the Key or Id of the object, and is used to make a query in MD-SAL. An ID can be made into a key, and Ids and keys can be used to make a Ref, and a Ref can be used to query MD-SAL (dataBroker.new_transaction.read) and obtaining an actual object. (AFAIK, a Ref object is basically the same as a URI container, and is therefore much the same as an InstanceIdentifier object).

I'm no expert, but that's what I gathered.

Examples: https://pastebin.com/uMsjEHAb

EDIT: Node Ref Clarifications

Ref objects have only one public method: getValue(). As far as I know, they are plain data objects, or wrapper objects. Modifying them doesn't seem to be of any use, since one could just as easily make another NodeConnectorRef.

getValue() returns an InstanceIdentifier of their object, which itself contains information to reproduce a URI which can then be used for a RESTFUL request to fetch the dedicated object.

I tested this: https://pastebin.com/zCf7nQ19

The second test shows that there's some way to make a URI-like string from the classes of the objects (which is what we pass the "child" methods to build the IID). Note that we also pass "key" objects to the "child" method: these keys are the unique identifiers for individual instances of object (hence the + "1" I added to mimic those keys).