mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-05 04:06:49 +02:00
ONOS-5475 OFAgent - Handle OFFlowStatsRequest, OFTableDescStatsRequest, OFGroupStatsRequest, OFGroupDescStatsRequest
Change-Id: I67734951a756ea61d8aaf9d520b3101141e3d73c
This commit is contained in:
parent
aa279c014e
commit
ce8ccc604f
@ -21,6 +21,9 @@ import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.Port;
|
||||
import org.onosproject.net.PortNumber;
|
||||
import org.onosproject.net.device.PortStatistics;
|
||||
import org.onosproject.net.flow.FlowEntry;
|
||||
import org.onosproject.net.flow.TableStatisticsEntry;
|
||||
import org.onosproject.net.group.Group;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -72,6 +75,33 @@ public interface OFSwitchService {
|
||||
*/
|
||||
List<PortStatistics> getPortStatistics(NetworkId networkId, DeviceId deviceId);
|
||||
|
||||
/**
|
||||
* Returns all flow entries of the specified device in the specified network.
|
||||
*
|
||||
* @param networkId network id
|
||||
* @param deviceId device id
|
||||
* @return list of flow entries; empty list if none exists for the specified device
|
||||
*/
|
||||
List<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId);
|
||||
|
||||
/**
|
||||
* Returns all flow table statistics of the specified device in the specified network.
|
||||
*
|
||||
* @param networkId network id
|
||||
* @param deviceId device id
|
||||
* @return list of flow table statistics; empty list if none exists for the specified device
|
||||
*/
|
||||
List<TableStatisticsEntry> getFlowTableStatistics(NetworkId networkId, DeviceId deviceId);
|
||||
|
||||
/**
|
||||
* Returns all groups associated with the specified device in the specified network.
|
||||
*
|
||||
* @param networkId network id
|
||||
* @param deviceId device id
|
||||
* @return list of groups; empty list if none exists for the specified device
|
||||
*/
|
||||
List<Group> getGroups(NetworkId networkId, DeviceId deviceId);
|
||||
|
||||
/**
|
||||
* Returns neighbour port of the specified port in the specified network.
|
||||
*
|
||||
|
||||
@ -16,28 +16,38 @@
|
||||
package org.onosproject.ofagent.impl;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.channel.Channel;
|
||||
import org.onlab.osgi.ServiceDirectory;
|
||||
import org.onosproject.incubator.net.virtual.NetworkId;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.Port;
|
||||
import org.onosproject.net.device.PortStatistics;
|
||||
import org.onosproject.net.flow.FlowRule;
|
||||
import org.onosproject.net.packet.InboundPacket;
|
||||
import org.onosproject.net.PortNumber;
|
||||
import org.onosproject.net.device.PortStatistics;
|
||||
import org.onosproject.net.flow.FlowEntry;
|
||||
import org.onosproject.net.flow.FlowRule;
|
||||
import org.onosproject.net.flow.TableStatisticsEntry;
|
||||
import org.onosproject.net.group.Group;
|
||||
import org.onosproject.net.packet.InboundPacket;
|
||||
import org.onosproject.ofagent.api.OFSwitch;
|
||||
import org.onosproject.ofagent.api.OFSwitchCapabilities;
|
||||
import org.onosproject.ofagent.api.OFSwitchService;
|
||||
import org.projectfloodlight.openflow.protocol.OFActionType;
|
||||
import org.projectfloodlight.openflow.protocol.OFBarrierReply;
|
||||
import org.projectfloodlight.openflow.protocol.OFBucket;
|
||||
import org.projectfloodlight.openflow.protocol.OFBucketCounter;
|
||||
import org.projectfloodlight.openflow.protocol.OFControllerRole;
|
||||
import org.projectfloodlight.openflow.protocol.OFEchoReply;
|
||||
import org.projectfloodlight.openflow.protocol.OFEchoRequest;
|
||||
import org.projectfloodlight.openflow.protocol.OFFactories;
|
||||
import org.projectfloodlight.openflow.protocol.OFFactory;
|
||||
import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
|
||||
import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
|
||||
import org.projectfloodlight.openflow.protocol.OFGetConfigReply;
|
||||
import org.projectfloodlight.openflow.protocol.OFGroupDescStatsEntry;
|
||||
import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry;
|
||||
import org.projectfloodlight.openflow.protocol.OFGroupType;
|
||||
import org.projectfloodlight.openflow.protocol.OFHello;
|
||||
import org.projectfloodlight.openflow.protocol.OFMessage;
|
||||
import org.projectfloodlight.openflow.protocol.OFMeterFeatures;
|
||||
@ -54,14 +64,18 @@ import org.projectfloodlight.openflow.protocol.OFRoleRequest;
|
||||
import org.projectfloodlight.openflow.protocol.OFSetConfig;
|
||||
import org.projectfloodlight.openflow.protocol.OFStatsReply;
|
||||
import org.projectfloodlight.openflow.protocol.OFStatsRequest;
|
||||
import org.projectfloodlight.openflow.protocol.OFTableStatsEntry;
|
||||
import org.projectfloodlight.openflow.protocol.OFType;
|
||||
import org.projectfloodlight.openflow.protocol.OFVersion;
|
||||
import org.projectfloodlight.openflow.protocol.action.OFAction;
|
||||
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
|
||||
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
|
||||
import org.projectfloodlight.openflow.protocol.match.Match;
|
||||
import org.projectfloodlight.openflow.protocol.match.MatchField;
|
||||
import org.projectfloodlight.openflow.types.DatapathId;
|
||||
import org.projectfloodlight.openflow.types.OFGroup;
|
||||
import org.projectfloodlight.openflow.types.OFPort;
|
||||
import org.projectfloodlight.openflow.types.TableId;
|
||||
import org.projectfloodlight.openflow.types.U64;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -259,6 +273,76 @@ public final class DefaultOFSwitch implements OFSwitch {
|
||||
return ofPortStatsEntry;
|
||||
}
|
||||
|
||||
private OFFlowStatsEntry ofFlowStatsEntry(FlowEntry flowEntry) {
|
||||
// TODO get match from flowEntry.selector()
|
||||
Match.Builder matchB = FACTORY.buildMatch();
|
||||
OFActionOutput actionOutput = FACTORY.actions()
|
||||
.buildOutput().build();
|
||||
// TODO get instructions from flowEntry.treatment()
|
||||
OFInstruction instruction = FACTORY.instructions()
|
||||
.applyActions(Collections.singletonList(actionOutput));
|
||||
OFFlowStatsEntry ofFlowStatsEntry = FACTORY.buildFlowStatsEntry()
|
||||
.setMatch(matchB.build())
|
||||
.setInstructions(Collections.singletonList(instruction))
|
||||
.setTableId(TableId.of(flowEntry.tableId()))
|
||||
.setHardTimeout(flowEntry.hardTimeout())
|
||||
.setIdleTimeout(flowEntry.timeout())
|
||||
.setCookie(U64.of(flowEntry.id().value()))
|
||||
.setPriority(flowEntry.priority())
|
||||
.setDurationSec(flowEntry.life())
|
||||
.setPacketCount(U64.of(flowEntry.packets()))
|
||||
.setByteCount(U64.of(flowEntry.bytes()))
|
||||
.build();
|
||||
return ofFlowStatsEntry;
|
||||
}
|
||||
|
||||
private OFTableStatsEntry ofFlowTableStatsEntry(TableStatisticsEntry tableStatisticsEntry) {
|
||||
OFTableStatsEntry ofTableStatsEntry = FACTORY.buildTableStatsEntry()
|
||||
.setTableId(TableId.of(tableStatisticsEntry.tableId()))
|
||||
.setActiveCount(tableStatisticsEntry.activeFlowEntries())
|
||||
.setLookupCount(U64.of(tableStatisticsEntry.packetsLookedup()))
|
||||
.setMatchedCount(U64.of(tableStatisticsEntry.packetsLookedup()))
|
||||
.build();
|
||||
return ofTableStatsEntry;
|
||||
}
|
||||
|
||||
private OFGroupStatsEntry ofGroupStatsEntry(Group group) {
|
||||
List<OFBucketCounter> ofBucketCounters = Lists.newArrayList();
|
||||
group.buckets().buckets().forEach(groupBucket -> {
|
||||
ofBucketCounters.add(FACTORY.bucketCounter(
|
||||
U64.of(groupBucket.packets()), U64.of(groupBucket.bytes())));
|
||||
});
|
||||
OFGroupStatsEntry entry = FACTORY.buildGroupStatsEntry()
|
||||
.setGroup(OFGroup.of(group.id().id()))
|
||||
.setDurationSec(group.life())
|
||||
.setPacketCount(U64.of(group.packets()))
|
||||
.setByteCount(U64.of(group.bytes()))
|
||||
.setRefCount(group.referenceCount())
|
||||
.setBucketStats(ofBucketCounters)
|
||||
.build();
|
||||
return entry;
|
||||
}
|
||||
|
||||
private OFGroupDescStatsEntry ofGroupDescStatsEntry(Group group) {
|
||||
List<OFBucket> ofBuckets = Lists.newArrayList();
|
||||
group.buckets().buckets().forEach(groupBucket -> {
|
||||
ofBuckets.add(FACTORY.buildBucket()
|
||||
.setWeight(groupBucket.weight())
|
||||
.setWatchGroup(OFGroup.of(groupBucket.watchGroup().id()))
|
||||
.setWatchPort(OFPort.of((int) groupBucket.watchPort().toLong()))
|
||||
.build()
|
||||
);
|
||||
});
|
||||
OFGroup ofGroup = OFGroup.of(group.givenGroupId());
|
||||
OFGroupType ofGroupType = OFGroupType.valueOf(group.type().name());
|
||||
OFGroupDescStatsEntry entry = FACTORY.buildGroupDescStatsEntry()
|
||||
.setGroup(ofGroup)
|
||||
.setGroupType(ofGroupType)
|
||||
.setBuckets(ofBuckets)
|
||||
.build();
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processStatsRequest(Channel channel, OFMessage msg) {
|
||||
if (msg.getType() != OFType.STATS_REQUEST) {
|
||||
@ -308,6 +392,54 @@ public final class DefaultOFSwitch implements OFSwitch {
|
||||
//TODO add details
|
||||
.build();
|
||||
break;
|
||||
case FLOW:
|
||||
List<OFFlowStatsEntry> flowStatsEntries = new ArrayList<>();
|
||||
List<FlowEntry> flowStats = ofSwitchService.getFlowEntries(networkId, deviceId);
|
||||
flowStats.forEach(flowEntry -> {
|
||||
OFFlowStatsEntry ofFlowStatsEntry = ofFlowStatsEntry(flowEntry);
|
||||
flowStatsEntries.add(ofFlowStatsEntry);
|
||||
});
|
||||
ofStatsReply = FACTORY.buildFlowStatsReply()
|
||||
.setEntries(flowStatsEntries)
|
||||
.setXid(msg.getXid())
|
||||
.build();
|
||||
break;
|
||||
case TABLE:
|
||||
List<OFTableStatsEntry> ofTableStatsEntries = new ArrayList<>();
|
||||
List<TableStatisticsEntry> tableStats = ofSwitchService.getFlowTableStatistics(networkId, deviceId);
|
||||
tableStats.forEach(tableStatisticsEntry -> {
|
||||
OFTableStatsEntry ofFlowStatsEntry = ofFlowTableStatsEntry(tableStatisticsEntry);
|
||||
ofTableStatsEntries.add(ofFlowStatsEntry);
|
||||
});
|
||||
ofStatsReply = FACTORY.buildTableStatsReply()
|
||||
.setEntries(ofTableStatsEntries)
|
||||
.setXid(msg.getXid())
|
||||
.build();
|
||||
break;
|
||||
case GROUP:
|
||||
List<Group> groupStats = ofSwitchService.getGroups(networkId, deviceId);
|
||||
List<OFGroupStatsEntry> ofGroupStatsEntries = new ArrayList<>();
|
||||
groupStats.forEach(group -> {
|
||||
OFGroupStatsEntry entry = ofGroupStatsEntry(group);
|
||||
ofGroupStatsEntries.add(entry);
|
||||
});
|
||||
ofStatsReply = FACTORY.buildGroupStatsReply()
|
||||
.setEntries(ofGroupStatsEntries)
|
||||
.setXid(msg.getXid())
|
||||
.build();
|
||||
break;
|
||||
case GROUP_DESC:
|
||||
List<OFGroupDescStatsEntry> ofGroupDescStatsEntries = new ArrayList<>();
|
||||
List<Group> groupStats2 = ofSwitchService.getGroups(networkId, deviceId);
|
||||
groupStats2.forEach(group -> {
|
||||
OFGroupDescStatsEntry entry = ofGroupDescStatsEntry(group);
|
||||
ofGroupDescStatsEntries.add(entry);
|
||||
});
|
||||
ofStatsReply = FACTORY.buildGroupDescStatsReply()
|
||||
.setEntries(ofGroupDescStatsEntries)
|
||||
.setXid(msg.getXid())
|
||||
.build();
|
||||
break;
|
||||
case DESC:
|
||||
ofStatsReply = FACTORY.buildDescStatsReply()
|
||||
.setXid(msg.getXid())
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.onosproject.ofagent.impl;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.netty.channel.ChannelOutboundInvoker;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import org.apache.felix.scr.annotations.Activate;
|
||||
@ -44,9 +45,13 @@ import org.onosproject.net.device.DeviceEvent;
|
||||
import org.onosproject.net.device.DeviceListener;
|
||||
import org.onosproject.net.device.DeviceService;
|
||||
import org.onosproject.net.device.PortStatistics;
|
||||
import org.onosproject.net.flow.FlowEntry;
|
||||
import org.onosproject.net.flow.FlowRuleEvent;
|
||||
import org.onosproject.net.flow.FlowRuleListener;
|
||||
import org.onosproject.net.flow.FlowRuleService;
|
||||
import org.onosproject.net.flow.TableStatisticsEntry;
|
||||
import org.onosproject.net.group.Group;
|
||||
import org.onosproject.net.group.GroupService;
|
||||
import org.onosproject.net.link.LinkService;
|
||||
import org.onosproject.net.packet.PacketContext;
|
||||
import org.onosproject.net.packet.PacketProcessor;
|
||||
@ -65,6 +70,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@ -198,6 +204,30 @@ public class OFSwitchManager implements OFSwitchService {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId) {
|
||||
FlowRuleService flowRuleService = virtualNetService.get(networkId, FlowRuleService.class);
|
||||
Iterable<FlowEntry> entries = flowRuleService.getFlowEntries(deviceId);
|
||||
return Lists.newArrayList(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TableStatisticsEntry> getFlowTableStatistics(NetworkId networkId, DeviceId deviceId) {
|
||||
FlowRuleService flowRuleService = virtualNetService.get(networkId, FlowRuleService.class);
|
||||
Iterable<TableStatisticsEntry> entries = flowRuleService.getFlowTableStatistics(deviceId);
|
||||
if (entries == null) {
|
||||
entries = new ArrayList<>();
|
||||
}
|
||||
return Lists.newArrayList(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Group> getGroups(NetworkId networkId, DeviceId deviceId) {
|
||||
GroupService groupService = virtualNetService.get(networkId, GroupService.class);
|
||||
Iterable<Group> entries = groupService.getGroups(deviceId);
|
||||
return Lists.newArrayList(entries);
|
||||
}
|
||||
|
||||
private void addOFSwitch(NetworkId networkId, DeviceId deviceId) {
|
||||
OFSwitch ofSwitch = DefaultOFSwitch.of(
|
||||
dpidWithDeviceId(deviceId),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user