ONOS-7810 calculate cookie field when pipeconf registered

Change-Id: Iea29fc447b34c49d4e8fcc831812385459c1ccbb
This commit is contained in:
ghj0504520 2018-10-22 10:50:41 -07:00 committed by Carmelo Cascone
parent 666258f7fc
commit ec1a420030
3 changed files with 37 additions and 18 deletions

View File

@ -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 @@ public final class DefaultPiPipeconf implements PiPipeconf {
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;
}
@ -59,6 +65,11 @@ public final class DefaultPiPipeconf implements PiPipeconf {
return pipelineModel;
}
@Override
public long fingerprint() {
return fingerprint;
}
@Override
public Collection<Class<? extends Behaviour>> behaviours() {
return behaviours.keySet();
@ -175,8 +186,23 @@ public final class DefaultPiPipeconf implements PiPipeconf {
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());
}
}
}

View File

@ -44,6 +44,13 @@ public interface PiPipeconf {
*/
PiPipelineModel pipelineModel();
/**
* Returns the fingerprint of pipeconf.
*
* @return a fingerprint
*/
long fingerprint();
/**
* Returns all pipeline-specific behaviour interfaces defined by this configuration.
*

View File

@ -80,7 +80,6 @@ import p4.v1.P4RuntimeOuterClass.WriteRequest;
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 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
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 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
}
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 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
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 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
.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)