use of org.onosproject.net.flowobjective.ObjectiveError in project onos by opennetworkinglab.
the class PacketManager method pushRule.
/**
* Pushes packet intercept flow rules to the device.
*
* @param device the device to push the rules to
* @param request the packet request
*/
private void pushRule(Device device, PacketRequest request) {
if (!device.type().equals(Device.Type.SWITCH)) {
return;
}
if (!deviceService.isAvailable(device.id())) {
return;
}
ForwardingObjective forwarding = createBuilder(request).add(new ObjectiveContext() {
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to install packet request {} to {}: {}", request, device.id(), error);
}
});
objectiveService.forward(device.id(), forwarding);
}
use of org.onosproject.net.flowobjective.ObjectiveError in project onos by opennetworkinglab.
the class FabricPipeliner method handleVerify.
private ObjectiveError handleVerify(NextObjective nextObjective) {
Map<GroupBucket, FlowRule> bucketsToFlows = getBucketToFlowMapping(nextObjective);
if (bucketsToFlows.isEmpty() && !nextObjective.nextTreatments().isEmpty()) {
log.warn("VERIFY failed due to translation error, bucketsToFlows is empty");
return ObjectiveError.BADPARAMS;
}
if (log.isTraceEnabled()) {
log.trace("Mapping bucketsToFlows {} has been generated ", bucketsToFlows);
}
GroupKey groupKey = nextTranslator.getGroupKey(nextObjective);
if (groupKey == null) {
log.warn("VERIFY failed due to translation error, unable to determine group key");
return ObjectiveError.BADPARAMS;
}
Group groupFromStore = groupService.getGroup(deviceId, groupKey);
if (groupFromStore == null) {
log.warn("VERIFY failed due to missing group in the store");
return ObjectiveError.GROUPMISSING;
}
// Looking for duplicate buckets - remove them by using a set and comparing size after/before
Set<GroupBucket> bucketsFromStore = Sets.newHashSet(groupFromStore.buckets().buckets());
if (groupFromStore.buckets().buckets().size() > bucketsFromStore.size()) {
log.warn("Duplicated buckets detected in device:{}, nextId:{}, before-size" + ":{} after-size:{} .. correcting", deviceId, nextObjective.id(), groupFromStore.buckets().buckets().size(), bucketsFromStore.size());
final GroupBuckets bucketToSet = new GroupBuckets(Lists.newArrayList(bucketsFromStore));
groupService.setBucketsForGroup(deviceId, groupKey, bucketToSet, groupKey, nextObjective.appId());
// Forge temporary the group to avoid race condition with the store
groupFromStore = new DefaultGroup(groupFromStore.id(), deviceId, groupFromStore.type(), bucketToSet);
}
// Looking for buckets missing in the group but defined in the next
Map<GroupBucket, FlowRule> toAdd = Maps.newHashMap();
for (Map.Entry<GroupBucket, FlowRule> entry : bucketsToFlows.entrySet()) {
if (!groupFromStore.buckets().buckets().contains(entry.getKey())) {
toAdd.put(entry.getKey(), entry.getValue());
}
}
// Looking for buckets missing in the next but defined in the group
// FIXME SDFAB-250 we cannot remove associated egress flows
List<GroupBucket> toRemove = Lists.newArrayList();
groupFromStore.buckets().buckets().forEach(bucket -> {
if (!bucketsToFlows.containsKey(bucket)) {
toRemove.add(bucket);
}
});
if (!toAdd.isEmpty() || !toRemove.isEmpty()) {
log.warn("Mismatch detected in device:{}, nextId:{}, groupFromTranslation-size:{} " + "groupFromStore-size:{} toAdd-size:{} toRemove-size: {} .. correcting", deviceId, nextObjective.id(), bucketsToFlows.size(), groupFromStore.buckets().buckets().size(), toAdd.size(), toRemove.size());
}
if (!toAdd.isEmpty()) {
if (log.isTraceEnabled()) {
log.trace("Adding missing buckets {} and flows {}", toAdd.keySet(), toAdd.values());
}
final FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
final FlowRule dummyFlow = getDummyFlow(nextObjective);
toAdd.values().stream().filter(flowRule -> !flowRule.equals(dummyFlow)).forEach(ops::add);
final GroupBuckets bucketsToAdd = new GroupBuckets(Lists.newArrayList(toAdd.keySet()));
groupService.addBucketsToGroup(deviceId, groupKey, bucketsToAdd, groupKey, nextObjective.appId());
flowRuleService.apply(ops.build());
}
if (!toRemove.isEmpty()) {
if (log.isTraceEnabled()) {
log.trace("Removing stale buckets {}", toRemove);
}
final GroupBuckets bucketsToRemove = new GroupBuckets(toRemove);
groupService.removeBucketsFromGroup(deviceId, groupKey, bucketsToRemove, groupKey, nextObjective.appId());
}
return null;
}
use of org.onosproject.net.flowobjective.ObjectiveError in project onos by opennetworkinglab.
the class InOrderFlowObjectiveManager method dequeue.
/**
* Dequeue flow objective. Execute the next flow objective in the queue, if any.
*
* @param deviceId Device ID
* @param obj Flow objective
* @param error ObjectiveError that triggers this dequeue. Null if this is not triggered by an error.
*/
private synchronized void dequeue(DeviceId deviceId, Objective obj, ObjectiveError error) {
List<Objective> remaining;
int priority = obj.priority();
LogLevel logLevel = (obj.op() == Objective.Operation.VERIFY) ? LogLevel.TRACE : LogLevel.DEBUG;
Tools.log(log, logLevel, "Dequeue {}", obj);
if (obj instanceof FilteringObjective) {
FilteringObjQueueKey k = new FilteringObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
if (!Objects.equals(ObjectiveError.INSTALLATIONTIMEOUT, error)) {
filtObjQueueHead.invalidate(k);
}
filtObjQueue.remove(k, obj);
remaining = filtObjQueue.get(k);
} else if (obj instanceof ForwardingObjective) {
ForwardingObjQueueKey k = new ForwardingObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
if (!Objects.equals(ObjectiveError.INSTALLATIONTIMEOUT, error)) {
fwdObjQueueHead.invalidate(k);
}
fwdObjQueue.remove(k, obj);
remaining = fwdObjQueue.get(k);
} else if (obj instanceof NextObjective) {
if (error != null) {
// Remove pendingForwards and pendingNexts if next objective failed
Set<PendingFlowObjective> removedForwards = pendingForwards.remove(obj.id());
List<PendingFlowObjective> removedNexts = pendingNexts.remove(obj.id());
if (removedForwards != null) {
removedForwards.stream().map(PendingFlowObjective::flowObjective).forEach(pendingObj -> pendingObj.context().ifPresent(c -> c.onError(pendingObj, error)));
}
if (removedNexts != null) {
removedNexts.stream().map(PendingFlowObjective::flowObjective).forEach(pendingObj -> pendingObj.context().ifPresent(c -> c.onError(pendingObj, error)));
}
}
NextObjQueueKey k = new NextObjQueueKey(deviceId, obj.id());
if (!Objects.equals(ObjectiveError.INSTALLATIONTIMEOUT, error)) {
nextObjQueueHead.invalidate(k);
}
nextObjQueue.remove(k, obj);
remaining = nextObjQueue.get(k);
} else {
log.error("Unknown flow objective instance: {}", obj.getClass().getName());
return;
}
log.trace("{} queue size {}", obj.getClass().getSimpleName(), remaining.size());
// Submit the next one in the queue, if any
if (remaining.size() > 0) {
execute(deviceId, remaining.get(0));
}
}
use of org.onosproject.net.flowobjective.ObjectiveError in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method processIgnoreVlanRule.
/**
* Process the ignore rules.
*
* @param deviceId the device id
* @param vlanId the vlan to be ignored
* @param op the operation, ADD to install; REMOVE to uninstall rules
*/
private void processIgnoreVlanRule(DeviceId deviceId, VlanId vlanId, Objective.Operation op) {
AtomicInteger installedCount = new AtomicInteger(DHCP_SELECTORS.size());
DHCP_SELECTORS.forEach(trafficSelector -> {
TrafficSelector selector = DefaultTrafficSelector.builder(trafficSelector).matchVlanId(vlanId).build();
ForwardingObjective.Builder builder = DefaultForwardingObjective.builder().withFlag(ForwardingObjective.Flag.VERSATILE).withSelector(selector).withPriority(IGNORE_CONTROL_PRIORITY).withTreatment(DefaultTrafficTreatment.emptyTreatment()).fromApp(appId);
ObjectiveContext objectiveContext = new ObjectiveContext() {
@Override
public void onSuccess(Objective objective) {
log.info("Ignore rule {} (Vlan id {}, device {}, selector {})", op, vlanId, deviceId, selector);
int countDown = installedCount.decrementAndGet();
if (countDown != 0) {
return;
}
switch(op) {
case ADD:
ignoredVlans.put(deviceId, vlanId);
break;
case REMOVE:
ignoredVlans.remove(deviceId, vlanId);
break;
default:
log.warn("Unsupported objective operation {}", op);
break;
}
}
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Can't {} ignore rule (vlan id {}, selector {}, device {}) due to {}", op, vlanId, selector, deviceId, error);
}
};
ForwardingObjective fwd;
switch(op) {
case ADD:
fwd = builder.add(objectiveContext);
break;
case REMOVE:
fwd = builder.remove(objectiveContext);
break;
default:
log.warn("Unsupported objective operation {}", op);
return;
}
Device device = deviceService.getDevice(deviceId);
if (device == null || !device.is(Pipeliner.class)) {
log.warn("Device {} is not available now, wait until device is available", deviceId);
return;
}
flowObjectiveService.apply(deviceId, fwd);
});
}
use of org.onosproject.net.flowobjective.ObjectiveError in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processIgnoreVlanRule.
/**
* Process the ignore rules.
*
* @param deviceId the device id
* @param vlanId the vlan to be ignored
* @param op the operation, ADD to install; REMOVE to uninstall rules
*/
private void processIgnoreVlanRule(DeviceId deviceId, VlanId vlanId, Objective.Operation op) {
AtomicInteger installedCount = new AtomicInteger(DHCP_SELECTORS.size());
DHCP_SELECTORS.forEach(trafficSelector -> {
TrafficSelector selector = DefaultTrafficSelector.builder(trafficSelector).matchVlanId(vlanId).build();
ForwardingObjective.Builder builder = DefaultForwardingObjective.builder().withFlag(ForwardingObjective.Flag.VERSATILE).withSelector(selector).withPriority(IGNORE_CONTROL_PRIORITY).withTreatment(DefaultTrafficTreatment.emptyTreatment()).fromApp(appId);
ObjectiveContext objectiveContext = new ObjectiveContext() {
@Override
public void onSuccess(Objective objective) {
log.info("Ignore rule {} (Vlan id {}, device {}, selector {})", op, vlanId, deviceId, selector);
int countDown = installedCount.decrementAndGet();
if (countDown != 0) {
return;
}
switch(op) {
case ADD:
ignoredVlans.put(deviceId, vlanId);
break;
case REMOVE:
ignoredVlans.remove(deviceId, vlanId);
break;
default:
log.warn("Unsupported objective operation {}", op);
break;
}
}
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Can't {} ignore rule (vlan id {}, selector {}, device {}) due to {}", op, vlanId, selector, deviceId, error);
}
};
ForwardingObjective fwd;
switch(op) {
case ADD:
fwd = builder.add(objectiveContext);
break;
case REMOVE:
fwd = builder.remove(objectiveContext);
break;
default:
log.warn("Unsupported objective operation {}", op);
return;
}
Device device = deviceService.getDevice(deviceId);
if (device == null || !device.is(Pipeliner.class)) {
log.warn("Device {} is not available now, wait until device is available", deviceId);
return;
}
flowObjectiveService.apply(deviceId, fwd);
});
}
Aggregations