ONOS-7810 use cookie field when checking the pipeline in P4Runtime
Change-Id: I777af9536889eb525f78493e2cbf43ff637b1a1f
diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
index c291db4..bbc7b69 100644
--- a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
+++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
@@ -80,6 +80,7 @@
import java.math.BigInteger;
import java.net.ConnectException;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -408,6 +409,11 @@
return null;
}
+ ForwardingPipelineConfig.Cookie pipeconfCookie = ForwardingPipelineConfig.Cookie
+ .newBuilder()
+ .setCookie(generateCookie(p4Info, deviceData))
+ .build();
+
// FIXME: This is specific to PI P4Runtime implementation.
P4Config.P4DeviceConfig p4DeviceConfigMsg = P4Config.P4DeviceConfig
.newBuilder()
@@ -420,6 +426,7 @@
.newBuilder()
.setP4Info(p4Info)
.setP4DeviceConfig(p4DeviceConfigMsg.toByteString())
+ .setCookie(pipeconfCookie)
.build();
}
@@ -428,6 +435,8 @@
GetForwardingPipelineConfigRequest request = GetForwardingPipelineConfigRequest
.newBuilder()
.setDeviceId(p4DeviceId)
+ .setResponseType(GetForwardingPipelineConfigRequest
+ .ResponseType.COOKIE_ONLY)
.build();
GetForwardingPipelineConfigResponse resp;
@@ -446,32 +455,17 @@
return false;
}
- ForwardingPipelineConfig expectedConfig = getPipelineConfig(
- pipeconf, deviceData);
+ long expectedConfigCookie = generateCookie(
+ PipeconfHelper.getP4Info(pipeconf), deviceData);
- if (expectedConfig == null) {
- return false;
- }
- if (!resp.hasConfig()) {
+ if (!resp.getConfig().hasCookie()) {
log.warn("{} returned GetForwardingPipelineConfigResponse " +
- "with 'config' field unset",
+ "with 'cookie' field unset",
deviceId);
return false;
}
- if (resp.getConfig().getP4DeviceConfig().isEmpty()
- && !expectedConfig.getP4DeviceConfig().isEmpty()) {
- // Don't bother with a warn or error since we don't really allow
- // updating the pipeline to a different one. So the P4Info should be
- // enough for us.
- log.debug("{} returned GetForwardingPipelineConfigResponse " +
- "with empty 'p4_device_config' field, " +
- "equality will be based only on P4Info",
- deviceId);
- return resp.getConfig().getP4Info().equals(
- expectedConfig.getP4Info());
- } else {
- return resp.getConfig().equals(expectedConfig);
- }
+
+ return resp.getConfig().getCookie().getCookie() == expectedConfigCookie;
}
private boolean doSetPipelineConfig(PiPipeconf pipeconf, ByteBuffer deviceData) {
@@ -1310,6 +1304,15 @@
.build();
}
+ /**
+ * A function to generate cookie based on P4Info and target-specific binary
+ * data.
+ * Moreover, the method to generate cookie can be replaced.
+ */
+ private long generateCookie(P4Info p4Info, ByteBuffer deviceData) {
+ return Objects.hash(p4Info, Arrays.hashCode(deviceData.array()));
+ }
+
private BigInteger uint128ToBigInteger(Uint128 value) {
return new BigInteger(
ByteBuffer.allocate(Long.BYTES * 2)