Jonathan Hart
Committed by Gerrit Code Review

Generic extensions to the treatment API to support protocol extensions like

OF experimenter actions.

Change-Id: I88cc5896d17fdbf89807f911f9c23e4f19f6a5ad
Showing 21 changed files with 842 additions and 43 deletions
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net.behaviour;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onosproject.net.driver.HandlerBehaviour;
21 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
22 +import org.onosproject.net.flow.instructions.ExtensionType;
23 +
24 +/**
25 + * Provides access to the extension implemented by this driver.
26 + */
27 +@Beta
28 +public interface ExtensionResolver extends HandlerBehaviour {
29 +
30 + /**
31 + * Gets an extension instruction instance of the specified type, if supported
32 + * by the driver.
33 + *
34 + * @param type type of extension to get
35 + * @return extension instruction
36 + * @throws UnsupportedOperationException if the extension type is not
37 + * supported by this driver
38 + */
39 + ExtensionInstruction getExtensionInstruction(ExtensionType type);
40 +}
...@@ -27,8 +27,10 @@ import org.onlab.packet.MplsLabel; ...@@ -27,8 +27,10 @@ import org.onlab.packet.MplsLabel;
27 import org.onlab.packet.TpPort; 27 import org.onlab.packet.TpPort;
28 import org.onlab.packet.VlanId; 28 import org.onlab.packet.VlanId;
29 import org.onosproject.core.GroupId; 29 import org.onosproject.core.GroupId;
30 +import org.onosproject.net.DeviceId;
30 import org.onosproject.net.IndexedLambda; 31 import org.onosproject.net.IndexedLambda;
31 import org.onosproject.net.PortNumber; 32 import org.onosproject.net.PortNumber;
33 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
32 import org.onosproject.net.flow.instructions.Instruction; 34 import org.onosproject.net.flow.instructions.Instruction;
33 import org.onosproject.net.flow.instructions.Instructions; 35 import org.onosproject.net.flow.instructions.Instructions;
34 import org.onosproject.net.meter.MeterId; 36 import org.onosproject.net.meter.MeterId;
...@@ -244,6 +246,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -244,6 +246,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
244 case L2MODIFICATION: 246 case L2MODIFICATION:
245 case L3MODIFICATION: 247 case L3MODIFICATION:
246 case L4MODIFICATION: 248 case L4MODIFICATION:
249 + case EXTENSION:
247 current.add(instruction); 250 current.add(instruction);
248 break; 251 break;
249 case TABLE: 252 case TABLE:
...@@ -481,6 +484,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -481,6 +484,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
481 } 484 }
482 485
483 @Override 486 @Override
487 + public TrafficTreatment.Builder extension(ExtensionInstruction extension,
488 + DeviceId deviceId) {
489 + return add(Instructions.extension(extension, deviceId));
490 + }
491 +
492 + @Override
484 public TrafficTreatment build() { 493 public TrafficTreatment build() {
485 if (deferred.size() == 0 && immediate.size() == 0 494 if (deferred.size() == 0 && immediate.size() == 0
486 && table == null && !clear) { 495 && table == null && !clear) {
......
...@@ -24,7 +24,9 @@ import org.onlab.packet.MplsLabel; ...@@ -24,7 +24,9 @@ import org.onlab.packet.MplsLabel;
24 import org.onlab.packet.TpPort; 24 import org.onlab.packet.TpPort;
25 import org.onlab.packet.VlanId; 25 import org.onlab.packet.VlanId;
26 import org.onosproject.core.GroupId; 26 import org.onosproject.core.GroupId;
27 +import org.onosproject.net.DeviceId;
27 import org.onosproject.net.PortNumber; 28 import org.onosproject.net.PortNumber;
29 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
28 import org.onosproject.net.flow.instructions.Instruction; 30 import org.onosproject.net.flow.instructions.Instruction;
29 import org.onosproject.net.flow.instructions.Instructions; 31 import org.onosproject.net.flow.instructions.Instructions;
30 import org.onosproject.net.meter.MeterId; 32 import org.onosproject.net.meter.MeterId;
...@@ -413,6 +415,15 @@ public interface TrafficTreatment { ...@@ -413,6 +415,15 @@ public interface TrafficTreatment {
413 Builder setUdpDst(TpPort port); 415 Builder setUdpDst(TpPort port);
414 416
415 /** 417 /**
418 + * Uses an extension treatment.
419 + *
420 + * @param extension extension treatment
421 + * @param deviceId device ID
422 + * @return a treatment builder
423 + */
424 + Builder extension(ExtensionInstruction extension, DeviceId deviceId);
425 +
426 + /**
416 * Builds an immutable traffic treatment descriptor. 427 * Builds an immutable traffic treatment descriptor.
417 * <p> 428 * <p>
418 * If the treatment is empty when build() is called, it will add a default 429 * If the treatment is empty when build() is called, it will add a default
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net.flow.instructions;
18 +
19 +import java.lang.reflect.Field;
20 +import java.util.ArrayList;
21 +import java.util.List;
22 +
23 +/**
24 + * Abstract implementation of the set/get property methods of ExtensionInstruction.
25 + */
26 +public abstract class AbstractExtensionInstruction implements ExtensionInstruction {
27 +
28 + private static final String INVALID_KEY = "Invalid property key: ";
29 + private static final String INVALID_TYPE = "Given type does not match field type: ";
30 +
31 + @Override
32 + public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
33 + Class<?> clazz = this.getClass();
34 + try {
35 + Field field = clazz.getDeclaredField(key);
36 + field.setAccessible(true);
37 + field.set(this, value);
38 + } catch (NoSuchFieldException | IllegalAccessException e) {
39 + throw new ExtensionPropertyException(INVALID_KEY + key);
40 + }
41 + }
42 +
43 + @Override
44 + public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
45 + Class<?> clazz = this.getClass();
46 + try {
47 + Field field = clazz.getDeclaredField(key);
48 + field.setAccessible(true);
49 + @SuppressWarnings("unchecked")
50 + T result = (T) field.get(this);
51 + return result;
52 + } catch (NoSuchFieldException | IllegalAccessException e) {
53 + throw new ExtensionPropertyException(INVALID_KEY + key);
54 + } catch (ClassCastException e) {
55 + throw new ExtensionPropertyException(INVALID_TYPE + key);
56 + }
57 + }
58 +
59 + @Override
60 + public List<String> getProperties() {
61 + Class<?> clazz = this.getClass();
62 +
63 + List<String> fields = new ArrayList<>();
64 +
65 + for (Field field : clazz.getDeclaredFields()) {
66 + fields.add(field.getName());
67 + }
68 +
69 + return fields;
70 + }
71 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net.flow.instructions;
18 +
19 +import java.util.List;
20 +
21 +/**
22 + * An extensible instruction type.
23 + */
24 +public interface ExtensionInstruction {
25 +
26 + /**
27 + * Gets the type of the extension instruction.
28 + *
29 + * @return type
30 + */
31 + ExtensionType type();
32 +
33 + /**
34 + * Sets a property on the extension instruction.
35 + *
36 + * @param key property key
37 + * @param value value to set for the given key
38 + * @param <T> class of the value
39 + * @throws ExtensionPropertyException if the given key is not a valid
40 + * property on this extension instruction
41 + */
42 + <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
43 +
44 + /**
45 + * Gets a property value of an extension instruction.
46 + *
47 + * @param key property key
48 + * @param <T> class of the value
49 + * @return value of the property
50 + * @throws ExtensionPropertyException if the given key is not a valid
51 + * property on this extension instruction
52 + */
53 + <T> T getPropertyValue(String key) throws ExtensionPropertyException;
54 +
55 + /**
56 + * Gets a list of all properties on the extension instruction.
57 + *
58 + * @return list of properties
59 + */
60 + List<String> getProperties();
61 +
62 + /**
63 + * Serialize the extension instruction to a byte array.
64 + *
65 + * @return byte array
66 + */
67 + byte[] serialize();
68 +
69 + /**
70 + * Deserialize the extension instruction from a byte array. The properties
71 + * of this object will be overwritten with the data in the byte array.
72 + *
73 + * @param data input byte array
74 + */
75 + void deserialize(byte[] data);
76 +
77 +
78 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net.flow.instructions;
18 +
19 +/**
20 + * Exception indicating there was an error while setting/getting an extension
21 + * instruction property.
22 + */
23 +public class ExtensionPropertyException extends Exception {
24 +
25 + public ExtensionPropertyException(String message) {
26 + super(message);
27 + }
28 +
29 + public ExtensionPropertyException(String message, Throwable cause) {
30 + super(message, cause);
31 + }
32 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net.flow.instructions;
18 +
19 +import com.google.common.annotations.Beta;
20 +import com.google.common.base.MoreObjects;
21 +
22 +import java.util.Objects;
23 +
24 +/**
25 + * Type of extension instructions.
26 + */
27 +@Beta
28 +public final class ExtensionType {
29 +
30 + /**
31 + * A list of well-known named extension instruction type codes.
32 + */
33 + public enum ExtensionTypes {
34 + // TODO fix type numbers to include experimenter id
35 + NICIRA_SET_TUNNEL_DST(31);
36 +
37 + private ExtensionType type;
38 +
39 + /**
40 + * Creates a new named extension instruction type.
41 + *
42 + * @param type type code
43 + */
44 + ExtensionTypes(int type) {
45 + this.type = new ExtensionType(type);
46 + }
47 +
48 + /**
49 + * Gets the extension type object for this named type code.
50 + *
51 + * @return extension type object
52 + */
53 + public ExtensionType type() {
54 + return type;
55 + }
56 + }
57 +
58 + private final int type;
59 +
60 + /**
61 + * Creates an extension type with the given int type code.
62 + *
63 + * @param type type code
64 + */
65 + public ExtensionType(int type) {
66 + this.type = type;
67 + }
68 +
69 + @Override
70 + public int hashCode() {
71 + return Objects.hash(type);
72 + }
73 +
74 + @Override
75 + public boolean equals(Object obj) {
76 + if (this == obj) {
77 + return true;
78 + }
79 + if (obj instanceof ExtensionType) {
80 + final ExtensionType that = (ExtensionType) obj;
81 + return this.type == that.type;
82 + }
83 + return false;
84 + }
85 +
86 + @Override
87 + public String toString() {
88 + return MoreObjects.toStringHelper(ExtensionType.class)
89 + .add("type", type)
90 + .toString();
91 + }
92 +}
...@@ -92,7 +92,12 @@ public interface Instruction { ...@@ -92,7 +92,12 @@ public interface Instruction {
92 /** 92 /**
93 * Signifies that the traffic should be modified in L4 way. 93 * Signifies that the traffic should be modified in L4 way.
94 */ 94 */
95 - L4MODIFICATION 95 + L4MODIFICATION,
96 +
97 + /**
98 + * Signifies that an extension instruction will be used.
99 + */
100 + EXTENSION
96 } 101 }
97 102
98 /** 103 /**
......
...@@ -22,6 +22,7 @@ import org.onlab.packet.MplsLabel; ...@@ -22,6 +22,7 @@ import org.onlab.packet.MplsLabel;
22 import org.onlab.packet.TpPort; 22 import org.onlab.packet.TpPort;
23 import org.onlab.packet.VlanId; 23 import org.onlab.packet.VlanId;
24 import org.onosproject.core.GroupId; 24 import org.onosproject.core.GroupId;
25 +import org.onosproject.net.DeviceId;
25 import org.onosproject.net.IndexedLambda; 26 import org.onosproject.net.IndexedLambda;
26 import org.onosproject.net.Lambda; 27 import org.onosproject.net.Lambda;
27 import org.onosproject.net.OchSignal; 28 import org.onosproject.net.OchSignal;
...@@ -480,6 +481,20 @@ public final class Instructions { ...@@ -480,6 +481,20 @@ public final class Instructions {
480 } 481 }
481 482
482 /** 483 /**
484 + * Creates an extension instruction.
485 + *
486 + * @param extension extension instruction
487 + * @param deviceId device ID
488 + * @return extension instruction
489 + */
490 + public static ExtensionInstructionWrapper extension(ExtensionInstruction extension,
491 + DeviceId deviceId) {
492 + checkNotNull(extension, "Extension instruction cannot be null");
493 + checkNotNull(deviceId, "Device ID cannot be null");
494 + return new ExtensionInstructionWrapper(extension, deviceId);
495 + }
496 +
497 + /**
483 * Drop instruction. 498 * Drop instruction.
484 */ 499 */
485 @Deprecated 500 @Deprecated
...@@ -820,6 +835,59 @@ public final class Instructions { ...@@ -820,6 +835,59 @@ public final class Instructions {
820 } 835 }
821 } 836 }
822 837
838 + /**
839 + * Extension instruction.
840 + */
841 + public static class ExtensionInstructionWrapper implements Instruction {
842 + private final ExtensionInstruction extensionInstruction;
843 + private final DeviceId deviceId;
844 +
845 + ExtensionInstructionWrapper(ExtensionInstruction extension, DeviceId deviceId) {
846 + extensionInstruction = extension;
847 + this.deviceId = deviceId;
848 + }
849 +
850 + public ExtensionInstruction extensionInstruction() {
851 + return extensionInstruction;
852 + }
853 +
854 + public DeviceId deviceId() {
855 + return deviceId;
856 + }
857 +
858 + @Override
859 + public Type type() {
860 + return Type.EXTENSION;
861 + }
862 +
863 + @Override
864 + public String toString() {
865 + return toStringHelper(type().toString())
866 + .add("extension", extensionInstruction)
867 + .add("deviceId", deviceId)
868 + .toString();
869 + }
870 +
871 + @Override
872 + public int hashCode() {
873 + return Objects.hash(type().ordinal(), extensionInstruction, deviceId);
874 + }
875 +
876 + @Override
877 + public boolean equals(Object obj) {
878 + if (this == obj) {
879 + return true;
880 + }
881 + if (obj instanceof ExtensionInstructionWrapper) {
882 + ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
883 + return Objects.equals(extensionInstruction, that.extensionInstruction)
884 + && Objects.equals(deviceId, that.deviceId);
885 +
886 + }
887 + return false;
888 + }
889 + }
890 +
823 } 891 }
824 892
825 893
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.store.serializers;
18 +
19 +import com.esotericsoftware.kryo.Kryo;
20 +import com.esotericsoftware.kryo.Serializer;
21 +import com.esotericsoftware.kryo.io.Input;
22 +import com.esotericsoftware.kryo.io.Output;
23 +import org.onlab.osgi.DefaultServiceDirectory;
24 +import org.onosproject.net.DeviceId;
25 +import org.onosproject.net.behaviour.ExtensionResolver;
26 +import org.onosproject.net.driver.DefaultDriverData;
27 +import org.onosproject.net.driver.DefaultDriverHandler;
28 +import org.onosproject.net.driver.DriverHandler;
29 +import org.onosproject.net.driver.DriverService;
30 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
31 +import org.onosproject.net.flow.instructions.ExtensionType;
32 +import org.onosproject.net.flow.instructions.Instructions;
33 +
34 +/**
35 + * Created by jono on 10/29/15.
36 + */
37 +public class ExtensionInstructionSerializer extends
38 + Serializer<Instructions.ExtensionInstructionWrapper> {
39 +
40 + public ExtensionInstructionSerializer() {
41 + super(false, true);
42 + }
43 +
44 + @Override
45 + public void write(Kryo kryo, Output output, Instructions.ExtensionInstructionWrapper object) {
46 + kryo.writeClassAndObject(output, object.extensionInstruction().type());
47 + kryo.writeClassAndObject(output, object.deviceId());
48 +
49 + kryo.writeClassAndObject(output, object.extensionInstruction().serialize());
50 +
51 + }
52 +
53 + @Override
54 + public Instructions.ExtensionInstructionWrapper read(Kryo kryo, Input input,
55 + Class<Instructions.ExtensionInstructionWrapper> type) {
56 + ExtensionType exType = (ExtensionType) kryo.readClassAndObject(input);
57 + DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
58 +
59 + DriverService driverService = DefaultServiceDirectory.getService(DriverService.class);
60 + DriverHandler handler = new DefaultDriverHandler(
61 + new DefaultDriverData(driverService.getDriver(deviceId), deviceId));
62 +
63 + ExtensionResolver resolver = handler.behaviour(ExtensionResolver.class);
64 +
65 + ExtensionInstruction instruction = resolver.getExtensionInstruction(exType);
66 +
67 + byte[] bytes = (byte[]) kryo.readClassAndObject(input);
68 +
69 + instruction.deserialize(bytes);
70 +
71 + return Instructions.extension(instruction, deviceId);
72 + }
73 +}
...@@ -128,6 +128,7 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion; ...@@ -128,6 +128,7 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion;
128 import org.onosproject.net.flow.criteria.UdpPortCriterion; 128 import org.onosproject.net.flow.criteria.UdpPortCriterion;
129 import org.onosproject.net.flow.criteria.VlanIdCriterion; 129 import org.onosproject.net.flow.criteria.VlanIdCriterion;
130 import org.onosproject.net.flow.criteria.VlanPcpCriterion; 130 import org.onosproject.net.flow.criteria.VlanPcpCriterion;
131 +import org.onosproject.net.flow.instructions.ExtensionType;
131 import org.onosproject.net.flow.instructions.Instructions; 132 import org.onosproject.net.flow.instructions.Instructions;
132 import org.onosproject.net.flow.instructions.L0ModificationInstruction; 133 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
133 import org.onosproject.net.flow.instructions.L1ModificationInstruction; 134 import org.onosproject.net.flow.instructions.L1ModificationInstruction;
...@@ -450,6 +451,8 @@ public final class KryoNamespaces { ...@@ -450,6 +451,8 @@ public final class KryoNamespaces {
450 .register(new HostLocationSerializer(), HostLocation.class) 451 .register(new HostLocationSerializer(), HostLocation.class)
451 .register(new DefaultOutboundPacketSerializer(), DefaultOutboundPacket.class) 452 .register(new DefaultOutboundPacketSerializer(), DefaultOutboundPacket.class)
452 .register(new AnnotationsSerializer(), DefaultAnnotations.class) 453 .register(new AnnotationsSerializer(), DefaultAnnotations.class)
454 + .register(new ExtensionInstructionSerializer(), Instructions.ExtensionInstructionWrapper.class)
455 + .register(ExtensionType.class)
453 .register(Versioned.class) 456 .register(Versioned.class)
454 .register(MapEvent.class) 457 .register(MapEvent.class)
455 .register(MapEvent.Type.class) 458 .register(MapEvent.Type.class)
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.driver.extensions;
18 +
19 +import org.onlab.packet.Ip4Address;
20 +import org.onosproject.net.behaviour.ExtensionResolver;
21 +import org.onosproject.net.driver.AbstractHandlerBehaviour;
22 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
23 +import org.onosproject.net.flow.instructions.ExtensionType;
24 +import org.onosproject.openflow.controller.ExtensionInterpreter;
25 +import org.projectfloodlight.openflow.protocol.OFActionType;
26 +import org.projectfloodlight.openflow.protocol.OFFactory;
27 +import org.projectfloodlight.openflow.protocol.action.OFAction;
28 +import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
29 +import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
30 +import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst;
31 +import org.projectfloodlight.openflow.types.IPv4Address;
32 +
33 +/**
34 + * Interpreter for Nicira OpenFlow extensions.
35 + */
36 +public class NiciraExtensionInterpreter extends AbstractHandlerBehaviour
37 + implements ExtensionInterpreter, ExtensionResolver {
38 +
39 + @Override
40 + public boolean supported(ExtensionType extensionType) {
41 + if (extensionType.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST)) {
42 + return true;
43 + }
44 +
45 + return false;
46 + }
47 +
48 + @Override
49 + public OFAction mapInstruction(OFFactory factory, ExtensionInstruction extensionInstruction) {
50 + ExtensionType type = extensionInstruction.type();
51 + if (type.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) {
52 + NiciraSetTunnelDst tunnelDst = (NiciraSetTunnelDst) extensionInstruction;
53 + return factory.actions().setField(factory.oxms().tunnelIpv4Dst(
54 + IPv4Address.of(tunnelDst.tunnelDst().toInt())));
55 + }
56 + return null;
57 + }
58 +
59 + @Override
60 + public ExtensionInstruction mapAction(OFAction action) {
61 + if (action.getType().equals(OFActionType.SET_FIELD)) {
62 + OFActionSetField setFieldAction = (OFActionSetField) action;
63 + OFOxm<?> oxm = setFieldAction.getField();
64 + switch (oxm.getMatchField().id) {
65 + case TUNNEL_IPV4_DST:
66 + OFOxmTunnelIpv4Dst tunnelIpv4Dst = (OFOxmTunnelIpv4Dst) oxm;
67 + return new NiciraSetTunnelDst(Ip4Address.valueOf(tunnelIpv4Dst.getValue().getInt()));
68 + default:
69 + throw new UnsupportedOperationException(
70 + "Driver does not support extension type " + oxm.getMatchField().id);
71 + }
72 + }
73 + return null;
74 + }
75 +
76 + @Override
77 + public ExtensionInstruction getExtensionInstruction(ExtensionType type) {
78 + if (type.equals(ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type())) {
79 + return new NiciraSetTunnelDst();
80 + }
81 + throw new UnsupportedOperationException(
82 + "Driver does not support extension type " + type.toString());
83 + }
84 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.driver.extensions;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onlab.packet.Ip4Address;
21 +import org.onlab.util.KryoNamespace;
22 +import org.onosproject.net.flow.instructions.AbstractExtensionInstruction;
23 +import org.onosproject.net.flow.instructions.ExtensionType;
24 +import org.onosproject.store.serializers.Ip4AddressSerializer;
25 +
26 +import java.util.Objects;
27 +
28 +import static com.google.common.base.Preconditions.checkNotNull;
29 +
30 +/**
31 + * Nicira set tunnel destination extension instruction.
32 + */
33 +public class NiciraSetTunnelDst extends AbstractExtensionInstruction {
34 +
35 + private Ip4Address tunnelDst;
36 +
37 + private final KryoNamespace appKryo = new KryoNamespace.Builder()
38 + .register(new Ip4AddressSerializer(), Ip4Address.class)
39 + .register(byte[].class)
40 + .build();
41 +
42 + /**
43 + * Creates a new set tunnel destination instruction.
44 + */
45 + NiciraSetTunnelDst() {
46 + tunnelDst = null;
47 + }
48 +
49 + /**
50 + * Creates a new set tunnel destination instruction with a particular IPv4
51 + * address.
52 + */
53 + NiciraSetTunnelDst(Ip4Address tunnelDst) {
54 + checkNotNull(tunnelDst);
55 + this.tunnelDst = tunnelDst;
56 + }
57 +
58 + /**
59 + * Gets the tunnel destination IPv4 address.
60 + *
61 + * @return tunnel destination IPv4 address
62 + */
63 + public Ip4Address tunnelDst() {
64 + return tunnelDst;
65 + }
66 +
67 + @Override
68 + public ExtensionType type() {
69 + return ExtensionType.ExtensionTypes.NICIRA_SET_TUNNEL_DST.type();
70 + }
71 +
72 + @Override
73 + public void deserialize(byte[] data) {
74 + tunnelDst = appKryo.deserialize(data);
75 + }
76 +
77 + @Override
78 + public byte[] serialize() {
79 + return appKryo.serialize(tunnelDst);
80 + }
81 +
82 + @Override
83 + public int hashCode() {
84 + return Objects.hash(tunnelDst);
85 + }
86 +
87 + @Override
88 + public boolean equals(Object obj) {
89 + if (this == obj) {
90 + return true;
91 + }
92 + if (obj instanceof NiciraSetTunnelDst) {
93 + NiciraSetTunnelDst that = (NiciraSetTunnelDst) obj;
94 + return Objects.equals(tunnelDst, that.tunnelDst);
95 +
96 + }
97 + return false;
98 + }
99 +
100 + @Override
101 + public String toString() {
102 + return MoreObjects.toStringHelper(getClass())
103 + .add("tunnelDst", tunnelDst)
104 + .toString();
105 + }
106 +}
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
32 impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/> 32 impl="org.onosproject.driver.handshaker.NiciraSwitchHandshaker"/>
33 <behaviour api="org.onosproject.net.behaviour.ControllerConfig" 33 <behaviour api="org.onosproject.net.behaviour.ControllerConfig"
34 impl="org.onosproject.driver.ovsdb.OvsdbControllerConfig"/> 34 impl="org.onosproject.driver.ovsdb.OvsdbControllerConfig"/>
35 + <behaviour api="org.onosproject.openflow.controller.ExtensionInterpreter"
36 + impl="org.onosproject.driver.extensions.NiciraExtensionInterpreter" />
37 + <behaviour api="org.onosproject.net.behaviour.ExtensionResolver"
38 + impl="org.onosproject.driver.extensions.NiciraExtensionInterpreter" />
35 </driver> 39 </driver>
36 <driver name="ovs-corsa" extends="ovs" 40 <driver name="ovs-corsa" extends="ovs"
37 manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0"> 41 manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0">
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.openflow.controller;
18 +
19 +import com.google.common.annotations.Beta;
20 +import org.onosproject.net.driver.HandlerBehaviour;
21 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
22 +import org.onosproject.net.flow.instructions.ExtensionType;
23 +import org.projectfloodlight.openflow.protocol.OFFactory;
24 +import org.projectfloodlight.openflow.protocol.action.OFAction;
25 +
26 +/**
27 + * Interprets extension instructions and converts them to/from OpenFlow objects.
28 + */
29 +@Beta
30 +public interface ExtensionInterpreter extends HandlerBehaviour {
31 +
32 + /**
33 + * Returns true if the given extension instruction is supported by this
34 + * driver.
35 + *
36 + * @param extensionType extension instruction type
37 + * @return true if the instruction is supported, otherwise false
38 + */
39 + boolean supported(ExtensionType extensionType);
40 +
41 + /**
42 + * Maps an extension instruction to an OpenFlow action.
43 + *
44 + * @param factory OpenFlow factory
45 + * @param extensionInstruction extension instruction
46 + * @return OpenFlow action
47 + */
48 + OFAction mapInstruction(OFFactory factory, ExtensionInstruction extensionInstruction);
49 +
50 + /**
51 + * Maps an OpenFlow action to an extension instruction.
52 + *
53 + * @param action OpenFlow action
54 + * @return extension instruction
55 + */
56 + ExtensionInstruction mapAction(OFAction action);
57 +
58 +}
...@@ -28,6 +28,11 @@ import org.onosproject.core.DefaultGroupId; ...@@ -28,6 +28,11 @@ import org.onosproject.core.DefaultGroupId;
28 import org.onosproject.net.DeviceId; 28 import org.onosproject.net.DeviceId;
29 import org.onosproject.net.Lambda; 29 import org.onosproject.net.Lambda;
30 import org.onosproject.net.PortNumber; 30 import org.onosproject.net.PortNumber;
31 +import org.onosproject.net.driver.DefaultDriverData;
32 +import org.onosproject.net.driver.DefaultDriverHandler;
33 +import org.onosproject.net.driver.Driver;
34 +import org.onosproject.net.driver.DriverHandler;
35 +import org.onosproject.net.driver.DriverService;
31 import org.onosproject.net.flow.DefaultFlowEntry; 36 import org.onosproject.net.flow.DefaultFlowEntry;
32 import org.onosproject.net.flow.DefaultFlowRule; 37 import org.onosproject.net.flow.DefaultFlowRule;
33 import org.onosproject.net.flow.DefaultTrafficSelector; 38 import org.onosproject.net.flow.DefaultTrafficSelector;
...@@ -39,6 +44,7 @@ import org.onosproject.net.flow.TrafficSelector; ...@@ -39,6 +44,7 @@ import org.onosproject.net.flow.TrafficSelector;
39 import org.onosproject.net.flow.TrafficTreatment; 44 import org.onosproject.net.flow.TrafficTreatment;
40 import org.onosproject.net.flow.instructions.Instructions; 45 import org.onosproject.net.flow.instructions.Instructions;
41 import org.onosproject.openflow.controller.Dpid; 46 import org.onosproject.openflow.controller.Dpid;
47 +import org.onosproject.openflow.controller.ExtensionInterpreter;
42 import org.projectfloodlight.openflow.protocol.OFFlowMod; 48 import org.projectfloodlight.openflow.protocol.OFFlowMod;
43 import org.projectfloodlight.openflow.protocol.OFFlowRemoved; 49 import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
44 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; 50 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
...@@ -106,7 +112,9 @@ public class FlowEntryBuilder { ...@@ -106,7 +112,9 @@ public class FlowEntryBuilder {
106 112
107 private final FlowType type; 113 private final FlowType type;
108 114
109 - public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) { 115 + private final DriverService driverService;
116 +
117 + public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry, DriverService driverService) {
110 this.stat = entry; 118 this.stat = entry;
111 this.match = entry.getMatch(); 119 this.match = entry.getMatch();
112 this.instructions = getInstructions(entry); 120 this.instructions = getInstructions(entry);
...@@ -114,9 +122,10 @@ public class FlowEntryBuilder { ...@@ -114,9 +122,10 @@ public class FlowEntryBuilder {
114 this.removed = null; 122 this.removed = null;
115 this.flowMod = null; 123 this.flowMod = null;
116 this.type = FlowType.STAT; 124 this.type = FlowType.STAT;
125 + this.driverService = driverService;
117 } 126 }
118 127
119 - public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) { 128 + public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed, DriverService driverService) {
120 this.match = removed.getMatch(); 129 this.match = removed.getMatch();
121 this.removed = removed; 130 this.removed = removed;
122 131
...@@ -125,10 +134,10 @@ public class FlowEntryBuilder { ...@@ -125,10 +134,10 @@ public class FlowEntryBuilder {
125 this.stat = null; 134 this.stat = null;
126 this.flowMod = null; 135 this.flowMod = null;
127 this.type = FlowType.REMOVED; 136 this.type = FlowType.REMOVED;
128 - 137 + this.driverService = driverService;
129 } 138 }
130 139
131 - public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) { 140 + public FlowEntryBuilder(Dpid dpid, OFFlowMod fm, DriverService driverService) {
132 this.match = fm.getMatch(); 141 this.match = fm.getMatch();
133 this.dpid = dpid; 142 this.dpid = dpid;
134 this.instructions = getInstructions(fm); 143 this.instructions = getInstructions(fm);
...@@ -136,6 +145,7 @@ public class FlowEntryBuilder { ...@@ -136,6 +145,7 @@ public class FlowEntryBuilder {
136 this.flowMod = fm; 145 this.flowMod = fm;
137 this.stat = null; 146 this.stat = null;
138 this.removed = null; 147 this.removed = null;
148 + this.driverService = driverService;
139 } 149 }
140 150
141 public FlowEntry build(FlowEntryState... state) { 151 public FlowEntry build(FlowEntryState... state) {
...@@ -307,7 +317,7 @@ public class FlowEntryBuilder { ...@@ -307,7 +317,7 @@ public class FlowEntryBuilder {
307 break; 317 break;
308 case SET_FIELD: 318 case SET_FIELD:
309 OFActionSetField setField = (OFActionSetField) act; 319 OFActionSetField setField = (OFActionSetField) act;
310 - handleSetField(builder, setField.getField()); 320 + handleSetField(builder, setField);
311 break; 321 break;
312 case POP_MPLS: 322 case POP_MPLS:
313 OFActionPopMpls popMpls = (OFActionPopMpls) act; 323 OFActionPopMpls popMpls = (OFActionPopMpls) act;
...@@ -363,7 +373,8 @@ public class FlowEntryBuilder { ...@@ -363,7 +373,8 @@ public class FlowEntryBuilder {
363 } 373 }
364 374
365 375
366 - private void handleSetField(TrafficTreatment.Builder builder, OFOxm<?> oxm) { 376 + private void handleSetField(TrafficTreatment.Builder builder, OFActionSetField action) {
377 + OFOxm<?> oxm = action.getField();
367 switch (oxm.getMatchField().id) { 378 switch (oxm.getMatchField().id) {
368 case VLAN_PCP: 379 case VLAN_PCP:
369 @SuppressWarnings("unchecked") 380 @SuppressWarnings("unchecked")
...@@ -432,6 +443,13 @@ public class FlowEntryBuilder { ...@@ -432,6 +443,13 @@ public class FlowEntryBuilder {
432 OFOxm<TransportPort> udpsrc = (OFOxm<TransportPort>) oxm; 443 OFOxm<TransportPort> udpsrc = (OFOxm<TransportPort>) oxm;
433 builder.setUdpSrc(TpPort.tpPort(udpsrc.getValue().getPort())); 444 builder.setUdpSrc(TpPort.tpPort(udpsrc.getValue().getPort()));
434 break; 445 break;
446 + case TUNNEL_IPV4_DST:
447 + DriverHandler driver = getDriver(dpid);
448 + ExtensionInterpreter interpreter = driver.behaviour(ExtensionInterpreter.class);
449 + if (interpreter != null) {
450 + builder.extension(interpreter.mapAction(action), DeviceId.deviceId(Dpid.uri(dpid)));
451 + }
452 + break;
435 case ARP_OP: 453 case ARP_OP:
436 case ARP_SHA: 454 case ARP_SHA:
437 case ARP_SPA: 455 case ARP_SPA:
...@@ -697,4 +715,11 @@ public class FlowEntryBuilder { ...@@ -697,4 +715,11 @@ public class FlowEntryBuilder {
697 } 715 }
698 return builder.build(); 716 return builder.build();
699 } 717 }
718 +
719 + private DriverHandler getDriver(Dpid dpid) {
720 + DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));
721 + Driver driver = driverService.getDriver(deviceId);
722 + DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
723 + return handler;
724 + }
700 } 725 }
......
...@@ -15,16 +15,13 @@ ...@@ -15,16 +15,13 @@
15 */ 15 */
16 package org.onosproject.provider.of.flow.impl; 16 package org.onosproject.provider.of.flow.impl;
17 17
18 -import static org.slf4j.LoggerFactory.getLogger;
19 -
20 -import java.util.Optional;
21 -
22 import org.onlab.packet.Ip4Address; 18 import org.onlab.packet.Ip4Address;
23 import org.onlab.packet.Ip4Prefix; 19 import org.onlab.packet.Ip4Prefix;
24 import org.onlab.packet.Ip6Address; 20 import org.onlab.packet.Ip6Address;
25 import org.onlab.packet.Ip6Prefix; 21 import org.onlab.packet.Ip6Prefix;
26 import org.onlab.packet.VlanId; 22 import org.onlab.packet.VlanId;
27 import org.onosproject.net.OchSignal; 23 import org.onosproject.net.OchSignal;
24 +import org.onosproject.net.driver.DriverService;
28 import org.onosproject.net.flow.FlowRule; 25 import org.onosproject.net.flow.FlowRule;
29 import org.onosproject.net.flow.TrafficSelector; 26 import org.onosproject.net.flow.TrafficSelector;
30 import org.onosproject.net.flow.criteria.Criterion; 27 import org.onosproject.net.flow.criteria.Criterion;
...@@ -85,6 +82,10 @@ import org.projectfloodlight.openflow.types.VlanPcp; ...@@ -85,6 +82,10 @@ import org.projectfloodlight.openflow.types.VlanPcp;
85 import org.projectfloodlight.openflow.types.VlanVid; 82 import org.projectfloodlight.openflow.types.VlanVid;
86 import org.slf4j.Logger; 83 import org.slf4j.Logger;
87 84
85 +import java.util.Optional;
86 +
87 +import static org.slf4j.LoggerFactory.getLogger;
88 +
88 /** 89 /**
89 * Builder for OpenFlow flow mods based on FlowRules. 90 * Builder for OpenFlow flow mods based on FlowRules.
90 */ 91 */
...@@ -96,6 +97,7 @@ public abstract class FlowModBuilder { ...@@ -96,6 +97,7 @@ public abstract class FlowModBuilder {
96 private final FlowRule flowRule; 97 private final FlowRule flowRule;
97 private final TrafficSelector selector; 98 private final TrafficSelector selector;
98 protected final Long xid; 99 protected final Long xid;
100 + protected final Optional<DriverService> driverService;
99 101
100 /** 102 /**
101 * Creates a new flow mod builder. 103 * Creates a new flow mod builder.
...@@ -107,12 +109,13 @@ public abstract class FlowModBuilder { ...@@ -107,12 +109,13 @@ public abstract class FlowModBuilder {
107 */ 109 */
108 public static FlowModBuilder builder(FlowRule flowRule, 110 public static FlowModBuilder builder(FlowRule flowRule,
109 OFFactory factory, 111 OFFactory factory,
110 - Optional<Long> xid) { 112 + Optional<Long> xid,
113 + Optional<DriverService> driverService) {
111 switch (factory.getVersion()) { 114 switch (factory.getVersion()) {
112 case OF_10: 115 case OF_10:
113 - return new FlowModBuilderVer10(flowRule, factory, xid); 116 + return new FlowModBuilderVer10(flowRule, factory, xid, driverService);
114 case OF_13: 117 case OF_13:
115 - return new FlowModBuilderVer13(flowRule, factory, xid); 118 + return new FlowModBuilderVer13(flowRule, factory, xid, driverService);
116 default: 119 default:
117 throw new UnsupportedOperationException( 120 throw new UnsupportedOperationException(
118 "No flow mod builder for protocol version " + factory.getVersion()); 121 "No flow mod builder for protocol version " + factory.getVersion());
...@@ -126,12 +129,13 @@ public abstract class FlowModBuilder { ...@@ -126,12 +129,13 @@ public abstract class FlowModBuilder {
126 * @param factory the OpenFlow factory to use to build the flow mod 129 * @param factory the OpenFlow factory to use to build the flow mod
127 * @param xid the transaction ID 130 * @param xid the transaction ID
128 */ 131 */
129 - protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid) { 132 + protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
133 + Optional<DriverService> driverService) {
130 this.factory = factory; 134 this.factory = factory;
131 this.flowRule = flowRule; 135 this.flowRule = flowRule;
132 this.selector = flowRule.selector(); 136 this.selector = flowRule.selector();
133 this.xid = xid.orElse(0L); 137 this.xid = xid.orElse(0L);
134 - 138 + this.driverService = driverService;
135 } 139 }
136 140
137 /** 141 /**
......
...@@ -17,6 +17,7 @@ package org.onosproject.provider.of.flow.impl; ...@@ -17,6 +17,7 @@ package org.onosproject.provider.of.flow.impl;
17 17
18 import org.onlab.packet.Ip4Address; 18 import org.onlab.packet.Ip4Address;
19 import org.onosproject.net.PortNumber; 19 import org.onosproject.net.PortNumber;
20 +import org.onosproject.net.driver.DriverService;
20 import org.onosproject.net.flow.FlowRule; 21 import org.onosproject.net.flow.FlowRule;
21 import org.onosproject.net.flow.TrafficTreatment; 22 import org.onosproject.net.flow.TrafficTreatment;
22 import org.onosproject.net.flow.instructions.Instruction; 23 import org.onosproject.net.flow.instructions.Instruction;
...@@ -68,8 +69,9 @@ public class FlowModBuilderVer10 extends FlowModBuilder { ...@@ -68,8 +69,9 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
68 * @param xid the transaction ID 69 * @param xid the transaction ID
69 */ 70 */
70 protected FlowModBuilderVer10(FlowRule flowRule, 71 protected FlowModBuilderVer10(FlowRule flowRule,
71 - OFFactory factory, Optional<Long> xid) { 72 + OFFactory factory, Optional<Long> xid,
72 - super(flowRule, factory, xid); 73 + Optional<DriverService> driverService) {
74 + super(flowRule, factory, xid, driverService);
73 75
74 this.treatment = flowRule.treatment(); 76 this.treatment = flowRule.treatment();
75 } 77 }
......
...@@ -18,10 +18,16 @@ package org.onosproject.provider.of.flow.impl; ...@@ -18,10 +18,16 @@ package org.onosproject.provider.of.flow.impl;
18 import com.google.common.collect.Lists; 18 import com.google.common.collect.Lists;
19 import org.onlab.packet.Ip4Address; 19 import org.onlab.packet.Ip4Address;
20 import org.onlab.packet.Ip6Address; 20 import org.onlab.packet.Ip6Address;
21 +import org.onosproject.net.DeviceId;
21 import org.onosproject.net.OchSignal; 22 import org.onosproject.net.OchSignal;
22 import org.onosproject.net.PortNumber; 23 import org.onosproject.net.PortNumber;
24 +import org.onosproject.net.driver.DefaultDriverData;
25 +import org.onosproject.net.driver.DefaultDriverHandler;
26 +import org.onosproject.net.driver.Driver;
27 +import org.onosproject.net.driver.DriverService;
23 import org.onosproject.net.flow.FlowRule; 28 import org.onosproject.net.flow.FlowRule;
24 import org.onosproject.net.flow.TrafficTreatment; 29 import org.onosproject.net.flow.TrafficTreatment;
30 +import org.onosproject.net.flow.instructions.ExtensionInstruction;
25 import org.onosproject.net.flow.instructions.Instruction; 31 import org.onosproject.net.flow.instructions.Instruction;
26 import org.onosproject.net.flow.instructions.Instructions; 32 import org.onosproject.net.flow.instructions.Instructions;
27 import org.onosproject.net.flow.instructions.Instructions.GroupInstruction; 33 import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
...@@ -34,15 +40,16 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction; ...@@ -34,15 +40,16 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction;
34 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 40 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
35 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction; 41 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
36 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction; 42 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
43 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
37 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; 44 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
38 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction; 45 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
39 import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions; 46 import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
40 -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
41 import org.onosproject.net.flow.instructions.L3ModificationInstruction; 47 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
42 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 48 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
43 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; 49 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
44 import org.onosproject.net.flow.instructions.L4ModificationInstruction; 50 import org.onosproject.net.flow.instructions.L4ModificationInstruction;
45 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; 51 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
52 +import org.onosproject.openflow.controller.ExtensionInterpreter;
46 import org.projectfloodlight.openflow.protocol.OFFactory; 53 import org.projectfloodlight.openflow.protocol.OFFactory;
47 import org.projectfloodlight.openflow.protocol.OFFlowAdd; 54 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
48 import org.projectfloodlight.openflow.protocol.OFFlowDelete; 55 import org.projectfloodlight.openflow.protocol.OFFlowDelete;
...@@ -88,6 +95,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -88,6 +95,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
88 private static final int OFPCML_NO_BUFFER = 0xffff; 95 private static final int OFPCML_NO_BUFFER = 0xffff;
89 96
90 private final TrafficTreatment treatment; 97 private final TrafficTreatment treatment;
98 + private final DeviceId deviceId;
91 99
92 /** 100 /**
93 * Constructor for a flow mod builder for OpenFlow 1.3. 101 * Constructor for a flow mod builder for OpenFlow 1.3.
...@@ -96,10 +104,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -96,10 +104,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
96 * @param factory the OpenFlow factory to use to build the flow mod 104 * @param factory the OpenFlow factory to use to build the flow mod
97 * @param xid the transaction ID 105 * @param xid the transaction ID
98 */ 106 */
99 - protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) { 107 + protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
100 - super(flowRule, factory, xid); 108 + Optional<DriverService> driverService) {
109 + super(flowRule, factory, xid, driverService);
101 110
102 this.treatment = flowRule.treatment(); 111 this.treatment = flowRule.treatment();
112 + this.deviceId = flowRule.deviceId();
103 } 113 }
104 114
105 @Override 115 @Override
...@@ -256,6 +266,10 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -256,6 +266,10 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
256 //FIXME: should not occur here. 266 //FIXME: should not occur here.
257 tableFound = true; 267 tableFound = true;
258 break; 268 break;
269 + case EXTENSION:
270 + actions.add(buildExtensionAction(((Instructions.ExtensionInstructionWrapper) i)
271 + .extensionInstruction()));
272 + break;
259 default: 273 default:
260 log.warn("Instruction type {} not yet implemented.", i.type()); 274 log.warn("Instruction type {} not yet implemented.", i.type());
261 } 275 }
...@@ -467,4 +481,20 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -467,4 +481,20 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
467 return null; 481 return null;
468 } 482 }
469 483
484 + private OFAction buildExtensionAction(ExtensionInstruction i) {
485 + if (!driverService.isPresent()) {
486 + log.error("No driver service present");
487 + return null;
488 + }
489 + Driver driver = driverService.get().getDriver(deviceId);
490 + if (driver.hasBehaviour(ExtensionInterpreter.class)) {
491 + DefaultDriverHandler handler =
492 + new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
493 + ExtensionInterpreter interpreter = handler.behaviour(ExtensionInterpreter.class);
494 + return interpreter.mapInstruction(factory(), i);
495 + }
496 +
497 + return null;
498 + }
499 +
470 } 500 }
......
...@@ -16,21 +16,10 @@ ...@@ -16,21 +16,10 @@
16 16
17 package org.onosproject.provider.of.flow.impl; 17 package org.onosproject.provider.of.flow.impl;
18 18
19 -import java.util.HashSet;
20 -import java.util.List;
21 -import java.util.Map;
22 -import java.util.Optional;
23 -import java.util.Set;
24 -import java.util.concurrent.TimeUnit;
25 -import java.util.concurrent.ScheduledFuture;
26 -import java.util.concurrent.Executors;
27 -import java.util.concurrent.ScheduledExecutorService;
28 -
29 import com.google.common.base.Objects; 19 import com.google.common.base.Objects;
30 import com.google.common.collect.ImmutableSet; 20 import com.google.common.collect.ImmutableSet;
31 import com.google.common.collect.Maps; 21 import com.google.common.collect.Maps;
32 import com.google.common.collect.Sets; 22 import com.google.common.collect.Sets;
33 -
34 import org.onosproject.net.flow.DefaultTypedFlowEntry; 23 import org.onosproject.net.flow.DefaultTypedFlowEntry;
35 import org.onosproject.net.flow.FlowEntry; 24 import org.onosproject.net.flow.FlowEntry;
36 import org.onosproject.net.flow.FlowId; 25 import org.onosproject.net.flow.FlowId;
...@@ -47,9 +36,19 @@ import org.projectfloodlight.openflow.types.OFPort; ...@@ -47,9 +36,19 @@ import org.projectfloodlight.openflow.types.OFPort;
47 import org.projectfloodlight.openflow.types.TableId; 36 import org.projectfloodlight.openflow.types.TableId;
48 import org.slf4j.Logger; 37 import org.slf4j.Logger;
49 38
39 +import java.util.HashSet;
40 +import java.util.List;
41 +import java.util.Map;
42 +import java.util.Optional;
43 +import java.util.Set;
44 +import java.util.concurrent.Executors;
45 +import java.util.concurrent.ScheduledExecutorService;
46 +import java.util.concurrent.ScheduledFuture;
47 +import java.util.concurrent.TimeUnit;
48 +
50 import static com.google.common.base.Preconditions.checkNotNull; 49 import static com.google.common.base.Preconditions.checkNotNull;
51 import static org.onlab.util.Tools.groupedThreads; 50 import static org.onlab.util.Tools.groupedThreads;
52 -import static org.onosproject.net.flow.TypedStoredFlowEntry.*; 51 +import static org.onosproject.net.flow.TypedStoredFlowEntry.FlowLiveType;
53 import static org.slf4j.LoggerFactory.getLogger; 52 import static org.slf4j.LoggerFactory.getLogger;
54 53
55 /** 54 /**
...@@ -232,7 +231,8 @@ public class NewAdaptiveFlowStatsCollector { ...@@ -232,7 +231,8 @@ public class NewAdaptiveFlowStatsCollector {
232 // send openflow flow stats request message with getting the specific flow entry(fe) to a given switch sw 231 // send openflow flow stats request message with getting the specific flow entry(fe) to a given switch sw
233 private void ofFlowStatsRequestFlowSend(FlowEntry fe) { 232 private void ofFlowStatsRequestFlowSend(FlowEntry fe) {
234 // set find match 233 // set find match
235 - Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty()).buildMatch(); 234 + Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty(),
235 + Optional.empty()).buildMatch();
236 // set find tableId 236 // set find tableId
237 TableId tableId = TableId.of(fe.tableId()); 237 TableId tableId = TableId.of(fe.tableId());
238 // set output port 238 // set output port
......
...@@ -21,7 +21,6 @@ import com.google.common.cache.RemovalCause; ...@@ -21,7 +21,6 @@ import com.google.common.cache.RemovalCause;
21 import com.google.common.cache.RemovalNotification; 21 import com.google.common.cache.RemovalNotification;
22 import com.google.common.collect.Maps; 22 import com.google.common.collect.Maps;
23 import com.google.common.collect.Sets; 23 import com.google.common.collect.Sets;
24 -
25 import org.apache.felix.scr.annotations.Activate; 24 import org.apache.felix.scr.annotations.Activate;
26 import org.apache.felix.scr.annotations.Component; 25 import org.apache.felix.scr.annotations.Component;
27 import org.apache.felix.scr.annotations.Deactivate; 26 import org.apache.felix.scr.annotations.Deactivate;
...@@ -32,6 +31,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -32,6 +31,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
32 import org.onosproject.cfg.ComponentConfigService; 31 import org.onosproject.cfg.ComponentConfigService;
33 import org.onosproject.core.ApplicationId; 32 import org.onosproject.core.ApplicationId;
34 import org.onosproject.net.DeviceId; 33 import org.onosproject.net.DeviceId;
34 +import org.onosproject.net.driver.DriverService;
35 import org.onosproject.net.flow.CompletedBatchOperation; 35 import org.onosproject.net.flow.CompletedBatchOperation;
36 import org.onosproject.net.flow.DefaultTableStatisticsEntry; 36 import org.onosproject.net.flow.DefaultTableStatisticsEntry;
37 import org.onosproject.net.flow.FlowEntry; 37 import org.onosproject.net.flow.FlowEntry;
...@@ -61,12 +61,12 @@ import org.projectfloodlight.openflow.protocol.OFErrorType; ...@@ -61,12 +61,12 @@ import org.projectfloodlight.openflow.protocol.OFErrorType;
61 import org.projectfloodlight.openflow.protocol.OFFlowMod; 61 import org.projectfloodlight.openflow.protocol.OFFlowMod;
62 import org.projectfloodlight.openflow.protocol.OFFlowRemoved; 62 import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
63 import org.projectfloodlight.openflow.protocol.OFFlowStatsReply; 63 import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
64 -import org.projectfloodlight.openflow.protocol.OFTableStatsReply;
65 -import org.projectfloodlight.openflow.protocol.OFTableStatsEntry;
66 import org.projectfloodlight.openflow.protocol.OFMessage; 64 import org.projectfloodlight.openflow.protocol.OFMessage;
67 import org.projectfloodlight.openflow.protocol.OFPortStatus; 65 import org.projectfloodlight.openflow.protocol.OFPortStatus;
68 import org.projectfloodlight.openflow.protocol.OFStatsReply; 66 import org.projectfloodlight.openflow.protocol.OFStatsReply;
69 import org.projectfloodlight.openflow.protocol.OFStatsType; 67 import org.projectfloodlight.openflow.protocol.OFStatsType;
68 +import org.projectfloodlight.openflow.protocol.OFTableStatsEntry;
69 +import org.projectfloodlight.openflow.protocol.OFTableStatsReply;
70 import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg; 70 import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
71 import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg; 71 import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg;
72 import org.slf4j.Logger; 72 import org.slf4j.Logger;
...@@ -106,6 +106,9 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -106,6 +106,9 @@ public class OpenFlowRuleProvider extends AbstractProvider
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected ComponentConfigService cfgService; 107 protected ComponentConfigService cfgService;
108 108
109 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 + protected DriverService driverService;
111 +
109 private static final int DEFAULT_POLL_FREQUENCY = 5; 112 private static final int DEFAULT_POLL_FREQUENCY = 5;
110 @Property(name = "flowPollFrequency", intValue = DEFAULT_POLL_FREQUENCY, 113 @Property(name = "flowPollFrequency", intValue = DEFAULT_POLL_FREQUENCY,
111 label = "Frequency (in seconds) for polling flow statistics") 114 label = "Frequency (in seconds) for polling flow statistics")
...@@ -269,7 +272,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -269,7 +272,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
269 return; 272 return;
270 } 273 }
271 sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(), 274 sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
272 - Optional.empty()).buildFlowAdd()); 275 + Optional.empty(), Optional.of(driverService)).buildFlowAdd());
273 276
274 if (adaptiveFlowSampling) { 277 if (adaptiveFlowSampling) {
275 // Add TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector 278 // Add TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
...@@ -298,7 +301,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -298,7 +301,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
298 return; 301 return;
299 } 302 }
300 sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(), 303 sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
301 - Optional.empty()).buildFlowDel()); 304 + Optional.empty(), Optional.of(driverService)).buildFlowDel());
302 305
303 if (adaptiveFlowSampling) { 306 if (adaptiveFlowSampling) {
304 // Remove TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector 307 // Remove TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
...@@ -334,7 +337,8 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -334,7 +337,8 @@ public class OpenFlowRuleProvider extends AbstractProvider
334 continue; 337 continue;
335 } 338 }
336 FlowModBuilder builder = 339 FlowModBuilder builder =
337 - FlowModBuilder.builder(fbe.target(), sw.factory(), Optional.of(batch.id())); 340 + FlowModBuilder.builder(fbe.target(), sw.factory(),
341 + Optional.of(batch.id()), Optional.of(driverService));
338 NewAdaptiveFlowStatsCollector collector = afsCollectors.get(dpid); 342 NewAdaptiveFlowStatsCollector collector = afsCollectors.get(dpid);
339 switch (fbe.operator()) { 343 switch (fbe.operator()) {
340 case ADD: 344 case ADD:
...@@ -423,7 +427,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -423,7 +427,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
423 case FLOW_REMOVED: 427 case FLOW_REMOVED:
424 OFFlowRemoved removed = (OFFlowRemoved) msg; 428 OFFlowRemoved removed = (OFFlowRemoved) msg;
425 429
426 - FlowEntry fr = new FlowEntryBuilder(dpid, removed).build(); 430 + FlowEntry fr = new FlowEntryBuilder(dpid, removed, driverService).build();
427 providerService.flowRemoved(fr); 431 providerService.flowRemoved(fr);
428 432
429 if (adaptiveFlowSampling) { 433 if (adaptiveFlowSampling) {
...@@ -474,7 +478,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -474,7 +478,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
474 InternalCacheEntry entry = 478 InternalCacheEntry entry =
475 pendingBatches.getIfPresent(msg.getXid()); 479 pendingBatches.getIfPresent(msg.getXid());
476 if (entry != null) { 480 if (entry != null) {
477 - entry.appendFailure(new FlowEntryBuilder(dpid, fm).build()); 481 + entry.appendFailure(new FlowEntryBuilder(dpid, fm, driverService).build());
478 } else { 482 } else {
479 log.error("No matching batch for this error: {}", error); 483 log.error("No matching batch for this error: {}", error);
480 } 484 }
...@@ -501,7 +505,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -501,7 +505,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
501 DeviceId did = DeviceId.deviceId(Dpid.uri(dpid)); 505 DeviceId did = DeviceId.deviceId(Dpid.uri(dpid));
502 506
503 List<FlowEntry> flowEntries = replies.getEntries().stream() 507 List<FlowEntry> flowEntries = replies.getEntries().stream()
504 - .map(entry -> new FlowEntryBuilder(dpid, entry).build()) 508 + .map(entry -> new FlowEntryBuilder(dpid, entry, driverService).build())
505 .collect(Collectors.toList()); 509 .collect(Collectors.toList());
506 510
507 if (adaptiveFlowSampling) { 511 if (adaptiveFlowSampling) {
......