From ec1a420030d2ecab77909056a34aee50f808f72f Mon Sep 17 00:00:00 2001 From: ghj0504520 Date: Mon, 22 Oct 2018 10:50:41 -0700 Subject: [PATCH] ONOS-7810 calculate cookie field when pipeconf registered Change-Id: Iea29fc447b34c49d4e8fcc831812385459c1ccbb --- .../net/pi/model/DefaultPiPipeconf.java | 30 +++++++++++++++++-- .../onosproject/net/pi/model/PiPipeconf.java | 7 +++++ .../p4runtime/ctl/P4RuntimeClientImpl.java | 18 ++--------- 3 files changed, 37 insertions(+), 18 deletions(-) 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 7d9dd283f8..cff8248948 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 @@ public final class DefaultPiPipeconf implements PiPipeconf { private final PiPipeconfId id; private final PiPipelineModel pipelineModel; + private final long fingerprint; private final Map, Class> behaviours; private final Map extensions; - private DefaultPiPipeconf(PiPipeconfId id, PiPipelineModel pipelineModel, + private DefaultPiPipeconf(PiPipeconfId id, PiPipelineModel pipelineModel, long fingerprint, Map, Class> behaviours, Map 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> 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 extensions = extensionMapBuilder.build(); + return new DefaultPiPipeconf(id, pipelineModel, generateFingerprint(extensions), + behaviourMapBuilder.build(), extensions); } + private long generateFingerprint(Map extensions) { + Collection hashArray = new ArrayList<>(); + for (Map.Entry 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 5fedaf7976..e3664e1ed3 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 @@ -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. * 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 bbc7b697a1..fa85056b6f 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 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)