[ONOS-4164] Flow decode in bgpcep flow provider
Change-Id: Ib64529e37ccff5b392a2ccb24341b5a780408f6c
(cherry picked from commit a4f66f62833d26cad205c93ecfe3f82fdc345d3e)
diff --git a/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java b/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java
index f8c3ec0..b005132 100644
--- a/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java
+++ b/providers/bgpcep/flow/src/main/java/org/onosproject/provider/bgpcep/flow/impl/BgpcepFlowRuleProvider.java
@@ -26,6 +26,7 @@
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MplsLabel;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
@@ -35,20 +36,31 @@
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleBatchOperation;
import org.onosproject.net.flow.FlowRuleProvider;
import org.onosproject.net.flow.FlowRuleProviderRegistry;
import org.onosproject.net.flow.FlowRuleProviderService;
+import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.MplsBosCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.resource.ResourceService;
+import org.onosproject.pcep.controller.PccId;
import org.onosproject.pcep.controller.PcepClient;
import org.onosproject.pcep.controller.PcepClientController;
import org.onosproject.pcepio.exceptions.PcepParseException;
@@ -106,12 +118,16 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TunnelService tunnelService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
private FlowRuleProviderService providerService;
private PcepLabelObject labelObj;
public static final int OUT_LABEL_TYPE = 0;
public static final int IN_LABEL_TYPE = 1;
public static final long IDENTIFIER_SET = 0x100000000L;
public static final long SET = 0xFFFFFFFFL;
+ private static final String LSRID = "lsrId";
/**
* Creates a BgpFlow host provider.
@@ -138,34 +154,88 @@
@Override
public void applyFlowRule(FlowRule... flowRules) {
for (FlowRule flowRule : flowRules) {
- applyRule(flowRule);
+ processRule(flowRule, Objective.Operation.ADD);
}
}
- private void applyRule(FlowRule flowRule) {
- flowRule.selector().criteria()
- .forEach(c -> {
- // If Criterion type is MPLS_LABEL, push labels through PCEP client
- if (c.type() == Criterion.Type.MPLS_LABEL) {
- PcepClient pcc;
- /** PCC client session is based on LSR ID, get the LSR ID for a specific device to
- push the flows */
+ @Override
+ public void removeFlowRule(FlowRule... flowRules) {
+ for (FlowRule flowRule : flowRules) {
+ processRule(flowRule, Objective.Operation.REMOVE);
+ }
+ }
- //TODO: commented code has dependency with other patch
- /* Set<TeRouterId> lrsIds = resourceService.getAvailableResourceValues(Resources
- .discrete(flowRule.deviceId()).id(), TeRouterId.class);
+ private void processRule(FlowRule flowRule, Objective.Operation type) {
+ MplsLabel mplsLabel = null;
+ IpPrefix ip4Prefix = null;
+ PortNumber port = null;
+ TunnelId tunnelId = null;
+ long labelType = 0;
+ boolean bottomOfStack = false;
+ int srcPort = 0;
+ int dstPort = 0;
- lrsIds.forEach(lsrId ->
- {
- if (pcepController.getClient(PccId.pccId(lsrId)) != null) {
- pcc = pcepController.getClient(PccId.pccId(lsrId));
- }
- });*/
- // TODO: Build message and send the PCEP label message via PCEP client
- } else {
- // TODO: Get the BGP peer based on deviceId and send the message
- }
- });
+ TrafficSelector selector = flowRule.selector();
+ for (Criterion c : selector.criteria()) {
+ switch (c.type()) {
+ case MPLS_LABEL:
+ MplsCriterion lc = (MplsCriterion) c;
+ mplsLabel = lc.label();
+ break;
+ case IPV4_SRC:
+ IPCriterion ipCriterion = (IPCriterion) c;
+ ip4Prefix = ipCriterion.ip().getIp4Prefix();
+ break;
+ case IN_PORT:
+ PortCriterion inPort = (PortCriterion) c;
+ port = inPort.port();
+ break;
+ case TCP_SRC:
+ TcpPortCriterion srcTcpPort = (TcpPortCriterion) c;
+ srcPort = srcTcpPort.tcpPort().toInt();
+ break;
+ case TCP_DST:
+ TcpPortCriterion dstTcpPort = (TcpPortCriterion) c;
+ dstPort = dstTcpPort.tcpPort().toInt();
+ break;
+ case TUNNEL_ID:
+ TunnelIdCriterion tc = (TunnelIdCriterion) c;
+ tunnelId = TunnelId.valueOf(String.valueOf(tc.tunnelId()));
+ break;
+ case METADATA:
+ MetadataCriterion metadata = (MetadataCriterion) c;
+ labelType = metadata.metadata();
+ break;
+ case MPLS_BOS:
+ MplsBosCriterion mplsBos = (MplsBosCriterion) c;
+ bottomOfStack = mplsBos.mplsBos();
+ break;
+ default:
+ break;
+ }
+ }
+
+ checkNotNull(mplsLabel);
+ LabelResourceId label = LabelResourceId.labelResourceId(mplsLabel.toInt());
+
+ try {
+ if (tunnelId != null) {
+ pushLocalLabels(flowRule.deviceId(), label, port, tunnelId, bottomOfStack, labelType, type);
+ return;
+ }
+
+ if (srcPort != 0 && dstPort != 0) {
+ pushAdjacencyLabel(flowRule.deviceId(), label, PortNumber.portNumber(srcPort),
+ PortNumber.portNumber(dstPort), type);
+ return;
+ }
+
+ pushGlobalNodeLabel(flowRule.deviceId(), label, ip4Prefix, type, bottomOfStack);
+
+ } catch (PcepParseException e) {
+ log.error("Exception occured while sending label message to PCC {}", e.getMessage());
+ }
+
}
/**
@@ -174,19 +244,13 @@
* @return PCEP client
*/
private PcepClient getPcepClient(DeviceId deviceId) {
- PcepClient pcc;
- //TODO: commented code has dependency
- /* Set<TeRouterId> lrsIds = resourceService.getAvailableResourceValues(Resources
- .discrete(deviceId()).id(), TeRouterId.class);
+ Device device = deviceService.getDevice(deviceId);
- lrsIds.forEach(lsrId ->
- {
- if (pcepController.getClient(PccId.pccId(lsrId)) != null) {
- pcc = pcepController.getClient(PccId.pccId(lsrId));
- return pcc
- }
- });*/
- return null;
+ // In future projections instead of annotations will be used to fetch LSR ID.
+ String lsrId = device.annotations().value(LSRID);
+
+ PcepClient pcc = pcepController.getClient(PccId.pccId(IpAddress.valueOf(lsrId)));
+ return pcc;
}
//Pushes node labels to the specified device.
@@ -195,7 +259,6 @@
checkNotNull(deviceId);
checkNotNull(labelId);
- checkNotNull(ipPrefix);
checkNotNull(type);
PcepClient pc = getPcepClient(deviceId);
@@ -206,6 +269,11 @@
LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
+ if (ipPrefix == null) {
+ // Pushing self node label to device.
+ IpPrefix.valueOf(pc.getPccId().ipAddress(), 32);
+ }
+
PcepFecObjectIPv4 fecObject = pc.factory().buildFecObjectIpv4()
.setNodeID(ipPrefix.address().getIp4Address().toInt())
.build();
@@ -484,39 +552,6 @@
}
@Override
- public void removeFlowRule(FlowRule... flowRules) {
- for (FlowRule flowRule : flowRules) {
- removeRule(flowRule);
- }
- }
-
- private void removeRule(FlowRule flowRule) {
- flowRule.selector().criteria()
- .forEach(c -> {
- // If Criterion type is MPLS_LABEL, remove the specified flow rules
- if (c.type() == Criterion.Type.MPLS_LABEL) {
- PcepClient pcc;
- /** PCC client session is based on LSR ID, get the LSR ID for a specific device to
- push the flows */
-
- //TODO: commented code has dependency with other patch
- /* Set<TeRouterId> lrsIds = resourceService.getAvailableResourceValues(Resources
- .discrete(flowRule.deviceId()).id(), TeRouterId.class);
-
- lrsIds.forEach(lsrId ->
- {
- if (pcepController.getClient(PccId.pccId(lsrId)) != null) {
- pcc = pcepController.getClient(PccId.pccId(lsrId));
- }
- });*/
- // TODO: Build message and send the PCEP label message via PCEP client
- } else {
- // TODO: Get the BGP peer based on deviceId and send the message
- }
- });
- }
-
- @Override
public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
// TODO
removeFlowRule(flowRules);