mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-18 10:51:04 +02:00
Add support for vlan based intents in the Corsa driver
Changes: - Improves processSpecific in AbstractCorsaPipeline in order to support Intents without an explicit match on the Ethertype; - Implements vlan based circuits in CorsaPipelineV3 through the management of the FwdObjective without Treatment; - Distinguish Groups from simple actions; - Corsa group are identified using the actions of the treatment; - handling of the pending next similar to DefaultSingleTablePipeline Change-Id: Iff0f70d56c64193524c6640f31ffb3f5629499dc
This commit is contained in:
parent
f97e13d0a1
commit
db67355aaf
@ -93,14 +93,14 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
private ServiceDirectory serviceDirectory;
|
private ServiceDirectory serviceDirectory;
|
||||||
protected FlowRuleService flowRuleService;
|
protected FlowRuleService flowRuleService;
|
||||||
private CoreService coreService;
|
private CoreService coreService;
|
||||||
private GroupService groupService;
|
protected GroupService groupService;
|
||||||
protected MeterService meterService;
|
protected MeterService meterService;
|
||||||
private FlowObjectiveStore flowObjectiveStore;
|
protected FlowObjectiveStore flowObjectiveStore;
|
||||||
protected DeviceId deviceId;
|
protected DeviceId deviceId;
|
||||||
protected ApplicationId appId;
|
protected ApplicationId appId;
|
||||||
protected DeviceService deviceService;
|
protected DeviceService deviceService;
|
||||||
|
|
||||||
private KryoNamespace appKryo = new KryoNamespace.Builder()
|
protected KryoNamespace appKryo = new KryoNamespace.Builder()
|
||||||
.register(GroupKey.class)
|
.register(GroupKey.class)
|
||||||
.register(DefaultGroupKey.class)
|
.register(DefaultGroupKey.class)
|
||||||
.register(CorsaGroup.class)
|
.register(CorsaGroup.class)
|
||||||
@ -108,6 +108,8 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
.build("AbstractCorsaPipeline");
|
.build("AbstractCorsaPipeline");
|
||||||
|
|
||||||
private Cache<GroupKey, NextObjective> pendingGroups;
|
private Cache<GroupKey, NextObjective> pendingGroups;
|
||||||
|
protected Cache<Integer, NextObjective> pendingNext;
|
||||||
|
|
||||||
|
|
||||||
private ScheduledExecutorService groupChecker =
|
private ScheduledExecutorService groupChecker =
|
||||||
Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner",
|
Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner",
|
||||||
@ -131,6 +133,16 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
}
|
}
|
||||||
}).build();
|
}).build();
|
||||||
|
|
||||||
|
pendingNext = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterWrite(20, TimeUnit.SECONDS)
|
||||||
|
.removalListener((RemovalNotification<Integer, NextObjective> notification) -> {
|
||||||
|
if (notification.getCause() == RemovalCause.EXPIRED) {
|
||||||
|
notification.getValue().context()
|
||||||
|
.ifPresent(c -> c.onError(notification.getValue(),
|
||||||
|
ObjectiveError.FLOWINSTALLATIONFAILED));
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
|
||||||
groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS);
|
groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
coreService = serviceDirectory.get(CoreService.class);
|
coreService = serviceDirectory.get(CoreService.class);
|
||||||
@ -304,6 +316,7 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forward(ForwardingObjective fwd) {
|
public void forward(ForwardingObjective fwd) {
|
||||||
|
|
||||||
Collection<FlowRule> rules;
|
Collection<FlowRule> rules;
|
||||||
FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
|
FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
|
||||||
|
|
||||||
@ -354,16 +367,20 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
|
private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
|
||||||
log.debug("Processing specific forwarding objective");
|
log.debug("Processing specific forwarding objective");
|
||||||
TrafficSelector selector = fwd.selector();
|
TrafficSelector selector = fwd.selector();
|
||||||
EthTypeCriterion ethType =
|
EthTypeCriterion ethTypeCriterion =
|
||||||
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
|
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
|
||||||
if (ethType != null) {
|
VlanIdCriterion vlanIdCriterion =
|
||||||
short et = ethType.ethType().toShort();
|
(VlanIdCriterion) selector.getCriterion(Criterion.Type.VLAN_VID);
|
||||||
|
if (ethTypeCriterion != null) {
|
||||||
|
short et = ethTypeCriterion.ethType().toShort();
|
||||||
if (et == Ethernet.TYPE_IPV4) {
|
if (et == Ethernet.TYPE_IPV4) {
|
||||||
return processSpecificRoute(fwd);
|
return processSpecificRoute(fwd);
|
||||||
} else if (et == Ethernet.TYPE_VLAN) {
|
} else if (et == Ethernet.TYPE_VLAN) {
|
||||||
/* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */
|
/* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */
|
||||||
return processSpecificSwitch(fwd);
|
return processSpecificSwitch(fwd);
|
||||||
}
|
}
|
||||||
|
} else if (vlanIdCriterion != null) {
|
||||||
|
return processSpecificSwitch(fwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fail(fwd, ObjectiveError.UNSUPPORTED);
|
fail(fwd, ObjectiveError.UNSUPPORTED);
|
||||||
@ -464,6 +481,41 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
//Hook for modifying Route flow rule
|
//Hook for modifying Route flow rule
|
||||||
protected abstract Builder processSpecificRoutingRule(Builder rb);
|
protected abstract Builder processSpecificRoutingRule(Builder rb);
|
||||||
|
|
||||||
|
protected enum CorsaTrafficTreatmentType {
|
||||||
|
/**
|
||||||
|
* If the treatment has to be handled as group.
|
||||||
|
*/
|
||||||
|
GROUP,
|
||||||
|
/**
|
||||||
|
* If the treatment has to be handled as simple set of actions.
|
||||||
|
*/
|
||||||
|
ACTIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to encapsulate both traffic treatment and
|
||||||
|
* type of treatment.
|
||||||
|
*/
|
||||||
|
protected class CorsaTrafficTreatment {
|
||||||
|
|
||||||
|
private CorsaTrafficTreatmentType type;
|
||||||
|
private TrafficTreatment trafficTreatment;
|
||||||
|
|
||||||
|
public CorsaTrafficTreatment(CorsaTrafficTreatmentType treatmentType, TrafficTreatment trafficTreatment) {
|
||||||
|
this.type = treatmentType;
|
||||||
|
this.trafficTreatment = trafficTreatment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CorsaTrafficTreatmentType type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TrafficTreatment treatment() {
|
||||||
|
return trafficTreatment;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void next(NextObjective nextObjective) {
|
public void next(NextObjective nextObjective) {
|
||||||
switch (nextObjective.type()) {
|
switch (nextObjective.type()) {
|
||||||
@ -471,20 +523,25 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
Collection<TrafficTreatment> treatments = nextObjective.next();
|
Collection<TrafficTreatment> treatments = nextObjective.next();
|
||||||
if (treatments.size() == 1) {
|
if (treatments.size() == 1) {
|
||||||
TrafficTreatment treatment = treatments.iterator().next();
|
TrafficTreatment treatment = treatments.iterator().next();
|
||||||
treatment = processNextTreatment(treatment);
|
CorsaTrafficTreatment corsaTreatment = processNextTreatment(treatment);
|
||||||
GroupBucket bucket =
|
|
||||||
DefaultGroupBucket.createIndirectGroupBucket(treatment);
|
|
||||||
final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
|
final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
|
||||||
GroupDescription groupDescription
|
if (corsaTreatment.type() == CorsaTrafficTreatmentType.GROUP) {
|
||||||
= new DefaultGroupDescription(deviceId,
|
GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(corsaTreatment.treatment());
|
||||||
GroupDescription.Type.INDIRECT,
|
GroupBuckets buckets = new GroupBuckets(Collections.singletonList(bucket));
|
||||||
new GroupBuckets(Collections
|
// group id == null, let group service determine group id
|
||||||
.singletonList(bucket)),
|
GroupDescription groupDescription = new DefaultGroupDescription(deviceId,
|
||||||
key,
|
GroupDescription.Type.INDIRECT,
|
||||||
null, // let group service determine group id
|
buckets,
|
||||||
nextObjective.appId());
|
key,
|
||||||
groupService.addGroup(groupDescription);
|
null,
|
||||||
pendingGroups.put(key, nextObjective);
|
nextObjective.appId());
|
||||||
|
groupService.addGroup(groupDescription);
|
||||||
|
pendingGroups.put(key, nextObjective);
|
||||||
|
} else if (corsaTreatment.type() == CorsaTrafficTreatmentType.ACTIONS) {
|
||||||
|
pendingNext.put(nextObjective.id(), nextObjective);
|
||||||
|
flowObjectiveStore.putNextGroup(nextObjective.id(), new CorsaGroup(key));
|
||||||
|
nextObjective.context().ifPresent(context -> context.onSuccess(nextObjective));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HASHED:
|
case HASHED:
|
||||||
@ -501,8 +558,8 @@ public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Hook for altering the NextObjective treatment
|
//Hook for altering the NextObjective treatment
|
||||||
protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
|
protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) {
|
||||||
return treatment;
|
return new CorsaTrafficTreatment(CorsaTrafficTreatmentType.GROUP, treatment);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Init helper: Table Miss = Drop
|
//Init helper: Table Miss = Drop
|
||||||
|
@ -30,9 +30,12 @@ import org.onosproject.net.flow.criteria.EthCriterion;
|
|||||||
import org.onosproject.net.flow.criteria.IPCriterion;
|
import org.onosproject.net.flow.criteria.IPCriterion;
|
||||||
import org.onosproject.net.flow.criteria.PortCriterion;
|
import org.onosproject.net.flow.criteria.PortCriterion;
|
||||||
import org.onosproject.net.flow.criteria.VlanIdCriterion;
|
import org.onosproject.net.flow.criteria.VlanIdCriterion;
|
||||||
|
import org.onosproject.net.flow.instructions.Instruction;
|
||||||
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
|
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
|
||||||
import org.onosproject.net.flowobjective.FilteringObjective;
|
import org.onosproject.net.flowobjective.FilteringObjective;
|
||||||
import org.onosproject.net.flowobjective.ForwardingObjective;
|
import org.onosproject.net.flowobjective.ForwardingObjective;
|
||||||
|
import org.onosproject.net.flowobjective.NextObjective;
|
||||||
|
import org.onosproject.net.flowobjective.ObjectiveError;
|
||||||
import org.onosproject.net.meter.Band;
|
import org.onosproject.net.meter.Band;
|
||||||
import org.onosproject.net.meter.DefaultBand;
|
import org.onosproject.net.meter.DefaultBand;
|
||||||
import org.onosproject.net.meter.DefaultMeterRequest;
|
import org.onosproject.net.meter.DefaultMeterRequest;
|
||||||
@ -69,9 +72,11 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline {
|
|||||||
protected MeterId defaultMeterId = null;
|
protected MeterId defaultMeterId = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
|
protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) {
|
||||||
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
|
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
treatment.immediate().stream()
|
treatment.immediate().stream()
|
||||||
.filter(i -> {
|
.filter(i -> {
|
||||||
switch (i.type()) {
|
switch (i.type()) {
|
||||||
@ -87,7 +92,48 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}).forEach(i -> tb.add(i));
|
}).forEach(i -> tb.add(i));
|
||||||
return tb.build();
|
|
||||||
|
TrafficTreatment t = tb.build();
|
||||||
|
|
||||||
|
|
||||||
|
boolean isPresentModVlanId = false;
|
||||||
|
boolean isPresentModEthSrc = false;
|
||||||
|
boolean isPresentModEthDst = false;
|
||||||
|
boolean isPresentOutpuPort = false;
|
||||||
|
|
||||||
|
for (Instruction instruction : t.immediate()) {
|
||||||
|
switch (instruction.type()) {
|
||||||
|
case L2MODIFICATION:
|
||||||
|
L2ModificationInstruction l2i = (L2ModificationInstruction) instruction;
|
||||||
|
if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction) {
|
||||||
|
isPresentModVlanId = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
|
||||||
|
L2ModificationInstruction.L2SubType subType = l2i.subtype();
|
||||||
|
if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC)) {
|
||||||
|
isPresentModEthSrc = true;
|
||||||
|
} else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST)) {
|
||||||
|
isPresentModEthDst = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case OUTPUT:
|
||||||
|
isPresentOutpuPort = true;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CorsaTrafficTreatmentType type = CorsaTrafficTreatmentType.ACTIONS;
|
||||||
|
/**
|
||||||
|
* This represents the allowed group for CorsaPipelinev3
|
||||||
|
*/
|
||||||
|
if (isPresentModVlanId &&
|
||||||
|
isPresentModEthSrc &&
|
||||||
|
isPresentModEthDst &&
|
||||||
|
isPresentOutpuPort) {
|
||||||
|
type = CorsaTrafficTreatmentType.GROUP;
|
||||||
|
}
|
||||||
|
CorsaTrafficTreatment corsaTreatment = new CorsaTrafficTreatment(type, t);
|
||||||
|
return corsaTreatment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,9 +161,37 @@ public class CorsaPipelineV3 extends AbstractCorsaPipeline {
|
|||||||
.withPriority(fwd.priority())
|
.withPriority(fwd.priority())
|
||||||
.forDevice(deviceId)
|
.forDevice(deviceId)
|
||||||
.withSelector(filteredSelector)
|
.withSelector(filteredSelector)
|
||||||
.withTreatment(fwd.treatment())
|
|
||||||
.forTable(VLAN_CIRCUIT_TABLE);
|
.forTable(VLAN_CIRCUIT_TABLE);
|
||||||
|
|
||||||
|
if (fwd.treatment() != null) {
|
||||||
|
ruleBuilder.withTreatment(fwd.treatment());
|
||||||
|
} else {
|
||||||
|
if (fwd.nextId() != null) {
|
||||||
|
NextObjective nextObjective = pendingNext.getIfPresent(fwd.nextId());
|
||||||
|
if (nextObjective != null) {
|
||||||
|
pendingNext.invalidate(fwd.nextId());
|
||||||
|
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
|
||||||
|
.setVlanPcp((byte) 0)
|
||||||
|
.setQueue(0)
|
||||||
|
.meter(defaultMeterId);
|
||||||
|
nextObjective.next().forEach(trafficTreatment -> {
|
||||||
|
trafficTreatment.allInstructions().forEach(instruction -> {
|
||||||
|
treatment.add(instruction);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ruleBuilder.withTreatment(treatment.build());
|
||||||
|
} else {
|
||||||
|
log.warn("The group left!");
|
||||||
|
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING));
|
||||||
|
return ImmutableSet.of();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Missing NextObjective ID for ForwardingObjective {}", fwd.id());
|
||||||
|
fail(fwd, ObjectiveError.BADPARAMS);
|
||||||
|
return ImmutableSet.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fwd.permanent()) {
|
if (fwd.permanent()) {
|
||||||
ruleBuilder.makePermanent();
|
ruleBuilder.makePermanent();
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,6 +29,7 @@ import org.onosproject.net.flow.TrafficTreatment;
|
|||||||
import org.onosproject.net.flow.criteria.Criterion;
|
import org.onosproject.net.flow.criteria.Criterion;
|
||||||
import org.onosproject.net.flow.criteria.IPCriterion;
|
import org.onosproject.net.flow.criteria.IPCriterion;
|
||||||
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
|
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
|
||||||
|
import org.onosproject.net.flow.instructions.Instruction;
|
||||||
import org.onosproject.net.flow.instructions.Instructions;
|
import org.onosproject.net.flow.instructions.Instructions;
|
||||||
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
|
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
|
||||||
import org.onosproject.net.flowobjective.ForwardingObjective;
|
import org.onosproject.net.flowobjective.ForwardingObjective;
|
||||||
@ -226,16 +227,14 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
|
protected CorsaTrafficTreatment processNextTreatment(TrafficTreatment treatment) {
|
||||||
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
|
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
|
||||||
tb.add(Instructions.popVlan());
|
|
||||||
treatment.immediate().stream()
|
treatment.immediate().stream()
|
||||||
.filter(i -> {
|
.filter(i -> {
|
||||||
switch (i.type()) {
|
switch (i.type()) {
|
||||||
case L2MODIFICATION:
|
case L2MODIFICATION:
|
||||||
L2ModificationInstruction l2i = (L2ModificationInstruction) i;
|
L2ModificationInstruction l2i = (L2ModificationInstruction) i;
|
||||||
if (l2i.subtype() == VLAN_ID ||
|
if (l2i.subtype() == VLAN_ID ||
|
||||||
l2i.subtype() == VLAN_POP ||
|
|
||||||
l2i.subtype() == VLAN_POP ||
|
l2i.subtype() == VLAN_POP ||
|
||||||
l2i.subtype() == ETH_DST ||
|
l2i.subtype() == ETH_DST ||
|
||||||
l2i.subtype() == ETH_SRC) {
|
l2i.subtype() == ETH_SRC) {
|
||||||
@ -247,6 +246,51 @@ public class CorsaPipelineV39 extends CorsaPipelineV3 {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}).forEach(i -> tb.add(i));
|
}).forEach(i -> tb.add(i));
|
||||||
return tb.build();
|
|
||||||
|
TrafficTreatment t = tb.build();
|
||||||
|
|
||||||
|
boolean isPresentModVlanId = false;
|
||||||
|
boolean isPresentModEthSrc = false;
|
||||||
|
boolean isPresentModEthDst = false;
|
||||||
|
boolean isPresentOutpuPort = false;
|
||||||
|
|
||||||
|
for (Instruction instruction : t.immediate()) {
|
||||||
|
switch (instruction.type()) {
|
||||||
|
case L2MODIFICATION:
|
||||||
|
L2ModificationInstruction l2i = (L2ModificationInstruction) instruction;
|
||||||
|
if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction) {
|
||||||
|
isPresentModVlanId = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
|
||||||
|
L2ModificationInstruction.L2SubType subType = l2i.subtype();
|
||||||
|
if (subType.equals(L2ModificationInstruction.L2SubType.ETH_SRC)) {
|
||||||
|
isPresentModEthSrc = true;
|
||||||
|
} else if (subType.equals(L2ModificationInstruction.L2SubType.ETH_DST)) {
|
||||||
|
isPresentModEthDst = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case OUTPUT:
|
||||||
|
isPresentOutpuPort = true;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CorsaTrafficTreatmentType type = CorsaTrafficTreatmentType.ACTIONS;
|
||||||
|
/**
|
||||||
|
* These are the allowed groups for CorsaPipelinev39
|
||||||
|
*/
|
||||||
|
if (isPresentModVlanId && isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) {
|
||||||
|
type = CorsaTrafficTreatmentType.GROUP;
|
||||||
|
|
||||||
|
} else if ((!isPresentModVlanId && isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) ||
|
||||||
|
(!isPresentModVlanId && !isPresentModEthSrc && isPresentModEthDst && isPresentOutpuPort) ||
|
||||||
|
(!isPresentModVlanId && !isPresentModEthSrc && !isPresentModEthDst && isPresentOutpuPort)) {
|
||||||
|
type = CorsaTrafficTreatmentType.GROUP;
|
||||||
|
TrafficTreatment.Builder tb2 = DefaultTrafficTreatment.builder(t);
|
||||||
|
tb2.add(Instructions.popVlan());
|
||||||
|
t = tb2.build();
|
||||||
|
}
|
||||||
|
CorsaTrafficTreatment corsaTreatment = new CorsaTrafficTreatment(type, t);
|
||||||
|
return corsaTreatment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user