ONOS-7810 calculate cookie field when pipeconf registered
Change-Id: Iea29fc447b34c49d4e8fcc831812385459c1ccbb
(cherry picked from commit ec1a420030d2ecab77909056a34aee50f808f72f)
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java b/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java
index 7d9dd28..cff8248 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/DefaultPiPipeconf.java
@@ -17,11 +17,15 @@
package org.onosproject.net.pi.model;
import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.IOUtils;
import org.onosproject.net.driver.Behaviour;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@@ -37,14 +41,16 @@
private final PiPipeconfId id;
private final PiPipelineModel pipelineModel;
+ private final long fingerprint;
private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours;
private final Map<ExtensionType, URL> extensions;
- private DefaultPiPipeconf(PiPipeconfId id, PiPipelineModel pipelineModel,
+ private DefaultPiPipeconf(PiPipeconfId id, PiPipelineModel pipelineModel, long fingerprint,
Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours,
Map<ExtensionType, URL> extensions) {
this.id = id;
this.pipelineModel = pipelineModel;
+ this.fingerprint = fingerprint;
this.behaviours = behaviours;
this.extensions = extensions;
}
@@ -60,6 +66,11 @@
}
@Override
+ public long fingerprint() {
+ return fingerprint;
+ }
+
+ @Override
public Collection<Class<? extends Behaviour>> behaviours() {
return behaviours.keySet();
}
@@ -175,8 +186,23 @@
public PiPipeconf build() {
checkNotNull(id);
checkNotNull(pipelineModel);
- return new DefaultPiPipeconf(id, pipelineModel, behaviourMapBuilder.build(), extensionMapBuilder.build());
+
+ Map<ExtensionType, URL> extensions = extensionMapBuilder.build();
+ return new DefaultPiPipeconf(id, pipelineModel, generateFingerprint(extensions),
+ behaviourMapBuilder.build(), extensions);
}
+ private long generateFingerprint(Map<ExtensionType, URL> extensions) {
+ Collection<Integer> hashArray = new ArrayList<>();
+ for (Map.Entry<ExtensionType, URL> pair : extensions.entrySet()) {
+ try {
+ hashArray.add(Arrays.hashCode(ByteBuffer.wrap(IOUtils.toByteArray(
+ pair.getValue().openStream())).array()));
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ return Arrays.hashCode(hashArray.toArray());
+ }
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
index 5fedaf7..e3664e1 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
@@ -45,6 +45,13 @@
PiPipelineModel pipelineModel();
/**
+ * Returns the fingerprint of pipeconf.
+ *
+ * @return a fingerprint
+ */
+ long fingerprint();
+
+ /**
* Returns all pipeline-specific behaviour interfaces defined by this configuration.
*
* @return a collection of behaviours
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 bbc7b69..fa85056 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,7 +80,6 @@
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;
@@ -411,7 +410,7 @@
ForwardingPipelineConfig.Cookie pipeconfCookie = ForwardingPipelineConfig.Cookie
.newBuilder()
- .setCookie(generateCookie(p4Info, deviceData))
+ .setCookie(pipeconf.fingerprint())
.build();
// FIXME: This is specific to PI P4Runtime implementation.
@@ -454,10 +453,6 @@
}
return false;
}
-
- long expectedConfigCookie = generateCookie(
- PipeconfHelper.getP4Info(pipeconf), deviceData);
-
if (!resp.getConfig().hasCookie()) {
log.warn("{} returned GetForwardingPipelineConfigResponse " +
"with 'cookie' field unset",
@@ -465,7 +460,7 @@
return false;
}
- return resp.getConfig().getCookie().getCookie() == expectedConfigCookie;
+ return resp.getConfig().getCookie().getCookie() == pipeconf.fingerprint();
}
private boolean doSetPipelineConfig(PiPipeconf pipeconf, ByteBuffer deviceData) {
@@ -1304,15 +1299,6 @@
.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)