Generic extensions to the treatment API to support protocol extensions like
OF experimenter actions.
Change-Id: I88cc5896d17fdbf89807f911f9c23e4f19f6a5ad
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java b/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java
new file mode 100644
index 0000000..54cbc7a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionType;
+
+/**
+ * Provides access to the extension implemented by this driver.
+ */
+@Beta
+public interface ExtensionResolver extends HandlerBehaviour {
+
+ /**
+ * Gets an extension instruction instance of the specified type, if supported
+ * by the driver.
+ *
+ * @param type type of extension to get
+ * @return extension instruction
+ * @throws UnsupportedOperationException if the extension type is not
+ * supported by this driver
+ */
+ ExtensionInstruction getExtensionInstruction(ExtensionType type);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index ac37d1f..6beeecc 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -27,8 +27,10 @@
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.IndexedLambda;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.meter.MeterId;
@@ -244,6 +246,7 @@
case L2MODIFICATION:
case L3MODIFICATION:
case L4MODIFICATION:
+ case EXTENSION:
current.add(instruction);
break;
case TABLE:
@@ -481,6 +484,12 @@
}
@Override
+ public TrafficTreatment.Builder extension(ExtensionInstruction extension,
+ DeviceId deviceId) {
+ return add(Instructions.extension(extension, deviceId));
+ }
+
+ @Override
public TrafficTreatment build() {
if (deferred.size() == 0 && immediate.size() == 0
&& table == null && !clear) {
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index 91c19b7..b14ab99 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -24,7 +24,9 @@
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.meter.MeterId;
@@ -413,6 +415,15 @@
Builder setUdpDst(TpPort port);
/**
+ * Uses an extension treatment.
+ *
+ * @param extension extension treatment
+ * @param deviceId device ID
+ * @return a treatment builder
+ */
+ Builder extension(ExtensionInstruction extension, DeviceId deviceId);
+
+ /**
* Builds an immutable traffic treatment descriptor.
* <p>
* If the treatment is empty when build() is called, it will add a default
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java
new file mode 100644
index 0000000..9f22f88
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.instructions;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Abstract implementation of the set/get property methods of ExtensionInstruction.
+ */
+public abstract class AbstractExtensionInstruction implements ExtensionInstruction {
+
+ private static final String INVALID_KEY = "Invalid property key: ";
+ private static final String INVALID_TYPE = "Given type does not match field type: ";
+
+ @Override
+ public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+ Class<?> clazz = this.getClass();
+ try {
+ Field field = clazz.getDeclaredField(key);
+ field.setAccessible(true);
+ field.set(this, value);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new ExtensionPropertyException(INVALID_KEY + key);
+ }
+ }
+
+ @Override
+ public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
+ Class<?> clazz = this.getClass();
+ try {
+ Field field = clazz.getDeclaredField(key);
+ field.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ T result = (T) field.get(this);
+ return result;
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new ExtensionPropertyException(INVALID_KEY + key);
+ } catch (ClassCastException e) {
+ throw new ExtensionPropertyException(INVALID_TYPE + key);
+ }
+ }
+
+ @Override
+ public List<String> getProperties() {
+ Class<?> clazz = this.getClass();
+
+ List<String> fields = new ArrayList<>();
+
+ for (Field field : clazz.getDeclaredFields()) {
+ fields.add(field.getName());
+ }
+
+ return fields;
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java
new file mode 100644
index 0000000..89e0cc5
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.instructions;
+
+import java.util.List;
+
+/**
+ * An extensible instruction type.
+ */
+public interface ExtensionInstruction {
+
+ /**
+ * Gets the type of the extension instruction.
+ *
+ * @return type
+ */
+ ExtensionType type();
+
+ /**
+ * Sets a property on the extension instruction.
+ *
+ * @param key property key
+ * @param value value to set for the given key
+ * @param <T> class of the value
+ * @throws ExtensionPropertyException if the given key is not a valid
+ * property on this extension instruction
+ */
+ <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
+
+ /**
+ * Gets a property value of an extension instruction.
+ *
+ * @param key property key
+ * @param <T> class of the value
+ * @return value of the property
+ * @throws ExtensionPropertyException if the given key is not a valid
+ * property on this extension instruction
+ */
+ <T> T getPropertyValue(String key) throws ExtensionPropertyException;
+
+ /**
+ * Gets a list of all properties on the extension instruction.
+ *
+ * @return list of properties
+ */
+ List<String> getProperties();
+
+ /**
+ * Serialize the extension instruction to a byte array.
+ *
+ * @return byte array
+ */
+ byte[] serialize();
+
+ /**
+ * Deserialize the extension instruction from a byte array. The properties
+ * of this object will be overwritten with the data in the byte array.
+ *
+ * @param data input byte array
+ */
+ void deserialize(byte[] data);
+
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionPropertyException.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionPropertyException.java
new file mode 100644
index 0000000..5750d09
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionPropertyException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.instructions;
+
+/**
+ * Exception indicating there was an error while setting/getting an extension
+ * instruction property.
+ */
+public class ExtensionPropertyException extends Exception {
+
+ public ExtensionPropertyException(String message) {
+ super(message);
+ }
+
+ public ExtensionPropertyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
new file mode 100644
index 0000000..747a85b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.instructions;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Type of extension instructions.
+ */
+@Beta
+public final class ExtensionType {
+
+ /**
+ * A list of well-known named extension instruction type codes.
+ */
+ public enum ExtensionTypes {
+ // TODO fix type numbers to include experimenter id
+ NICIRA_SET_TUNNEL_DST(31);
+
+ private ExtensionType type;
+
+ /**
+ * Creates a new named extension instruction type.
+ *
+ * @param type type code
+ */
+ ExtensionTypes(int type) {
+ this.type = new ExtensionType(type);
+ }
+
+ /**
+ * Gets the extension type object for this named type code.
+ *
+ * @return extension type object
+ */
+ public ExtensionType type() {
+ return type;
+ }
+ }
+
+ private final int type;
+
+ /**
+ * Creates an extension type with the given int type code.
+ *
+ * @param type type code
+ */
+ public ExtensionType(int type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ExtensionType) {
+ final ExtensionType that = (ExtensionType) obj;
+ return this.type == that.type;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(ExtensionType.class)
+ .add("type", type)
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
index 2f6a1cc..31ad80c 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
@@ -92,7 +92,12 @@
/**
* Signifies that the traffic should be modified in L4 way.
*/
- L4MODIFICATION
+ L4MODIFICATION,
+
+ /**
+ * Signifies that an extension instruction will be used.
+ */
+ EXTENSION
}
/**
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index 8868bf7..aad407c 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -22,6 +22,7 @@
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.IndexedLambda;
import org.onosproject.net.Lambda;
import org.onosproject.net.OchSignal;
@@ -480,6 +481,20 @@
}
/**
+ * Creates an extension instruction.
+ *
+ * @param extension extension instruction
+ * @param deviceId device ID
+ * @return extension instruction
+ */
+ public static ExtensionInstructionWrapper extension(ExtensionInstruction extension,
+ DeviceId deviceId) {
+ checkNotNull(extension, "Extension instruction cannot be null");
+ checkNotNull(deviceId, "Device ID cannot be null");
+ return new ExtensionInstructionWrapper(extension, deviceId);
+ }
+
+ /**
* Drop instruction.
*/
@Deprecated
@@ -820,6 +835,59 @@
}
}
+ /**
+ * Extension instruction.
+ */
+ public static class ExtensionInstructionWrapper implements Instruction {
+ private final ExtensionInstruction extensionInstruction;
+ private final DeviceId deviceId;
+
+ ExtensionInstructionWrapper(ExtensionInstruction extension, DeviceId deviceId) {
+ extensionInstruction = extension;
+ this.deviceId = deviceId;
+ }
+
+ public ExtensionInstruction extensionInstruction() {
+ return extensionInstruction;
+ }
+
+ public DeviceId deviceId() {
+ return deviceId;
+ }
+
+ @Override
+ public Type type() {
+ return Type.EXTENSION;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("extension", extensionInstruction)
+ .add("deviceId", deviceId)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type().ordinal(), extensionInstruction, deviceId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ExtensionInstructionWrapper) {
+ ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
+ return Objects.equals(extensionInstruction, that.extensionInstruction)
+ && Objects.equals(deviceId, that.deviceId);
+
+ }
+ return false;
+ }
+ }
+
}
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java
new file mode 100644
index 0000000..6b12df9
--- /dev/null
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/ExtensionInstructionSerializer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.store.serializers;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.ExtensionResolver;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionType;
+import org.onosproject.net.flow.instructions.Instructions;
+
+/**
+ * Created by jono on 10/29/15.
+ */
+public class ExtensionInstructionSerializer extends
+ Serializer<Instructions.ExtensionInstructionWrapper> {
+
+ public ExtensionInstructionSerializer() {
+ super(false, true);
+ }
+
+ @Override
+ public void write(Kryo kryo, Output output, Instructions.ExtensionInstructionWrapper object) {
+ kryo.writeClassAndObject(output, object.extensionInstruction().type());
+ kryo.writeClassAndObject(output, object.deviceId());
+
+ kryo.writeClassAndObject(output, object.extensionInstruction().serialize());
+
+ }
+
+ @Override
+ public Instructions.ExtensionInstructionWrapper read(Kryo kryo, Input input,
+ Class<Instructions.ExtensionInstructionWrapper> type) {
+ ExtensionType exType = (ExtensionType) kryo.readClassAndObject(input);
+ DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
+
+ DriverService driverService = DefaultServiceDirectory.getService(DriverService.class);
+ DriverHandler handler = new DefaultDriverHandler(
+ new DefaultDriverData(driverService.getDriver(deviceId), deviceId));
+
+ ExtensionResolver resolver = handler.behaviour(ExtensionResolver.class);
+
+ ExtensionInstruction instruction = resolver.getExtensionInstruction(exType);
+
+ byte[] bytes = (byte[]) kryo.readClassAndObject(input);
+
+ instruction.deserialize(bytes);
+
+ return Instructions.extension(instruction, deviceId);
+ }
+}
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 225b95d..0312baf 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -128,6 +128,7 @@
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.onosproject.net.flow.instructions.ExtensionType;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L1ModificationInstruction;
@@ -450,6 +451,8 @@
.register(new HostLocationSerializer(), HostLocation.class)
.register(new DefaultOutboundPacketSerializer(), DefaultOutboundPacket.class)
.register(new AnnotationsSerializer(), DefaultAnnotations.class)
+ .register(new ExtensionInstructionSerializer(), Instructions.ExtensionInstructionWrapper.class)
+ .register(ExtensionType.class)
.register(Versioned.class)
.register(MapEvent.class)
.register(MapEvent.Type.class)
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionInterpreter.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionInterpreter.java
new file mode 100644
index 0000000..082c5a6
--- /dev/null
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionInterpreter.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.extensions;
+
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.behaviour.ExtensionResolver;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionType;
+import org.onosproject.openflow.controller.ExtensionInterpreter;
+import org.projectfloodlight.openflow.protocol.OFActionType;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst;
+import org.projectfloodlight.openflow.types.IPv4Address;
+
+/**
+ * Interpreter for Nicira OpenFlow extensions.
+ */
+public class NiciraExtensionInterpreter extends AbstractHandlerBehaviour
+ implements ExtensionInterpreter, ExtensionResolver {
+
+ @Override
+ public boolean supported(ExtensionType extensionType) {
+ if (extensionType.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public OFAction mapInstruction(OFFactory factory, ExtensionInstruction extensionInstruction) {
+ ExtensionType type = extensionInstruction.type();
+ if (type.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) {
+ NiciraSetTunnelDst tunnelDst = (NiciraSetTunnelDst) extensionInstruction;
+ return factory.actions().setField(factory.oxms().tunnelIpv4Dst(
+ IPv4Address.of(tunnelDst.tunnelDst().toInt())));
+ }
+ return null;
+ }
+
+ @Override
+ public ExtensionInstruction mapAction(OFAction action) {
+ if (action.getType().equals(OFActionType.SET_FIELD)) {
+ OFActionSetField setFieldAction = (OFActionSetField) action;
+ OFOxm<?> oxm = setFieldAction.getField();
+ switch (oxm.getMatchField().id) {
+ case TUNNEL_IPV4_DST:
+ OFOxmTunnelIpv4Dst tunnelIpv4Dst = (OFOxmTunnelIpv4Dst) oxm;
+ return new NiciraSetTunnelDst(Ip4Address.valueOf(tunnelIpv4Dst.getValue().getInt()));
+ default:
+ throw new UnsupportedOperationException(
+ "Driver does not support extension type " + oxm.getMatchField().id);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ExtensionInstruction getExtensionInstruction(ExtensionType type) {
+ if (type.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) {
+ return new NiciraSetTunnelDst();
+ }
+ throw new UnsupportedOperationException(
+ "Driver does not support extension type " + type.toString());
+ }
+}
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java
new file mode 100644
index 0000000..16aa1b0
--- /dev/null
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.extensions;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.Ip4Address;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.flow.instructions.AbstractExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionType;
+import org.onosproject.store.serializers.Ip4AddressSerializer;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Nicira set tunnel destination extension instruction.
+ */
+public class NiciraSetTunnelDst extends AbstractExtensionInstruction {
+
+ private Ip4Address tunnelDst;
+
+ private final KryoNamespace appKryo = new KryoNamespace.Builder()
+ .register(new Ip4AddressSerializer(), Ip4Address.class)
+ .register(byte[].class)
+ .build();
+
+ /**
+ * Creates a new set tunnel destination instruction.
+ */
+ NiciraSetTunnelDst() {
+ tunnelDst = null;
+ }
+
+ /**
+ * Creates a new set tunnel destination instruction with a particular IPv4
+ * address.
+ */
+ NiciraSetTunnelDst(Ip4Address tunnelDst) {
+ checkNotNull(tunnelDst);
+ this.tunnelDst = tunnelDst;
+ }
+
+ /**
+ * Gets the tunnel destination IPv4 address.
+ *
+ * @return tunnel destination IPv4 address
+ */
+ public Ip4Address tunnelDst() {
+ return tunnelDst;
+ }
+
+ @Override
+ public ExtensionType type() {
+ return ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type();
+ }
+
+ @Override
+ public void deserialize(byte[] data) {
+ tunnelDst = appKryo.deserialize(data);
+ }
+
+ @Override
+ public byte[] serialize() {
+ return appKryo.serialize(tunnelDst);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tunnelDst);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof NiciraSetTunnelDst) {
+ NiciraSetTunnelDst that = (NiciraSetTunnelDst) obj;
+ return Objects.equals(tunnelDst, that.tunnelDst);
+
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("tunnelDst", tunnelDst)
+ .toString();
+ }
+}
diff --git a/drivers/src/main/resources/onos-drivers.xml b/drivers/src/main/resources/onos-drivers.xml
index 74281bf..af49883 100644
--- a/drivers/src/main/resources/onos-drivers.xml
+++ b/drivers/src/main/resources/onos-drivers.xml
@@ -32,6 +32,10 @@
impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/>
<behaviour api="org.onosproject.net.behaviour.ControllerConfig"
impl="org.onosproject.driver.ovsdb.OvsdbControllerConfig"/>
+ <behaviour api="org.onosproject.openflow.controller.ExtensionInterpreter"
+ impl="org.onosproject.driver.extensions.NiciraExtensionInterpreter" />
+ <behaviour api="org.onosproject.net.behaviour.ExtensionResolver"
+ impl="org.onosproject.driver.extensions.NiciraExtensionInterpreter" />
</driver>
<driver name="ovs-corsa" extends="ovs"
manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionInterpreter.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionInterpreter.java
new file mode 100644
index 0000000..44b121a
--- /dev/null
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionInterpreter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.openflow.controller;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionType;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+
+/**
+ * Interprets extension instructions and converts them to/from OpenFlow objects.
+ */
+@Beta
+public interface ExtensionInterpreter extends HandlerBehaviour {
+
+ /**
+ * Returns true if the given extension instruction is supported by this
+ * driver.
+ *
+ * @param extensionType extension instruction type
+ * @return true if the instruction is supported, otherwise false
+ */
+ boolean supported(ExtensionType extensionType);
+
+ /**
+ * Maps an extension instruction to an OpenFlow action.
+ *
+ * @param factory OpenFlow factory
+ * @param extensionInstruction extension instruction
+ * @return OpenFlow action
+ */
+ OFAction mapInstruction(OFFactory factory, ExtensionInstruction extensionInstruction);
+
+ /**
+ * Maps an OpenFlow action to an extension instruction.
+ *
+ * @param action OpenFlow action
+ * @return extension instruction
+ */
+ ExtensionInstruction mapAction(OFAction action);
+
+}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
index 2c01e96..4d5b6b2 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
@@ -28,6 +28,11 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.Lambda;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.DefaultFlowEntry;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -39,6 +44,7 @@
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.ExtensionInterpreter;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
@@ -106,7 +112,9 @@
private final FlowType type;
- public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) {
+ private final DriverService driverService;
+
+ public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry, DriverService driverService) {
this.stat = entry;
this.match = entry.getMatch();
this.instructions = getInstructions(entry);
@@ -114,9 +122,10 @@
this.removed = null;
this.flowMod = null;
this.type = FlowType.STAT;
+ this.driverService = driverService;
}
- public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) {
+ public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed, DriverService driverService) {
this.match = removed.getMatch();
this.removed = removed;
@@ -125,10 +134,10 @@
this.stat = null;
this.flowMod = null;
this.type = FlowType.REMOVED;
-
+ this.driverService = driverService;
}
- public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) {
+ public FlowEntryBuilder(Dpid dpid, OFFlowMod fm, DriverService driverService) {
this.match = fm.getMatch();
this.dpid = dpid;
this.instructions = getInstructions(fm);
@@ -136,6 +145,7 @@
this.flowMod = fm;
this.stat = null;
this.removed = null;
+ this.driverService = driverService;
}
public FlowEntry build(FlowEntryState... state) {
@@ -307,7 +317,7 @@
break;
case SET_FIELD:
OFActionSetField setField = (OFActionSetField) act;
- handleSetField(builder, setField.getField());
+ handleSetField(builder, setField);
break;
case POP_MPLS:
OFActionPopMpls popMpls = (OFActionPopMpls) act;
@@ -363,7 +373,8 @@
}
- private void handleSetField(TrafficTreatment.Builder builder, OFOxm<?> oxm) {
+ private void handleSetField(TrafficTreatment.Builder builder, OFActionSetField action) {
+ OFOxm<?> oxm = action.getField();
switch (oxm.getMatchField().id) {
case VLAN_PCP:
@SuppressWarnings("unchecked")
@@ -432,6 +443,13 @@
OFOxm<TransportPort> udpsrc = (OFOxm<TransportPort>) oxm;
builder.setUdpSrc(TpPort.tpPort(udpsrc.getValue().getPort()));
break;
+ case TUNNEL_IPV4_DST:
+ DriverHandler driver = getDriver(dpid);
+ ExtensionInterpreter interpreter = driver.behaviour(ExtensionInterpreter.class);
+ if (interpreter != null) {
+ builder.extension(interpreter.mapAction(action), DeviceId.deviceId(Dpid.uri(dpid)));
+ }
+ break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
@@ -697,4 +715,11 @@
}
return builder.build();
}
+
+ private DriverHandler getDriver(Dpid dpid) {
+ DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));
+ Driver driver = driverService.getDriver(deviceId);
+ DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
+ return handler;
+ }
}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index e050524..7eca492 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -15,16 +15,13 @@
*/
package org.onosproject.provider.of.flow.impl;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Optional;
-
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.Ip6Prefix;
import org.onlab.packet.VlanId;
import org.onosproject.net.OchSignal;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.criteria.Criterion;
@@ -85,6 +82,10 @@
import org.projectfloodlight.openflow.types.VlanVid;
import org.slf4j.Logger;
+import java.util.Optional;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Builder for OpenFlow flow mods based on FlowRules.
*/
@@ -96,6 +97,7 @@
private final FlowRule flowRule;
private final TrafficSelector selector;
protected final Long xid;
+ protected final Optional<DriverService> driverService;
/**
* Creates a new flow mod builder.
@@ -107,12 +109,13 @@
*/
public static FlowModBuilder builder(FlowRule flowRule,
OFFactory factory,
- Optional<Long> xid) {
+ Optional<Long> xid,
+ Optional<DriverService> driverService) {
switch (factory.getVersion()) {
case OF_10:
- return new FlowModBuilderVer10(flowRule, factory, xid);
+ return new FlowModBuilderVer10(flowRule, factory, xid, driverService);
case OF_13:
- return new FlowModBuilderVer13(flowRule, factory, xid);
+ return new FlowModBuilderVer13(flowRule, factory, xid, driverService);
default:
throw new UnsupportedOperationException(
"No flow mod builder for protocol version " + factory.getVersion());
@@ -126,12 +129,13 @@
* @param factory the OpenFlow factory to use to build the flow mod
* @param xid the transaction ID
*/
- protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
+ protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
+ Optional<DriverService> driverService) {
this.factory = factory;
this.flowRule = flowRule;
this.selector = flowRule.selector();
this.xid = xid.orElse(0L);
-
+ this.driverService = driverService;
}
/**
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
index f77819d..c789841 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
@@ -17,6 +17,7 @@
import org.onlab.packet.Ip4Address;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instruction;
@@ -68,8 +69,9 @@
* @param xid the transaction ID
*/
protected FlowModBuilderVer10(FlowRule flowRule,
- OFFactory factory, Optional<Long> xid) {
- super(flowRule, factory, xid);
+ OFFactory factory, Optional<Long> xid,
+ Optional<DriverService> driverService) {
+ super(flowRule, factory, xid, driverService);
this.treatment = flowRule.treatment();
}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index 64b4360..a99aa81 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -18,10 +18,16 @@
import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.ExtensionInstruction;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
@@ -34,15 +40,16 @@
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
+import org.onosproject.openflow.controller.ExtensionInterpreter;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFFlowDelete;
@@ -88,6 +95,7 @@
private static final int OFPCML_NO_BUFFER = 0xffff;
private final TrafficTreatment treatment;
+ private final DeviceId deviceId;
/**
* Constructor for a flow mod builder for OpenFlow 1.3.
@@ -96,10 +104,12 @@
* @param factory the OpenFlow factory to use to build the flow mod
* @param xid the transaction ID
*/
- protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
- super(flowRule, factory, xid);
+ protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
+ Optional<DriverService> driverService) {
+ super(flowRule, factory, xid, driverService);
this.treatment = flowRule.treatment();
+ this.deviceId = flowRule.deviceId();
}
@Override
@@ -256,6 +266,10 @@
//FIXME: should not occur here.
tableFound = true;
break;
+ case EXTENSION:
+ actions.add(buildExtensionAction(((Instructions.ExtensionInstructionWrapper) i)
+ .extensionInstruction()));
+ break;
default:
log.warn("Instruction type {} not yet implemented.", i.type());
}
@@ -467,4 +481,20 @@
return null;
}
+ private OFAction buildExtensionAction(ExtensionInstruction i) {
+ if (!driverService.isPresent()) {
+ log.error("No driver service present");
+ return null;
+ }
+ Driver driver = driverService.get().getDriver(deviceId);
+ if (driver.hasBehaviour(ExtensionInterpreter.class)) {
+ DefaultDriverHandler handler =
+ new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
+ ExtensionInterpreter interpreter = handler.behaviour(ExtensionInterpreter.class);
+ return interpreter.mapInstruction(factory(), i);
+ }
+
+ return null;
+ }
+
}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
index 487cae9..d5186fa 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
@@ -16,21 +16,10 @@
package org.onosproject.provider.of.flow.impl;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-
import org.onosproject.net.flow.DefaultTypedFlowEntry;
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowId;
@@ -47,9 +36,19 @@
import org.projectfloodlight.openflow.types.TableId;
import org.slf4j.Logger;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.flow.TypedStoredFlowEntry.*;
+import static org.onosproject.net.flow.TypedStoredFlowEntry.FlowLiveType;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -232,7 +231,8 @@
// send openflow flow stats request message with getting the specific flow entry(fe) to a given switch sw
private void ofFlowStatsRequestFlowSend(FlowEntry fe) {
// set find match
- Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty()).buildMatch();
+ Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty(),
+ Optional.empty()).buildMatch();
// set find tableId
TableId tableId = TableId.of(fe.tableId());
// set output port
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
index 6374ca5..b37cb42 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
@@ -21,7 +21,6 @@
import com.google.common.cache.RemovalNotification;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -32,6 +31,7 @@
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.CompletedBatchOperation;
import org.onosproject.net.flow.DefaultTableStatisticsEntry;
import org.onosproject.net.flow.FlowEntry;
@@ -61,12 +61,12 @@
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
-import org.projectfloodlight.openflow.protocol.OFTableStatsReply;
-import org.projectfloodlight.openflow.protocol.OFTableStatsEntry;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsType;
+import org.projectfloodlight.openflow.protocol.OFTableStatsEntry;
+import org.projectfloodlight.openflow.protocol.OFTableStatsReply;
import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg;
import org.slf4j.Logger;
@@ -106,6 +106,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DriverService driverService;
+
private static final int DEFAULT_POLL_FREQUENCY = 5;
@Property(name = "flowPollFrequency", intValue = DEFAULT_POLL_FREQUENCY,
label = "Frequency (in seconds) for polling flow statistics")
@@ -269,7 +272,7 @@
return;
}
sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
- Optional.empty()).buildFlowAdd());
+ Optional.empty(), Optional.of(driverService)).buildFlowAdd());
if (adaptiveFlowSampling) {
// Add TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
@@ -298,7 +301,7 @@
return;
}
sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
- Optional.empty()).buildFlowDel());
+ Optional.empty(), Optional.of(driverService)).buildFlowDel());
if (adaptiveFlowSampling) {
// Remove TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
@@ -334,7 +337,8 @@
continue;
}
FlowModBuilder builder =
- FlowModBuilder.builder(fbe.target(), sw.factory(), Optional.of(batch.id()));
+ FlowModBuilder.builder(fbe.target(), sw.factory(),
+ Optional.of(batch.id()), Optional.of(driverService));
NewAdaptiveFlowStatsCollector collector = afsCollectors.get(dpid);
switch (fbe.operator()) {
case ADD:
@@ -423,7 +427,7 @@
case FLOW_REMOVED:
OFFlowRemoved removed = (OFFlowRemoved) msg;
- FlowEntry fr = new FlowEntryBuilder(dpid, removed).build();
+ FlowEntry fr = new FlowEntryBuilder(dpid, removed, driverService).build();
providerService.flowRemoved(fr);
if (adaptiveFlowSampling) {
@@ -474,7 +478,7 @@
InternalCacheEntry entry =
pendingBatches.getIfPresent(msg.getXid());
if (entry != null) {
- entry.appendFailure(new FlowEntryBuilder(dpid, fm).build());
+ entry.appendFailure(new FlowEntryBuilder(dpid, fm, driverService).build());
} else {
log.error("No matching batch for this error: {}", error);
}
@@ -501,7 +505,7 @@
DeviceId did = DeviceId.deviceId(Dpid.uri(dpid));
List<FlowEntry> flowEntries = replies.getEntries().stream()
- .map(entry -> new FlowEntryBuilder(dpid, entry).build())
+ .map(entry -> new FlowEntryBuilder(dpid, entry, driverService).build())
.collect(Collectors.toList());
if (adaptiveFlowSampling) {