Metering and polling with ODL

Vincent Jahjah <vincent_jahjah@...>

Hello ODLers,

I've been looking at developping a Java application running on ODL.

So far, I've understood how to communicate with MD-SAL, how to use Maven to import the right dependencies, how to declare interfaces with YANG and how to inject dependencies with the blueprint xml files.

Now, I know how to get the list of Nodes, Links, Connectors, Flow Tables and Flows.

Now, monitoring flow bandwidth, sending notification on given bandwidth thresholds, and throttling flows that are too large.

I understand that Queues can "sort of" throttle flows, except that Queues are port-specific and not flow-specific. I understand that in OF1.3+, Meters can throttle flows, but it's hard (?) to find hardware that supports it. Neither of these appear to offer a functionality for "warning the controller when a flow reaches a certain bandwidth threshold". But it seems to do the job for throttling.

-> I don't understand is how to install meters, and how to install flow rules to redirect packets to meters before performing an output action. The L2Switch code has a fair amount of examples on how to install rules for routing, but not on how to install meters or forward packets to meters.

-> I don't understand *where* to look if I want to poll the bandwidth usage for flows. I know that in practice flow rules have packet counts and byte counts, which can be polled to estimate the bandwidth. That said, I'm unsure which object in MD-SAL is responsible for forwarding this information, or how I can access it given, e.g. a Flow object.

-> I was also led to believe that there already exist mechanisms internal to ODL which already do the polling, although I am unsure if these mechanisms poll for bandwidth explicitly, or other networking stats (like link latency). Is there already a way to get the bandwidth of a Flow object?

I know there are specific northbound REST APIs for doing a lot of the above tasks, but it seems silly to use a cumbersome interface like REST when I am coding side-to-side with the Controller code, which should be able to handle the queries anyway.

More concretely, I'm looking to complete the following code:

private void foo(InstanceIdentifier<Table> tableId) {
            FlowId flowId = new FlowId(FLOW_ID_PREFIX + String.valueOf(flowIdInc.getAndIncrement()));
            FlowKey flowKey = new FlowKey(flowId);
            InstanceIdentifier<Flow> flow =  tableId.child(Flow.class, flowKey);
            // get packet/byte count of the flow

private void bar(InstanceIdentifier<Meter> Meter, NodeConnectorRef destPort) {
      Uri destPortUri = destPort.getValue().firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId();

        Action sendToMeter = new ActionBuilder()
                .setKey(new ActionKey(0))
                .setAction(new OutputActionCaseBuilder()
                        .setOutputAction(new OutputActionBuilder()
                                // Send to Meter, and output to destPortUri