Jonathan Hart
Committed by Gerrit Code Review

Implemented the extension framework for selectors.

Change-Id: I577900141889fc70ca54e96cd5d54cfd5194b05d
Showing 26 changed files with 578 additions and 92 deletions
/*
* 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.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
/**
* Provides access to the extension selectors implemented by this driver.
*/
@Beta
public interface ExtensionSelectorResolver extends HandlerBehaviour {
/**
* Gets an extension selector instance of the specified type, if supported
* by the driver.
*
* @param type type of extension to get
* @return extension selector
* @throws UnsupportedOperationException if the extension type is not
* supported by this driver
*/
ExtensionSelector getExtensionSelector(ExtensionSelectorType type);
}
......@@ -14,22 +14,25 @@
* limitations under the License.
*/
package org.onosproject.net.flow.instructions;
package org.onosproject.net.flow;
import org.onosproject.net.flow.instructions.ExtensionPropertyException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract implementation of the set/get property methods of ExtensionInstruction.
* Abstract implementation of the set/get property methods of Extension.
*/
public abstract class AbstractExtensionTreatment implements ExtensionTreatment {
public abstract class AbstractExtension implements Extension {
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 {
public <T> void setPropertyValue(String key, T value) throws
ExtensionPropertyException {
Class<?> clazz = this.getClass();
try {
Field field = clazz.getDeclaredField(key);
......
......@@ -15,14 +15,8 @@
*/
package org.onosproject.net.flow;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
......@@ -30,12 +24,19 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
/**
* Default traffic selector implementation.
......@@ -379,6 +380,12 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@Override
public TrafficSelector.Builder extension(ExtensionSelector extensionSelector,
DeviceId deviceId) {
return add(Criteria.extension(extensionSelector, deviceId));
}
@Override
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
......
/*
* 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;
import org.onosproject.net.flow.instructions.ExtensionPropertyException;
import java.util.List;
/**
* An extension to the northbound APIs.
*/
public interface Extension {
/**
* Sets a property on the extension.
*
* @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
*/
<T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
/**
* Gets a property value of an extension.
*
* @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
*/
<T> T getPropertyValue(String key) throws ExtensionPropertyException;
/**
* Gets a list of all properties on the extension.
*
* @return list of properties
*/
List<String> getProperties();
/**
* Serialize the extension to a byte array.
*
* @return byte array
*/
byte[] serialize();
/**
* Deserialize the extension 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);
}
......@@ -15,8 +15,6 @@
*/
package org.onosproject.net.flow;
import java.util.Set;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
......@@ -24,8 +22,12 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import java.util.Set;
/**
* Abstraction of a slice of network traffic.
......@@ -427,6 +429,15 @@ public interface TrafficSelector {
Builder matchArpOp(int arpOp);
/**
* Uses an extension selector.
*
* @param extensionSelector extension selector
* @param deviceId device ID
* @return a selection builder
*/
Builder extension(ExtensionSelector extensionSelector, DeviceId deviceId);
/**
* Builds an immutable traffic selector.
*
* @return traffic selector
......
......@@ -23,6 +23,7 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.IndexedLambda;
import org.onosproject.net.Lambda;
import org.onosproject.net.OchSignal;
......@@ -579,6 +580,23 @@ public final class Criteria {
return new ArpOpCriterion(arpOp, Type.ARP_OP);
}
/**
* Creates an extension criterion for the specified extension selector.
*
* @param extensionSelector extension selector
* @param deviceId device ID
* @return match criterion
*/
public static Criterion extension(ExtensionSelector extensionSelector,
DeviceId deviceId) {
return new ExtensionCriterion(extensionSelector, deviceId);
}
/**
* Creates a dummy criterion.
*
* @return match criterion
*/
public static Criterion dummy() {
return new DummyCriterion();
}
......
......@@ -177,6 +177,9 @@ public interface Criterion {
/** ODU (Optical channel Data Unit) signal type. */
ODU_SIGTYPE,
/** Extension criterion. */
EXTENSION,
/** An empty criterion. */
DUMMY
}
......
/*
* 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.criteria;
import org.onosproject.net.DeviceId;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Criterion for implementing selector extensions.
*/
public class ExtensionCriterion implements Criterion {
private final ExtensionSelector extensionSelector;
private final DeviceId deviceId;
/**
* Constructor.
*
* @param extensionSelector extension selector
*/
public ExtensionCriterion(ExtensionSelector extensionSelector, DeviceId deviceId) {
this.extensionSelector = extensionSelector;
this.deviceId = deviceId;
}
/**
* Returns the extension selector.
*
* @return extension selector
*/
public ExtensionSelector extensionSelector() {
return extensionSelector;
}
/**
* Returns the device ID.
*
* @return device ID
*/
public DeviceId deviceId() {
return deviceId;
}
@Override
public Type type() {
return Type.EXTENSION;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("extensionSelector", extensionSelector.toString())
.add("deviceId", deviceId)
.toString();
}
@Override
public int hashCode() {
return Objects.hash(type().ordinal(), extensionSelector, deviceId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ExtensionCriterion) {
ExtensionCriterion that = (ExtensionCriterion) obj;
return Objects.equals(extensionSelector, that.extensionSelector) &&
Objects.equals(deviceId, that.deviceId) &&
Objects.equals(this.type(), that.type());
}
return false;
}
}
/*
* 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.criteria;
import org.onosproject.net.flow.Extension;
/**
* An extension for the selector API.
*/
public interface ExtensionSelector extends Extension {
/**
* Gets the type of the extension selector.
*
* @return type
*/
ExtensionSelectorType type();
}
/*
* 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.criteria;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
* Type of selector extensions.
*/
@Beta
public class ExtensionSelectorType {
/**
* A list of well-known named extension selector type codes.
* These numbers have no impact on the actual OF type id.
*/
public enum ExtensionSelectorTypes {
PLACEHOLDER(0); // TODO remove when actual extensions are added
private ExtensionSelectorType type;
/**
* Creates a new named extension selector type.
*
* @param type type code
*/
ExtensionSelectorTypes(int type) {
this.type = new ExtensionSelectorType(type);
}
/**
* Gets the extension type object for this named type code.
*
* @return extension type object
*/
public ExtensionSelectorType type() {
return type;
}
}
private final int type;
/**
* Creates an extension type with the given int type code.
*
* @param type type code
*/
public ExtensionSelectorType(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 ExtensionSelectorType) {
final ExtensionSelectorType that = (ExtensionSelectorType) obj;
return this.type == that.type;
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(ExtensionSelectorType.class)
.add("type", type)
.toString();
}
}
......@@ -16,12 +16,12 @@
package org.onosproject.net.flow.instructions;
import java.util.List;
import org.onosproject.net.flow.Extension;
/**
* An extensible instruction type.
* An extenstion for the treatment API.
*/
public interface ExtensionTreatment {
public interface ExtensionTreatment extends Extension {
/**
* Gets the type of the extension instruction.
......@@ -30,49 +30,4 @@ public interface ExtensionTreatment {
*/
ExtensionTreatmentType 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);
}
......
......@@ -22,7 +22,7 @@ import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
* Type of extension instructions.
* Type of treatment extensions.
*/
@Beta
public final class ExtensionTreatmentType {
......
......@@ -127,6 +127,7 @@ public final class EncodeCriterionCodecHelper {
formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
formatMap.put(Criterion.Type.EXTENSION, new FormatUnknown());
}
private interface CriterionTypeFormatter {
......
......@@ -436,7 +436,7 @@ public class FlowRuleManager
log.debug("Adding rule in store, but not on switch {}", rule);
flowMissing(rule);
} catch (Exception e) {
log.debug("Can't add missing flow rule {}", e.getMessage());
log.debug("Can't add missing flow rule:", e);
continue;
}
}
......
/*
* 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.onosproject.net.behaviour.ExtensionSelectorResolver;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
/**
* Interpreter for Nicira OpenFlow selector extensions.
*/
public class NiciraExtensionSelectorInterpreter
extends AbstractHandlerBehaviour
implements ExtensionSelectorInterpreter, ExtensionSelectorResolver {
@Override
public boolean supported(ExtensionSelectorType extensionSelectorType) {
return false;
}
@Override
public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) {
return null;
}
@Override
public ExtensionSelector mapOxm(OFOxm<?> oxm) {
return null;
}
@Override
public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) {
return null;
}
}
......@@ -31,7 +31,7 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst;
import org.projectfloodlight.openflow.types.IPv4Address;
/**
* Interpreter for Nicira OpenFlow extensions.
* Interpreter for Nicira OpenFlow treatment extensions.
*/
public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviour
implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver {
......
......@@ -19,7 +19,8 @@ package org.onosproject.driver.extensions;
import com.google.common.base.MoreObjects;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import org.onosproject.store.serializers.PortNumberSerializer;
......@@ -30,7 +31,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* Nicira resubmit extension instruction.
*/
public class NiciraResubmit extends AbstractExtensionTreatment {
public class NiciraResubmit extends AbstractExtension implements ExtensionTreatment {
private PortNumber inPort;
......
......@@ -20,7 +20,8 @@ import com.google.common.base.MoreObjects;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import org.onosproject.store.serializers.PortNumberSerializer;
......@@ -33,7 +34,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* Nicira resubmit-table extension instruction.
*/
public class NiciraResubmitTable extends AbstractExtensionTreatment {
public class NiciraResubmitTable extends AbstractExtension implements
ExtensionTreatment {
//the list of the in port number(PortNumber) and the table(short)
private List<Object> inPortAndTable = new ArrayList<Object>();
......@@ -109,4 +111,4 @@ public class NiciraResubmitTable extends AbstractExtensionTreatment {
return MoreObjects.toStringHelper(getClass())
.add("inPortAndTable", inPortAndTable).toString();
}
}
\ No newline at end of file
}
......
......@@ -16,18 +16,19 @@
package org.onosproject.driver.extensions;
import java.util.Objects;
import com.google.common.base.MoreObjects;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
* Nicira set NSH Context header extension instruction.
*/
public class NiciraSetNshContextHeader extends AbstractExtensionTreatment {
public class NiciraSetNshContextHeader extends AbstractExtension implements
ExtensionTreatment {
private int nshCh;
private ExtensionTreatmentType type;
......
......@@ -16,18 +16,19 @@
package org.onosproject.driver.extensions;
import java.util.Objects;
import com.google.common.base.MoreObjects;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
* Nicira set NSH SI extension instruction.
*/
public class NiciraSetNshSi extends AbstractExtensionTreatment {
public class NiciraSetNshSi extends AbstractExtension implements
ExtensionTreatment {
private byte nshSi;
......
......@@ -16,18 +16,19 @@
package org.onosproject.driver.extensions;
import java.util.Objects;
import com.google.common.base.MoreObjects;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
* Nicira set NSH SPI extension instruction.
*/
public class NiciraSetNshSpi extends AbstractExtensionTreatment {
public class NiciraSetNshSpi extends AbstractExtension implements
ExtensionTreatment {
private int nshSpi;
......
......@@ -19,7 +19,8 @@ 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.AbstractExtensionTreatment;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import org.onosproject.store.serializers.Ip4AddressSerializer;
......@@ -30,7 +31,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* Nicira set tunnel destination extension instruction.
*/
public class NiciraSetTunnelDst extends AbstractExtensionTreatment {
public class NiciraSetTunnelDst extends AbstractExtension implements
ExtensionTreatment {
private Ip4Address tunnelDst;
......
......@@ -36,6 +36,10 @@
impl="org.onosproject.driver.extensions.NiciraExtensionTreatmentInterpreter" />
<behaviour api="org.onosproject.net.behaviour.ExtensionTreatmentResolver"
impl="org.onosproject.driver.extensions.NiciraExtensionTreatmentInterpreter" />
<behaviour api="org.onosproject.openflow.controller.ExtensionSelectorInterpreter"
impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" />
<behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver"
impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" />
</driver>
<!--This driver is for simulated NETCONF devices through of-config tool on top og OVSDB-->
<driver name="ovs-netconf" extends="default"
......
/*
* 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.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
/**
* Interprets extension selectors and converts them to/from OpenFlow objects.
*/
@Beta
public interface ExtensionSelectorInterpreter extends HandlerBehaviour {
/**
* Returns true if the given extension selector is supported by this
* driver.
*
* @param extensionSelectorType extension selector type
* @return true if the instruction is supported, otherwise false
*/
boolean supported(ExtensionSelectorType extensionSelectorType);
/**
* Maps an extension selector to an OpenFlow OXM.
*
* @param factory OpenFlow factory
* @param extensionSelector extension selector
* @return OpenFlow action
*/
OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector);
/**
* Maps an OpenFlow OXM to an extension selector.
*
* @param oxm OpenFlow OXM
* @return extension selector
*/
ExtensionSelector mapOxm(OFOxm<?> oxm);
}
......@@ -20,7 +20,11 @@ import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.Ip6Prefix;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.OchSignal;
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.TrafficSelector;
......@@ -30,6 +34,8 @@ import org.onosproject.net.flow.criteria.ArpPaCriterion;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.ExtensionCriterion;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPDscpCriterion;
import org.onosproject.net.flow.criteria.IPEcnCriterion;
......@@ -54,12 +60,14 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFFlowDelete;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
import org.projectfloodlight.openflow.types.ArpOpcode;
import org.projectfloodlight.openflow.types.CircuitSignalID;
import org.projectfloodlight.openflow.types.EthType;
......@@ -102,6 +110,7 @@ public abstract class FlowModBuilder {
private final TrafficSelector selector;
protected final Long xid;
protected final Optional<DriverService> driverService;
protected final DeviceId deviceId;
/**
* Creates a new flow mod builder.
......@@ -142,6 +151,7 @@ public abstract class FlowModBuilder {
this.selector = flowRule.selector();
this.xid = xid.orElse(0L);
this.driverService = driverService;
this.deviceId = flowRule.deviceId();
}
/**
......@@ -446,6 +456,21 @@ public abstract class FlowModBuilder {
mBuilder.setExact(MatchField.ARP_TPA,
IPv4Address.of(arpPaCriterion.ip().toInt()));
break;
case EXTENSION:
ExtensionCriterion extensionCriterion = (ExtensionCriterion) c;
OFOxm oxm = buildExtensionOxm(extensionCriterion.extensionSelector());
if (oxm == null) {
log.warn("Unable to build extension selector");
break;
}
if (oxm.isMasked()) {
mBuilder.setMasked(oxm.getMatchField(), oxm.getValue(), oxm.getMask());
} else {
mBuilder.setExact(oxm.getMatchField(), oxm.getValue());
}
break;
case MPLS_TC:
case PBB_ISID:
default:
......@@ -473,4 +498,21 @@ public abstract class FlowModBuilder {
return factory;
}
private OFOxm buildExtensionOxm(ExtensionSelector extension) {
if (!driverService.isPresent()) {
log.error("No driver service present");
return null;
}
Driver driver = driverService.get().getDriver(deviceId);
if (driver.hasBehaviour(ExtensionSelectorInterpreter.class)) {
DefaultDriverHandler handler =
new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
ExtensionSelectorInterpreter interpreter = handler.behaviour(ExtensionSelectorInterpreter.class);
return interpreter.mapSelector(factory(), extension);
}
return null;
}
}
......
......@@ -18,7 +18,6 @@ package org.onosproject.provider.of.flow.impl;
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;
......@@ -95,7 +94,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
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.
......@@ -110,7 +108,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
super(flowRule, factory, xid, driverService);
this.treatment = flowRule.treatment();
this.deviceId = flowRule.deviceId();
}
@Override
......