use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method getNextMappings.
@Override
public List<String> getNextMappings(NextGroup nextGroup) {
List<String> mappings = new ArrayList<>();
List<Deque<GroupKey>> gkeys = appKryo.deserialize(nextGroup.data());
for (Deque<GroupKey> gkd : gkeys) {
Group lastGroup = null;
StringBuilder gchain = new StringBuilder();
for (GroupKey gk : gkd) {
Group g = groupService.getGroup(deviceId, gk);
if (g == null) {
gchain.append(" NoGrp").append(" -->");
continue;
}
gchain.append(" 0x").append(Integer.toHexString(g.id().id())).append(" -->");
lastGroup = g;
}
// add port information for last group in group-chain
List<Instruction> lastGroupIns = new ArrayList<>();
if (lastGroup != null && !lastGroup.buckets().buckets().isEmpty()) {
lastGroupIns = lastGroup.buckets().buckets().get(0).treatment().allInstructions();
}
for (Instruction i : lastGroupIns) {
if (i instanceof OutputInstruction) {
gchain.append(" port:").append(((OutputInstruction) i).port());
}
}
mappings.add(gchain.toString());
}
return mappings;
}
use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class Ofdpa3Pipeline method processTermPwVersatile.
private Collection<FlowRule> processTermPwVersatile(ForwardingObjective forwardingObjective, ModTunnelIdInstruction modTunnelIdInstruction, OutputInstruction outputInstruction) {
TrafficTreatment.Builder flowTreatment;
TrafficSelector.Builder flowSelector;
// We divide the mpls actions from the tunnel actions. We need
// this to order the actions in the final treatment.
TrafficTreatment.Builder mplsTreatment = DefaultTrafficTreatment.builder();
createMplsTreatment(forwardingObjective.treatment(), mplsTreatment);
// The match of the forwarding objective is ready to go.
flowSelector = DefaultTrafficSelector.builder(forwardingObjective.selector());
// We verify the tunnel id and mpls port are correct.
long tunnelId = MPLS_TUNNEL_ID_BASE | modTunnelIdInstruction.tunnelId();
if (tunnelId > MPLS_TUNNEL_ID_MAX) {
log.error("Pw Versatile Forwarding Objective must include tunnel id < {}", MPLS_TUNNEL_ID_MAX);
fail(forwardingObjective, ObjectiveError.BADPARAMS);
return Collections.emptySet();
}
// 0x0002XXXX is NNI interface.
int mplsLogicalPort = ((int) outputInstruction.port().toLong()) | MPLS_NNI_PORT_BASE;
if (mplsLogicalPort > MPLS_NNI_PORT_MAX) {
log.error("Pw Versatile Forwarding Objective invalid logical port {}", mplsLogicalPort);
fail(forwardingObjective, ObjectiveError.BADPARAMS);
return Collections.emptySet();
}
// Next id cannot be null.
if (forwardingObjective.nextId() == null) {
log.error("Pw Versatile Forwarding Objective must contain nextId ", forwardingObjective.nextId());
fail(forwardingObjective, ObjectiveError.BADPARAMS);
return Collections.emptySet();
}
// We retrieve the l2 interface group and point the mpls
// flow to this.
NextGroup next = getGroupForNextObjective(forwardingObjective.nextId());
if (next == null) {
log.warn("next-id:{} not found in dev:{}", forwardingObjective.nextId(), deviceId);
fail(forwardingObjective, ObjectiveError.GROUPMISSING);
return Collections.emptySet();
}
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group == null) {
log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), forwardingObjective.nextId(), deviceId);
fail(forwardingObjective, ObjectiveError.GROUPMISSING);
return Collections.emptySet();
}
// We prepare the treatment for the mpls flow table.
// The order of the actions has to be strictly this
// according to the OFDPA 2.0 specification.
flowTreatment = DefaultTrafficTreatment.builder(mplsTreatment.build());
flowTreatment.extension(new Ofdpa3PopCw(), deviceId);
// Even though the specification and the xml/json files
// specify is allowed, the switch rejects the flow. In the
// OFDPA 3.0 EA0 version was necessary
// flowTreatment.popVlan();
flowTreatment.extension(new Ofdpa3PopL2Header(), deviceId);
flowTreatment.setTunnelId(tunnelId);
flowTreatment.extension(new Ofdpa3SetMplsL2Port(mplsLogicalPort), deviceId);
flowTreatment.extension(new Ofdpa3SetMplsType(VPWS), deviceId);
flowTreatment.transition(MPLS_TYPE_TABLE);
flowTreatment.deferred().group(group.id());
// We prepare the flow rule for the mpls table.
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(forwardingObjective.appId()).withPriority(forwardingObjective.priority()).forDevice(deviceId).withSelector(flowSelector.build()).withTreatment(flowTreatment.build()).makePermanent().forTable(MPLS_TABLE_1);
return Collections.singletonList(ruleBuilder.build());
}
use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class OvsOfdpaPipeline method processDoubleTaggedFwd.
/**
* Handles forwarding rules to the IP Unicast Routing.
*
* @param fwd the forwarding objective
* @return A collection of flow rules, or an empty set
*/
protected Collection<FlowRule> processDoubleTaggedFwd(ForwardingObjective fwd) {
// inner for UNICAST_ROUTING_TABLE_1, outer for UNICAST_ROUTING_TABLE
TrafficSelector selector = fwd.selector();
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder innerTtb = DefaultTrafficTreatment.builder();
TrafficTreatment.Builder outerTtb = DefaultTrafficTreatment.builder();
EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
sBuilder.matchEthType(Ethernet.TYPE_IPV4);
sBuilder.matchVlanId(VlanId.ANY);
IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
if (!ipv4Dst.isMulticast() && ipv4Dst.prefixLength() == 32) {
sBuilder.matchIPDst(ipv4Dst);
if (fwd.nextId() != null) {
NextGroup next = getGroupForNextObjective(fwd.nextId());
if (next != null) {
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
// we only need the top level group's key to point the flow to it
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group == null) {
log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.GROUPMISSING);
return Collections.emptySet();
}
outerTtb.immediate().setVlanId(extractDummyVlanIdFromGroupId(group.id().id()));
// ACTSET_OUTPUT in OVS will match output action in write_action() set.
outerTtb.deferred().setOutput(extractOutputPortFromGroupId(group.id().id()));
outerTtb.transition(EGRESS_VLAN_FLOW_TABLE_IN_INGRESS);
innerTtb.deferred().group(group.id());
innerTtb.transition(ACL_TABLE);
FlowRule.Builder innerRuleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sBuilder.build()).withTreatment(innerTtb.build()).forTable(UNICAST_ROUTING_TABLE_1);
if (fwd.permanent()) {
innerRuleBuilder.makePermanent();
} else {
innerRuleBuilder.makeTemporary(fwd.timeout());
}
Collection<FlowRule> flowRuleCollection = new HashSet<>();
flowRuleCollection.add(innerRuleBuilder.build());
FlowRule.Builder outerRuleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(sBuilder.build()).withTreatment(outerTtb.build()).forTable(UNICAST_ROUTING_TABLE);
if (fwd.permanent()) {
outerRuleBuilder.makePermanent();
} else {
outerRuleBuilder.makeTemporary(fwd.timeout());
}
flowRuleCollection.add(innerRuleBuilder.build());
flowRuleCollection.add(outerRuleBuilder.build());
return flowRuleCollection;
} else {
log.warn("Cannot find group for nextId:{} in dev:{}. Aborting fwd:{}", fwd.nextId(), deviceId, fwd.id());
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
} else {
log.warn("NextId is not specified in fwd:{}", fwd.id());
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
}
}
return Collections.emptySet();
}
use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class OvsOfdpaPipeline method isDoubleTagged.
/**
* Determines if the forwarding objective will be used for double-tagged packets.
*
* @param fwd Forwarding objective
* @return True if the objective was created for double-tagged packets, false otherwise.
*/
private boolean isDoubleTagged(ForwardingObjective fwd) {
if (fwd.nextId() != null) {
NextGroup next = getGroupForNextObjective(fwd.nextId());
if (next != null) {
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
// we only need the top level group's key
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group != null) {
int groupId = group.id().id();
if (((groupId & ~TYPE_MASK) == L3_UNICAST_TYPE) && ((groupId & TYPE_L3UG_DOUBLE_VLAN_MASK) == TYPE_L3UG_DOUBLE_VLAN_MASK)) {
return true;
}
}
}
}
return false;
}
use of org.onosproject.net.behaviour.NextGroup in project onos by opennetworkinglab.
the class DefaultSingleTablePipeline method forward.
@Override
public void forward(ForwardingObjective fwd) {
TrafficSelector selector = fwd.selector();
if (fwd.treatment() != null) {
// Deal with SPECIFIC and VERSATILE in the same manner.
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector).fromApp(fwd.appId()).withPriority(fwd.priority()).withTreatment(fwd.treatment());
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
installObjective(ruleBuilder, fwd);
} else {
NextObjective nextObjective;
NextGroup next;
TrafficTreatment treatment;
if (fwd.op() == ADD) {
// Give a try to the cache. Doing an operation
// on the store seems to be very expensive.
nextObjective = pendingAddNext.getIfPresent(fwd.nextId());
// We will try with the store
if (nextObjective == null) {
next = flowObjectiveStore.getNextGroup(fwd.nextId());
// the treatment in order to re-build the flow rule.
if (next == null) {
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING));
return;
}
treatment = appKryo.deserialize(next.data());
} else {
pendingAddNext.invalidate(fwd.nextId());
treatment = getTreatment(nextObjective);
if (treatment == null) {
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.UNSUPPORTED));
return;
}
}
} else {
// We get the NextGroup from the remove operation.
// Doing an operation on the store seems to be very expensive.
next = flowObjectiveStore.getNextGroup(fwd.nextId());
treatment = (next != null) ? appKryo.deserialize(next.data()) : null;
}
// If the treatment is null we cannot re-build the original flow
if (treatment == null) {
fwd.context().ifPresent(c -> c.onError(fwd, ObjectiveError.GROUPMISSING));
return;
}
// Finally we build the flow rule and push to the flow rule subsystem.
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().forDevice(deviceId).withSelector(selector).fromApp(fwd.appId()).withPriority(fwd.priority()).withTreatment(treatment);
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
installObjective(ruleBuilder, fwd);
}
}
Aggregations