use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class HPPipelineV3800 method tableIdForForwardingObjective.
@Override
protected int tableIdForForwardingObjective(TrafficSelector selector, TrafficTreatment treatment) {
boolean hardwareProcess = true;
log.debug("HP V3800 Driver - Evaluating the ForwardingObjective for proper TableID");
// Check criteria supported in hardware
for (Criterion criterion : selector.criteria()) {
if (!this.hardwareCriteria.contains(criterion.type())) {
log.warn("HP V3800 Driver - criterion {} only supported in SOFTWARE", criterion.type());
hardwareProcess = false;
break;
}
// HP3800 does not support hardware match on ETH_TYPE of value TYPE_VLAN
if (criterion.type() == Criterion.Type.ETH_TYPE) {
if (((EthTypeCriterion) criterion).ethType().toShort() == Ethernet.TYPE_VLAN) {
log.warn("HP V3800 Driver - ETH_TYPE == VLAN (0x8100) is only supported in software");
hardwareProcess = false;
break;
}
}
}
// Check if a CLEAR action is included
if (treatment.clearedDeferred()) {
log.warn("HP V3800 Driver - CLEAR action only supported in SOFTWARE");
hardwareProcess = false;
}
// If criteria can be processed in hardware, then check treatment
if (hardwareProcess) {
for (Instruction instruction : treatment.allInstructions()) {
// Check if the instruction type is contained in the hardware instruction
if (!this.hardwareInstructions.contains(instruction.type())) {
log.warn("HP V3800 Driver - instruction {} only supported in SOFTWARE", instruction.type());
hardwareProcess = false;
break;
}
/**
* If output is CONTROLLER_PORT the flow entry could be installed in hardware
* but is anyway processed in software because OPENFLOW header has to be added
*/
if (instruction.type() == Instruction.Type.OUTPUT) {
if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
log.warn("HP V3800 Driver - Forwarding to CONTROLLER only supported in software");
hardwareProcess = false;
break;
}
}
// Check if the specific L2MODIFICATION.subtype is supported in hardware
if (instruction.type() == Instruction.Type.L2MODIFICATION) {
if (!this.hardwareInstructionsL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
log.warn("HP V3800 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE", ((L2ModificationInstruction) instruction).subtype());
hardwareProcess = false;
break;
}
}
// TODO --- check if all the buckets contains one and only one output action
if (instruction.type() == Instruction.Type.GROUP) {
boolean groupInstalled = false;
GroupId groupId = ((Instructions.GroupInstruction) instruction).groupId();
Iterable<Group> groupsOnDevice = groupService.getGroups(deviceId);
for (Group group : groupsOnDevice) {
if ((group.state() == Group.GroupState.ADDED) && (group.id().equals(groupId))) {
groupInstalled = true;
if (group.type() != Group.Type.ALL) {
log.warn("HP V3800 Driver - group type {} only supported in SOFTWARE", group.type().toString());
hardwareProcess = false;
}
break;
}
}
if (!groupInstalled) {
log.warn("HP V3800 Driver - referenced group is not installed on the device.");
hardwareProcess = false;
}
}
}
}
if (hardwareProcess) {
log.warn("HP V3800 Driver - This flow rule is supported in HARDWARE");
return HP_HARDWARE_TABLE;
} else {
// TODO: create a specific flow in table 100 to redirect selected traffic on table 200
log.warn("HP V3800 Driver - This flow rule is only supported in SOFTWARE");
return HP_SOFTWARE_TABLE;
}
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class HPPipelineV3 method tableIdForForwardingObjective.
@Override
protected int tableIdForForwardingObjective(TrafficSelector selector, TrafficTreatment treatment) {
boolean hardwareProcess = true;
log.debug("HP V3 Driver - Evaluating the ForwardingObjective for proper TableID");
// Check criteria supported in hardware
for (Criterion criterion : selector.criteria()) {
if (!this.hardwareCriteria.contains(criterion.type())) {
log.warn("HP V3 Driver - criterion {} only supported in SOFTWARE", criterion.type());
hardwareProcess = false;
break;
}
// HP3800 does not support hardware match on ETH_TYPE of value TYPE_VLAN
if (criterion.type() == Criterion.Type.ETH_TYPE) {
if (((EthTypeCriterion) criterion).ethType().toShort() == Ethernet.TYPE_VLAN) {
log.warn("HP V3 Driver - ETH_TYPE == VLAN (0x8100) is only supported in software");
hardwareProcess = false;
break;
}
}
}
// If criteria can be processed in hardware, then check treatment
if (hardwareProcess) {
for (Instruction instruction : treatment.allInstructions()) {
// Check if the instruction type is contained in the hardware instruction
if (!this.hardwareInstructions.contains(instruction.type())) {
log.warn("HP V3 Driver - instruction {} only supported in SOFTWARE", instruction.type());
hardwareProcess = false;
break;
}
/**
* If output is CONTROLLER_PORT the flow entry could be installed in hardware
* but is anyway processed in software because OPENFLOW header has to be added
*/
if (instruction.type() == Instruction.Type.OUTPUT) {
if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
log.warn("HP V3 Driver - Forwarding to CONTROLLER only supported in software");
hardwareProcess = false;
break;
}
}
// Check if the specific L2MODIFICATION.subtype is supported in hardware
if (instruction.type() == Instruction.Type.L2MODIFICATION) {
if (!this.hardwareInstructionsL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
log.warn("HP V3 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE", ((L2ModificationInstruction) instruction).subtype());
hardwareProcess = false;
break;
}
}
// Check if the specific L3MODIFICATION.subtype is supported in hardware
if (instruction.type() == Instruction.Type.L3MODIFICATION) {
if (!this.hardwareInstructionsL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
log.warn("HP V3 Driver - L3MODIFICATION.subtype {} only supported in SOFTWARE", ((L3ModificationInstruction) instruction).subtype());
hardwareProcess = false;
break;
}
}
// Check if the specific L4MODIFICATION.subtype is supported in hardware
if (instruction.type() == Instruction.Type.L4MODIFICATION) {
if (!this.hardwareInstructionsL4mod.contains(((L4ModificationInstruction) instruction).subtype())) {
log.warn("HP V3 Driver - L4MODIFICATION.subtype {} only supported in SOFTWARE", ((L4ModificationInstruction) instruction).subtype());
hardwareProcess = false;
break;
}
}
// TODO --- check if all the buckets contains one and only one output action
if (instruction.type() == Instruction.Type.GROUP) {
boolean groupInstalled = false;
GroupId groupId = ((Instructions.GroupInstruction) instruction).groupId();
Iterable<Group> groupsOnDevice = groupService.getGroups(deviceId);
for (Group group : groupsOnDevice) {
if ((group.state() == Group.GroupState.ADDED) && (group.id().equals(groupId))) {
groupInstalled = true;
if (group.type() != Group.Type.ALL) {
log.warn("HP V3 Driver - group type {} only supported in SOFTWARE", group.type().toString());
hardwareProcess = false;
}
break;
}
}
if (!groupInstalled) {
log.warn("HP V3 Driver - referenced group is not installed on the device.");
hardwareProcess = false;
}
}
}
}
if (hardwareProcess) {
log.warn("HP V3 Driver - This flow rule is supported in HARDWARE");
return HP_HARDWARE_TABLE;
} else {
// TODO: create a specific flow in table 100 to redirect selected traffic on table 200
log.warn("HP V3 Driver - This flow rule is only supported in SOFTWARE");
return HP_SOFTWARE_TABLE;
}
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class OpenFlowGroupProvider method checkFailoverGroups.
/**
* Builds a list of failover Groups whose primary live bucket failed over
* (i.e. bucket in use has changed).
*
* @param dpid DPID of switch whose port's status changed
* @param status new status of port
* @return list of groups whose primary live bucket failed over
*/
private List<Group> checkFailoverGroups(Dpid dpid, OFPortStatus status) {
List<Group> groupList = new ArrayList<>();
OFPortDesc desc = status.getDesc();
PortNumber portNumber = PortNumber.portNumber(desc.getPortNo().getPortNumber());
DeviceId id = DeviceId.deviceId(Dpid.uri(dpid));
if (desc.isEnabled()) {
return groupList;
}
Iterator<Group> iterator = groupService.getGroups(id).iterator();
while (iterator.hasNext()) {
Group group = iterator.next();
if (group.type() == GroupDescription.Type.FAILOVER && checkFailoverGroup(group, id, portNumber)) {
groupList.add(group);
}
}
return groupList;
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStore method storeGroupDescriptionInternal.
private void storeGroupDescriptionInternal(GroupDescription groupDesc) {
// Check if a group is existing with the same key
if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) {
return;
}
synchronized (deviceAuditStatus) {
if (deviceAuditStatus.get(groupDesc.deviceId()) == null) {
// Device group audit has not completed yet
// Add this group description to pending group key table
// Create a group entry object with Dummy Group ID
log.debug("storeGroupDescriptionInternal: Device {} AUDIT pending...Queuing Group id {} ADD request", groupDesc.deviceId(), groupDesc.givenGroupId() != null ? "0x" + Integer.toHexString(groupDesc.givenGroupId()) : "N/A");
StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc);
group.setState(GroupState.WAITING_AUDIT_COMPLETE);
Map<GroupStoreKeyMapKey, StoredGroupEntry> pendingKeyTable = getPendingGroupKeyTable();
pendingKeyTable.put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
return;
}
}
Group matchingExtraneousGroup = null;
if (groupDesc.givenGroupId() != null) {
// Check if there is a extraneous group existing with the same Id
matchingExtraneousGroup = getMatchingExtraneousGroupbyId(groupDesc.deviceId(), groupDesc.givenGroupId());
if (matchingExtraneousGroup != null) {
log.debug("storeGroupDescriptionInternal: Matching extraneous group " + "found in Device {} for group id 0x{}", groupDesc.deviceId(), Integer.toHexString(groupDesc.givenGroupId()));
// Check if the group buckets matches with user provided buckets
if (matchingExtraneousGroup.buckets().equals(groupDesc.buckets())) {
// Group is already existing with the same buckets and Id
// Create a group entry object
log.debug("storeGroupDescriptionInternal: Buckets also matching " + "in Device {} for group id 0x{}", groupDesc.deviceId(), Integer.toHexString(groupDesc.givenGroupId()));
StoredGroupEntry group = new DefaultGroup(matchingExtraneousGroup.id(), groupDesc);
// Insert the newly created group entry into key and id maps
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(matchingExtraneousGroup.id(), group);
addOrUpdateGroupEntry(matchingExtraneousGroup);
removeExtraneousGroupEntry(matchingExtraneousGroup);
return;
} else {
// Group buckets are not matching. Update group
// with user provided buckets.
log.debug("storeGroupDescriptionInternal: Buckets are not " + "matching in Device {} for group id 0x{}", groupDesc.deviceId(), Integer.toHexString(groupDesc.givenGroupId()));
StoredGroupEntry modifiedGroup = new DefaultGroup(matchingExtraneousGroup.id(), groupDesc);
modifiedGroup.setState(GroupState.PENDING_UPDATE);
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), modifiedGroup);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(matchingExtraneousGroup.id(), modifiedGroup);
removeExtraneousGroupEntry(matchingExtraneousGroup);
log.debug("storeGroupDescriptionInternal: Triggering Group " + "UPDATE request for {} in device {}", matchingExtraneousGroup.id(), groupDesc.deviceId());
notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, modifiedGroup));
return;
}
}
} else {
// Check if there is an extraneous group with user provided buckets
matchingExtraneousGroup = getMatchingExtraneousGroupbyBuckets(groupDesc.deviceId(), groupDesc.buckets());
if (matchingExtraneousGroup != null) {
// Group is already existing with the same buckets.
// So reuse this group.
log.debug("storeGroupDescriptionInternal: Matching extraneous group found in Device {}", groupDesc.deviceId());
// Create a group entry object
StoredGroupEntry group = new DefaultGroup(matchingExtraneousGroup.id(), groupDesc);
// Insert the newly created group entry into key and id maps
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(matchingExtraneousGroup.id(), group);
addOrUpdateGroupEntry(matchingExtraneousGroup);
removeExtraneousGroupEntry(matchingExtraneousGroup);
return;
} else {
// TODO: Check if there are any empty groups that can be used here
log.debug("storeGroupDescriptionInternal: No matching extraneous groups found in Device {}", groupDesc.deviceId());
}
}
GroupId id = null;
if (groupDesc.givenGroupId() == null) {
// Get a new group identifier
id = new GroupId(getFreeGroupIdValue(groupDesc.deviceId()));
} else {
// we need to use the identifier passed in by caller, but check if
// already used
Group existing = getGroup(groupDesc.deviceId(), new GroupId(groupDesc.givenGroupId()));
if (existing != null) {
log.warn("Group already exists with the same id: 0x{} in dev:{} " + "but with different key: {} (request gkey: {})", Integer.toHexString(groupDesc.givenGroupId()), groupDesc.deviceId(), existing.appCookie(), groupDesc.appCookie());
return;
}
id = new GroupId(groupDesc.givenGroupId());
}
// Create a group entry object
StoredGroupEntry group = new DefaultGroup(id, groupDesc);
// Insert the newly created group entry into key and id maps
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(id, group);
log.debug("storeGroupDescriptionInternal: Processing Group ADD request for Id {} in device {}", id, groupDesc.deviceId());
notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, group));
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStore method pushGroupMetrics.
@Override
public void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries) {
boolean deviceInitialAuditStatus = deviceInitialAuditStatus(deviceId);
Set<Group> southboundGroupEntries = Sets.newHashSet(groupEntries);
Set<StoredGroupEntry> storedGroupEntries = Sets.newHashSet(getStoredGroups(deviceId));
Set<Group> extraneousStoredEntries = Sets.newHashSet(getExtraneousGroups(deviceId));
NodeId master;
if (log.isTraceEnabled()) {
log.trace("pushGroupMetrics: Displaying all ({}) southboundGroupEntries for device {}", southboundGroupEntries.size(), deviceId);
for (Group group : southboundGroupEntries) {
log.trace("Group {} in device {}", group, deviceId);
}
log.trace("Displaying all ({}) stored group entries for device {}", storedGroupEntries.size(), deviceId);
for (StoredGroupEntry group : storedGroupEntries) {
log.trace("Stored Group {} for device {}", group, deviceId);
}
}
garbageCollect(deviceId, southboundGroupEntries, storedGroupEntries);
// update stats
for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext(); ) {
// Mastership change can occur during this iteration
if (!shouldHandle(deviceId)) {
log.warn("Tried to update the group stats while the node was not the master" + " or the device {} was not available", deviceId);
return;
}
Group group = it2.next();
if (storedGroupEntries.remove(group)) {
// we both have the group, let's update some info then.
log.trace("Group AUDIT: group {} exists in both planes for device {}", group.id(), deviceId);
groupAdded(group);
it2.remove();
}
}
// extraneous groups in the dataplane
for (Group group : southboundGroupEntries) {
if (getGroup(group.deviceId(), group.id()) != null) {
// in progress while we got a stale info from switch
if (!storedGroupEntries.remove(getGroup(group.deviceId(), group.id()))) {
log.warn("Group AUDIT: Inconsistent state:" + "Group exists in ID based table while " + "not present in key based table");
}
} else {
// Mastership change can occur during this iteration
if (!shouldHandle(deviceId)) {
log.warn("Tried to process extraneous groups while the node was not the master" + " or the device {} was not available", deviceId);
return;
}
// there are groups in the switch that aren't in the store
log.debug("Group AUDIT: extraneous group {} exists in data plane for device {}", group.id(), deviceId);
extraneousStoredEntries.remove(group);
if (allowExtraneousGroups) {
extraneousGroup(group);
} else {
notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, group));
}
}
}
// missing groups in the dataplane
for (StoredGroupEntry group : storedGroupEntries) {
// Mastership change can occur during this iteration
if (!shouldHandle(deviceId)) {
log.warn("Tried to process missing groups while the node was not the master" + " or the device {} was not available", deviceId);
return;
}
// there are groups in the store that aren't in the switch
log.debug("Group AUDIT: group {} missing in data plane for device {}", group.id(), deviceId);
groupMissing(group);
}
// extraneous groups in the store
for (Group group : extraneousStoredEntries) {
// Mastership change can occur during this iteration
if (!shouldHandle(deviceId)) {
log.warn("Tried to process node extraneous groups while the node was not the master" + " or the device {} was not available", deviceId);
return;
}
// there are groups in the extraneous store that
// aren't in the switch
log.debug("Group AUDIT: clearing extraneous group {} from store for device {}", group.id(), deviceId);
removeExtraneousGroupEntry(group);
}
if (!deviceInitialAuditStatus) {
log.info("Group AUDIT: Setting device {} initial AUDIT completed", deviceId);
deviceInitialAuditCompleted(deviceId, true);
}
}
Aggregations