public static int forwardingObjectiveHash(ForwardingObjective forwardingObjective) { return Objects.hash(forwardingObjective.selector(), forwardingObjective.flag(), forwardingObjective.permanent(), forwardingObjective.timeout(), forwardingObjective.appId(), forwardingObjective.priority(), forwardingObjective.nextId(), forwardingObjective.treatment()); } }
@Override public ObjectNode encode(ForwardingObjective forwardingObjective, CodecContext context) { checkNotNull(forwardingObjective, NOT_NULL_MESSAGE); final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class); final JsonCodec<TrafficSelector> trafficSelectorCodec = context.codec(TrafficSelector.class); // encode common properties ObjectiveCodecHelper och = new ObjectiveCodecHelper(); ObjectNode result = och.encode(forwardingObjective, context); // encode id result.put(ID, forwardingObjective.id()); // encode flag result.put(FLAG, forwardingObjective.flag().toString()); // encode op result.put(OPERATION, forwardingObjective.op().toString()); // encode selector ObjectNode trafficSelectorNode = trafficSelectorCodec.encode(forwardingObjective.selector(), context); result.set(SELECTOR, trafficSelectorNode); // encode nextId if (forwardingObjective.nextId() != null) { result.put(NEXT_ID, forwardingObjective.nextId()); } // encode treatment if (forwardingObjective.treatment() != null) { ObjectNode trafficTreatmentNode = trafficTreatmentCodec.encode(forwardingObjective.treatment(), context); result.set(TREATMENT, trafficTreatmentNode); } return result; }
public static String forwardingObjectiveToString(ForwardingObjective forwardingObjective) { String str = forwardingObjective.priority() + " "; str += "selector( "; for (Criterion criterion : forwardingObjective.selector().criteria()) { str += criterion + " "; } str += ") treatment( "; for (Instruction instruction : forwardingObjective.treatment().allInstructions()) { str += instruction + " "; } str += ")"; return str; }
boolean queueFwdObjective(DeviceId deviceId, ForwardingObjective fwd) { boolean queued = false; synchronized (pendingForwards) { // double check the flow objective store, because this block could run // after a notification arrives if (flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { pendingForwards.compute(fwd.nextId(), (id, pending) -> { PendingFlowObjective pendfo = new PendingFlowObjective(deviceId, fwd); if (pending == null) { return Sets.newLinkedHashSet(ImmutableSet.of(pendfo)); } else { pending.add(pendfo); return pending; } }); queued = true; } } if (queued) { log.debug("Queued forwarding objective {} for nextId {} meant for device {}", fwd.id(), fwd.nextId(), deviceId); } return queued; }
public static ForwardingObjective composeOverride(ForwardingObjective fo, int priorityAddend) { return DefaultForwardingObjective.builder() .fromApp(fo.appId()) .makePermanent() .withFlag(fo.flag()) .withPriority(fo.priority() + priorityAddend) .withSelector(fo.selector()) .withTreatment(fo.treatment()) .add(); }
private void processMulticastRule(ForwardingObjective fwd) { if (fwd.nextId() == null) { log.error("Multicast objective does not have a next id"); fail(fwd, ObjectiveError.BADPARAMS); GroupKey key = getGroupForNextObjective(fwd.nextId()); .fromApp(fwd.appId()) .forDevice(deviceId) .forTable(0) .makePermanent() .withPriority(fwd.priority()) .withSelector(fwd.selector()) .withTreatment(treatment) .build(); switch (fwd.op()) { break; default: log.warn("Unknown forwarding operation: {}", fwd.op());
.fromApp(fwd.appId()) .forDevice(deviceId) .makePermanent() .withPriority(fwd.priority()) .withSelector(fwd.selector()) .withTreatment(buildTreatment(innerPair.getRight(), Instructions.transition(QQ_TABLE))); fwd.selector().getCriterion(Criterion.Type.IN_PORT); .fromApp(fwd.appId()) .forDevice(deviceId) .forTable(QQ_TABLE) .makePermanent() .withPriority(fwd.priority()) .withSelector(buildSelector(inPort, Criteria.matchVlanId(cVlanId)))
private boolean isSupportedEthDstObjective(ForwardingObjective fwd) { TrafficSelector selector = fwd.selector(); EthCriterion ethDst = (EthCriterion) selector .getCriterion(Criterion.Type.ETH_DST); VlanIdCriterion vlanId = (VlanIdCriterion) selector .getCriterion(Criterion.Type.VLAN_VID); return !(ethDst == null && vlanId == null); }
public ForwardUpdateTable updateForward(ForwardingObjective forwardingObjective) { ForwardUpdateTable updates = new ForwardUpdateTable(); switch (forwardingObjective.op()) { case ADD: this.forwardMap.put(forwardingObjectiveHash(forwardingObjective), forwardingObjective); this.generatedParentForwardingObjectiveMap .put(forwardingObjectiveHash(forwardingObjective), new ArrayList<>()); updates.addObjectives.add(forwardingObjective); break; case REMOVE: if (this.forwardMap.remove(forwardingObjectiveHash(forwardingObjective)) != null) { updates.removeObjectives.add(forwardingObjective); } break; default: break; } return updates; }
private Collection<FlowRule> processForward(ForwardingObjective fwd) { switch (fwd.flag()) { case SPECIFIC: return processSpecific(fwd); case VERSATILE: return processVersatile(fwd); default: fail(fwd, ObjectiveError.UNKNOWN); log.warn("Unknown forwarding flag {}", fwd.flag()); } return Collections.emptySet(); }
private Instruction fetchOutput(ForwardingObjective fwd, String direction) { Instruction output = fwd.treatment().allInstructions().stream() .filter(i -> i.type() == Instruction.Type.OUTPUT) .findFirst().orElse(null); if (output == null) { log.error("OLT {} rule has no output", direction); fail(fwd, ObjectiveError.BADPARAMS); return null; } return output; }
private boolean queueObjective(DeviceId deviceId, ForwardingObjective fwd) { if (fwd.nextId() != null && flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); if (pendingForwards.putIfAbsent(fwd.nextId(), Sets.newHashSet(new PendingNext(deviceId, fwd))) != null) { Set<PendingNext> pending = pendingForwards.get(fwd.nextId()); pending.add(new PendingNext(deviceId, fwd)); } return true; } return false; }
public static Collection<ForwardingObjective> minusForwardingObjectives(Collection<ForwardingObjective> fo1, Collection<ForwardingObjective> fo2) { Map<Integer, ForwardingObjective> map = new HashMap<>(); for (ForwardingObjective fo : fo1) { map.put(fo.id(), fo); } for (ForwardingObjective fo : fo2) { map.remove(fo.id()); } return map.values(); }
public ForwardUpdateTable updateForwardNode(ForwardingObjective forwardingObjective) { switch (this.operator) { case Parallel: case Sequential: case Override: return updateForwardComposition(forwardingObjective); case Application: if (forwardingObjective.appId().id() == this.applicationId) { return this.forwardTable.updateForward(forwardingObjective); } else { return (new ForwardUpdateTable()); } default: return (new ForwardUpdateTable()); } }
public static ForwardingObjective composeParallel(ForwardingObjective fo1, ForwardingObjective fo2) { TrafficSelector trafficSelector = intersectTrafficSelector(fo1.selector(), fo2.selector()); if (trafficSelector == null) { return null; } TrafficTreatment trafficTreatment = unionTrafficTreatment(fo1.treatment(), fo2.treatment()); return DefaultForwardingObjective.builder() .fromApp(fo1.appId()) .makePermanent() .withFlag(ForwardingObjective.Flag.VERSATILE) .withPriority(fo1.priority() + fo2.priority()) .withSelector(trafficSelector) .withTreatment(trafficTreatment) .add(); }
/** * In the OF-DPA 2.0 pipeline, specific forwarding refers to the IP table * (unicast or multicast) or the L2 table (mac + vlan) or the MPLS table. * * @param fwd the forwarding objective of type 'specific' * @return a collection of flow rules. Typically there will be only one * for this type of forwarding objective. An empty set may be * returned if there is an issue in processing the objective. */ protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) { log.debug("Processing specific fwd objective:{} in dev:{} with next:{}", fwd.id(), deviceId, fwd.nextId()); boolean isEthTypeObj = isSupportedEthTypeObjective(fwd); boolean isEthDstObj = isSupportedEthDstObjective(fwd); if (isEthTypeObj) { return processEthTypeSpecific(fwd); } else if (isEthDstObj) { return processEthDstSpecific(fwd); } else { log.warn("processSpecific: Unsupported forwarding objective " + "criteria fwd:{} in dev:{}", fwd.nextId(), deviceId); fail(fwd, ObjectiveError.UNSUPPORTED); return Collections.emptySet(); } }
TrafficSelector selector = fwd.selector(); .fromApp(fwd.appId()) .forDevice(deviceId) .makePermanent() .withPriority(fwd.priority()) .withSelector(buildSelector(inport, outerVlan, bullshit)) .withTreatment(buildTreatment(popAndRewrite.getLeft(), .fromApp(fwd.appId()) .forDevice(deviceId) .forTable(QQ_TABLE) .makePermanent() .withPriority(fwd.priority()) .withSelector(buildSelector(inport, innerVid)) .withTreatment(buildTreatment(popAndRewrite.getLeft(),
private boolean isSupportedEthDstObjective(ForwardingObjective fwd) { TrafficSelector selector = fwd.selector(); EthCriterion ethDst = (EthCriterion) selector .getCriterion(Criterion.Type.ETH_DST); VlanIdCriterion vlanId = (VlanIdCriterion) selector .getCriterion(Criterion.Type.VLAN_VID); if (ethDst == null && vlanId == null) { return false; } return true; }