[ONOS-6208]Implemention of onos and loxi for OVS NAT and connection tracking support

Change-Id: I782422d41fdacc805b523b57c3bd0b6e67e483a2
This commit is contained in:
Frank Wang 2017-03-28 10:15:18 +08:00 committed by Yuta HIGUCHI
parent 21720341e0
commit 5733c387cc
11 changed files with 1069 additions and 11 deletions

View File

@ -39,6 +39,10 @@ public class ExtensionSelectorType {
NICIRA_MATCH_NSH_CH3(4),
NICIRA_MATCH_NSH_CH4(5),
NICIRA_MATCH_ENCAP_ETH_TYPE(6),
NICIRA_MATCH_CONNTRACK_STATE(7),
NICIRA_MATCH_CONNTRACK_ZONE(8),
NICIRA_MATCH_CONNTRACK_MARK(9),
NICIRA_MATCH_CONNTRACK_LABEL(10),
OFDPA_MATCH_VLAN_VID(16),
OFDPA_MATCH_OVID(17),
OFDPA_MATCH_MPLS_L2_PORT(18),

View File

@ -48,6 +48,9 @@ public final class ExtensionTreatmentType {
NICIRA_RESUBMIT_TABLE(14),
NICIRA_PUSH_NSH(38),
NICIRA_POP_NSH(39),
NICIRA_CT(40),
NICIRA_NAT(41),
NICIRA_CT_CLEAR(42),
OFDPA_SET_VLAN_ID(64),
OFDPA_SET_MPLS_TYPE(65),
OFDPA_SET_OVID(66),

View File

@ -0,0 +1,187 @@
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.extensions;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* Nicira ct extension instruction.
*/
public class NiciraCt extends AbstractExtension implements ExtensionTreatment {
private int flags;
private long zoneSrc;
private int zone;
private short recircTable;
private int alg;
private List<ExtensionTreatment> nestedActions;
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
/**
* Creates a new nicicra ct instruction.
*/
public NiciraCt() {
flags = 0;
zoneSrc = 0L;
zone = 0;
alg = 0;
recircTable = 0xFF;
nestedActions = new ArrayList<>();
}
/**
* Creates a new nicicra ct instruction.
* @param flags zero or commit(0x01)
* @param zoneSrc If 'zone_src' is nonzero, this specifies that the zone should be
* sourced from a field zone_src[ofs:ofs+nbits].
* @param zone this is the union of zone_imm and zone_ofs_nbits
* If 'zone_src' is zero, then the value of 'zone_imm'
* will be used as the connection tracking zone
* @param recircTable Recirculate to a specific table or 0xff for no recirculation
* @param alg Well-known port number for the protocol, 0 indicates no ALG is required
* @param actions a sequence of zero or more OpenFlow actions
*/
public NiciraCt(int flags, long zoneSrc, int zone, short recircTable, int alg, List<ExtensionTreatment> actions) {
this.flags = flags;
this.zoneSrc = zoneSrc;
this.zone = zone;
this.recircTable = recircTable;
this.alg = alg;
this.nestedActions = actions;
}
@Override
public ExtensionTreatmentType type() {
return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type();
}
/**
* Get Nicira Conntrack flags.
* @return flags
*/
public int niciraCtFlags() {
return flags;
}
/**
* Get Nicira Conntrack zone.
* @return zone
*/
public int niciraCtZone() {
return zone;
}
/**
* Get Nicira Conntrack zone src.
* @return zoneSrc
*/
public long niciraCtZoneSrc() {
return zoneSrc;
}
/**
* Get Nicira Conntrack alg.
* @return alg
*/
public int niciraCtAlg() {
return alg;
}
/**
* Get Nicira Conntrack Recirc table.
* @return recirc table
*/
public short niciraCtRecircTable() {
return recircTable;
}
/**
* Get Nicira Conntrack Recirc table.
* @return list extension treatment
*/
public List<ExtensionTreatment> niciraCtNestActions() {
return nestedActions;
}
@Override
public void deserialize(byte[] data) {
Map<String, Object> values = appKryo.deserialize(data);
flags = (int) values.get("flags");
zoneSrc = (long) values.get("zoneSrc");
zone = (int) values.get("zone");
recircTable = (short) values.get("recircTable");
alg = (int) values.get("alg");
nestedActions = (List) values.get("nestedActions");
}
@Override
public byte[] serialize() {
Map<String, Object> values = Maps.newHashMap();
values.put("flags", flags);
values.put("zoneSrc", zoneSrc);
values.put("zone", zone);
values.put("recircTable", recircTable);
values.put("alg", alg);
values.put("nestedActions", nestedActions);
return appKryo.serialize(values);
}
@Override
public int hashCode() {
return Objects.hash(type(), flags, zone, zoneSrc, alg, recircTable, nestedActions);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NiciraCt) {
NiciraCt that = (NiciraCt) obj;
return Objects.equals(flags, that.flags) &&
Objects.equals(zone, that.zone) &&
Objects.equals(zoneSrc, that.zoneSrc) &&
Objects.equals(alg, that.alg) &&
Objects.equals(recircTable, that.recircTable) &&
Objects.equals(nestedActions, that.nestedActions) &&
Objects.equals(this.type(), that.type());
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("flags", flags)
.add("zoneSrc", zoneSrc)
.add("zone", zone)
.add("recircTable", recircTable)
.add("alg", alg)
.add("nestedActions", nestedActions)
.toString();
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.extensions;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
/**
* Nicira conntrack clear extension instruction.
*/
public class NiciraCtClear extends AbstractExtension implements ExtensionTreatment {
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
/**
* Creates a conntrack clear instruction.
*/
public NiciraCtClear() {
}
@Override
public ExtensionTreatmentType type() {
return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type();
}
@Override
public void deserialize(byte[] data) {
}
@Override
public byte[] serialize() {
return appKryo.serialize(0);
}
@Override
public int hashCode() {
return 1;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NiciraCtClear) {
return true;
}
return false;
}
}

View File

@ -28,6 +28,9 @@ import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmConntrackMark;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmConntrackStateMasked;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmConntrackZone;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthType;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsi;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp;
@ -66,6 +69,22 @@ public class NiciraExtensionSelectorInterpreter
.type())) {
return true;
}
if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE
.type())) {
return true;
}
if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_ZONE
.type())) {
return true;
}
if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_MARK
.type())) {
return true;
}
if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_LABEL
.type())) {
return true;
}
return false;
}
@ -97,6 +116,20 @@ public class NiciraExtensionSelectorInterpreter
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) {
// TODO
}
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE.type())) {
NiciraMatchCtState niciraMatchCtState = (NiciraMatchCtState) extensionSelector;
return factory.oxms().conntrackStateMasked(U32.of(niciraMatchCtState.ctState()),
U32.of(niciraMatchCtState.ctStateMask()));
}
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_ZONE.type())) {
NiciraMatchCtZone niciraMatchCtZone = (NiciraMatchCtZone) extensionSelector;
return factory.oxms().conntrackZone(U16.of(niciraMatchCtZone.ctZone()));
}
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_MARK.type())) {
NiciraMatchCtMark niciraMatchCtMark = (NiciraMatchCtMark) extensionSelector;
return factory.oxms().conntrackMark(U32.of(niciraMatchCtMark.ctMark()));
}
return null;
}
@ -115,7 +148,18 @@ public class NiciraExtensionSelectorInterpreter
OFOxmEncapEthType oxmField = (OFOxmEncapEthType) oxm;
return new NiciraMatchEncapEthType(oxmField.getValue().getRaw());
}
if (oxm.getMatchField() == MatchField.CONNTRACK_STATE) {
OFOxmConntrackStateMasked oxmField = (OFOxmConntrackStateMasked) oxm;
return new NiciraMatchCtState(oxmField.getValue().getRaw(), oxmField.getMask().getRaw());
}
if (oxm.getMatchField() == MatchField.CONNTRACK_ZONE) {
OFOxmConntrackZone oxmField = (OFOxmConntrackZone) oxm;
return new NiciraMatchCtZone(oxmField.getValue().getRaw());
}
if (oxm.getMatchField() == MatchField.CONNTRACK_MARK) {
OFOxmConntrackMark oxmField = (OFOxmConntrackMark) oxm;
return new NiciraMatchCtMark(oxmField.getValue().getRaw());
}
return null;
}
@ -136,6 +180,15 @@ public class NiciraExtensionSelectorInterpreter
|| type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) {
return new NiciraMatchNshContextHeader(type);
}
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE.type())) {
return new NiciraMatchCtState();
}
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_ZONE.type())) {
return new NiciraMatchCtZone();
}
if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_MARK.type())) {
return new NiciraMatchCtMark();
}
return null;
}

View File

@ -18,8 +18,10 @@ package org.onosproject.driver.extensions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
import com.google.common.collect.Lists;
import com.google.common.primitives.Bytes;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onosproject.codec.CodecContext;
import org.onosproject.net.NshContextHeader;
import org.onosproject.net.NshServiceIndex;
@ -35,7 +37,9 @@ import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
import org.projectfloodlight.openflow.protocol.action.OFActionNicira;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraCt;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraMove;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraNat;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmit;
import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmitTable;
import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
@ -54,6 +58,7 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunGpeNp;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv6Address;
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.U16;
import org.projectfloodlight.openflow.types.U32;
@ -61,6 +66,9 @@ import org.projectfloodlight.openflow.types.U8;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.ArrayList;
import java.util.List;
/**
* Interpreter for Nicira OpenFlow treatment extensions.
*/
@ -80,9 +88,19 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou
private static final int TUN_IPV4_DST = 0x00014004;
private static final int TUN_ID = 0x12008;
private static final int NAT_RANGE_IPV4_MIN = 0x01;
private static final int NAT_RANGE_IPV4_MAX = 0x02;
private static final int NAT_RANGE_IPV6_MIN = 0x04;
private static final int NAT_RANGE_IPV6_MAX = 0x08;
private static final int NAT_RANGE_PROTO_MIN = 0x10;
private static final int NAT_RANGE_PROTO_MAX = 0x20;
private static final int SUB_TYPE_RESUBMIT = 1;
private static final int SUB_TYPE_RESUBMIT_TABLE = 14;
private static final int SUB_TYPE_MOVE = 6;
private static final int SUB_TYPE_CT = 35;
private static final int SUB_TYPE_NAT = 36;
private static final int SUB_TYPE_CT_CLEAR = 43;
private static final int SUB_TYPE_PUSH_NSH = 38;
private static final int SUB_TYPE_POP_NSH = 39;
@ -199,6 +217,15 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou
.type())) {
return true;
}
if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type())) {
return true;
}
if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NAT.type())) {
return true;
}
if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type())) {
return true;
}
return false;
}
@ -299,6 +326,70 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou
action.setDst(mov.dst());
return action.build();
}
if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type())) {
NiciraCt niciraCt = (NiciraCt) extensionTreatment;
OFActionNiciraCt.Builder ctAction = factory.actions().buildNiciraCt();
ctAction.setFlags(niciraCt.niciraCtFlags());
ctAction.setZoneSrc(niciraCt.niciraCtZoneSrc());
ctAction.setZone(niciraCt.niciraCtZone());
ctAction.setRecircTable(niciraCt.niciraCtRecircTable());
ctAction.setAlg(niciraCt.niciraCtAlg());
for (ExtensionTreatment nestedTreatment : niciraCt.niciraCtNestActions()) {
if (nestedTreatment instanceof NiciraNat) {
NiciraNat niciraNat = (NiciraNat) nestedTreatment;
OFActionNiciraNat.Builder action = factory.actions().buildNiciraNat();
action.setFlags(niciraNat.niciraNatFlags());
int presetFlags = niciraNat.niciraNatPresentFlags();
action.setRangePresent(presetFlags);
List<IPv4Address> ipv4RangeList = Lists.newArrayList();
List<IPv6Address> ipv6RangeList = Lists.newArrayList();
List<U16> portRangeList = Lists.newArrayList();
List<U8> padList = Lists.newArrayList();
if ((presetFlags & NAT_RANGE_IPV4_MIN) != 0) {
ipv4RangeList.add(IPv4Address.of(niciraNat.niciraNatIpAddressMin().getIp4Address().toString()));
}
if ((presetFlags & NAT_RANGE_IPV4_MAX) != 0) {
ipv4RangeList.add(IPv4Address.of(niciraNat.niciraNatIpAddressMax().getIp4Address().toString()));
}
if ((presetFlags & NAT_RANGE_IPV6_MIN) != 0) {
ipv6RangeList.add(IPv6Address.of(niciraNat.niciraNatIpAddressMin().getIp6Address().toString()));
}
if ((presetFlags & NAT_RANGE_IPV6_MAX) != 0) {
ipv6RangeList.add(IPv6Address.of(niciraNat.niciraNatIpAddressMax().getIp6Address().toString()));
}
if ((presetFlags & NAT_RANGE_PROTO_MIN) != 0) {
portRangeList.add(U16.of(niciraNat.niciraNatPortMin()));
}
if ((presetFlags & NAT_RANGE_PROTO_MAX) != 0) {
portRangeList.add(U16.of(niciraNat.niciraNatPortMax()));
}
for (; (ipv6RangeList.size() * 16 + ipv4RangeList.size() * 4
+ portRangeList.size() * 2 + padList.size()) % 8 != 0;) {
padList.add(U8.ofRaw((byte) 0));
}
action.setIpv4Range(ipv4RangeList);
action.setIpv6Range(ipv6RangeList);
action.setPortRange(portRangeList);
action.setPad(padList);
//nat action must be nested in ct action
List<OFAction> actions = Lists.newArrayList();
actions.add(action.build());
ctAction.setActions(actions);
}
}
return ctAction.build();
}
if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type())) {
return factory.actions().niciraCtClear();
}
return null;
}
@ -404,14 +495,87 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou
case SUB_TYPE_RESUBMIT:
OFActionNiciraResubmit resubmitAction = (OFActionNiciraResubmit) nicira;
return new NiciraResubmit(PortNumber.portNumber(resubmitAction.getInPort()));
case SUB_TYPE_PUSH_NSH:
return new NiciraPushNsh();
case SUB_TYPE_POP_NSH:
return new NiciraPopNsh();
case SUB_TYPE_RESUBMIT_TABLE:
OFActionNiciraResubmitTable resubmitTable = (OFActionNiciraResubmitTable) nicira;
return new NiciraResubmitTable(PortNumber.portNumber(resubmitTable.getInPort()),
resubmitTable.getTable());
case SUB_TYPE_PUSH_NSH:
return new NiciraPushNsh();
case SUB_TYPE_POP_NSH:
return new NiciraPopNsh();
case SUB_TYPE_RESUBMIT_TABLE:
OFActionNiciraResubmitTable resubmitTable = (OFActionNiciraResubmitTable) nicira;
return new NiciraResubmitTable(PortNumber.portNumber(resubmitTable.getInPort()),
resubmitTable.getTable());
case SUB_TYPE_CT:
OFActionNiciraCt ctAction = (OFActionNiciraCt) nicira;
List<OFAction> actions = ctAction.getActions();
for (OFAction act : actions) {
OFActionExperimenter ctExperimenter = (OFActionExperimenter) act;
if (Long.valueOf(ctExperimenter.getExperimenter()).intValue() == TYPE_NICIRA) {
OFActionNicira actionNicira = (OFActionNicira) ctExperimenter;
switch (actionNicira.getSubtype()) {
case SUB_TYPE_NAT:
OFActionNiciraNat natAction = (OFActionNiciraNat) actionNicira;
int portMin = 0;
int portMax = 0;
IpAddress ipAddressMin = IpAddress.valueOf(0);
IpAddress ipAddressMax = IpAddress.valueOf(0);
//FIXME: we need to get ipv6 and port from list<ipv4> temporarily,
// becase loxi don't know how to arrange these data to corresonding field.
IPv4Address[] arrays = (IPv4Address[]) natAction
.getIpv4Range().toArray(new IPv4Address[0]);
int index = 0;
if ((natAction.getRangePresent() & NAT_RANGE_IPV4_MIN) != 0) {
ipAddressMin = IpAddress.valueOf(arrays[index++].toString());
}
if ((natAction.getRangePresent() & NAT_RANGE_IPV4_MAX) != 0) {
ipAddressMax = IpAddress.valueOf(arrays[index++].toString());
}
if ((natAction.getRangePresent() & NAT_RANGE_IPV6_MIN) != 0) {
byte[] bytes = Bytes.concat(arrays[index++].getBytes(),
arrays[index++].getBytes(),
arrays[index++].getBytes(),
arrays[index++].getBytes());
ipAddressMin = IpAddress.valueOf(IpAddress.Version.INET6, bytes);
}
if ((natAction.getRangePresent() & NAT_RANGE_IPV6_MAX) != 0) {
byte[] bytes = Bytes.concat(arrays[index++].getBytes(),
arrays[index++].getBytes(),
arrays[index++].getBytes(),
arrays[index++].getBytes());
ipAddressMax = IpAddress.valueOf(IpAddress.Version.INET6, bytes);
}
if ((natAction.getRangePresent() & NAT_RANGE_PROTO_MIN) != 0) {
portMin = arrays[index].getInt() >> 16 & 0x0000ffff;
}
if ((natAction.getRangePresent() & NAT_RANGE_PROTO_MAX) != 0) {
portMax = arrays[index].getInt() & 0x0000ffff;
}
List<ExtensionTreatment> treatments = new ArrayList<>();
NiciraNat natTreatment = new NiciraNat(natAction.getFlags(),
natAction.getRangePresent(),
portMin, portMax,
ipAddressMin, ipAddressMax);
treatments.add(natTreatment);
return new NiciraCt(ctAction.getFlags(),
ctAction.getZoneSrc(),
ctAction.getZone(),
ctAction.getRecircTable(),
ctAction.getAlg(),
treatments);
default:
throw new UnsupportedOperationException("Driver does not support nested" +
" in ct action extension subtype " + actionNicira.getSubtype());
}
}
}
return new NiciraCt(ctAction.getFlags(),
ctAction.getZoneSrc(),
ctAction.getZone(),
ctAction.getRecircTable(),
ctAction.getAlg(),
new ArrayList<>());
case SUB_TYPE_CT_CLEAR:
return new NiciraCtClear();
default:
throw new UnsupportedOperationException("Driver does not support extension subtype "
+ nicira.getSubtype());
@ -502,6 +666,15 @@ public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviou
if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) {
return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId();
}
if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type())) {
return new NiciraCt();
}
if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NAT.type())) {
return new NiciraNat();
}
if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT_CLEAR.type())) {
return new NiciraCtClear();
}
throw new UnsupportedOperationException("Driver does not support extension type " + type.toString());
}

View File

@ -0,0 +1,133 @@
/*
* Copyright 2017-present 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 java.util.Map;
import java.util.Objects;
import com.google.common.collect.Maps;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
import com.google.common.base.MoreObjects;
/**
* Nicira conntrack mark extension selector.
*/
public class NiciraMatchCtMark extends AbstractExtension implements ExtensionSelector {
private long ctMark;
private long ctMarkMask;
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
/**
* Creates a new conntrack mark selector.
*/
NiciraMatchCtMark() {
ctMark = 0L;
ctMarkMask = ~0L;
}
/**
* Creates a new conntrack state selector with given mark.
*
* @param ctMark conntrack mark
*/
public NiciraMatchCtMark(long ctMark) {
this.ctMark = ctMark;
this.ctMarkMask = ~0L;
}
/**
* Creates a new conntrack state selector with given mark.
*
* @param ctMark conntrack mark
* @param mask conntrack mark mask
*/
public NiciraMatchCtMark(long ctMark, long mask) {
this.ctMark = ctMark;
this.ctMarkMask = mask;
}
/**
* Gets the conntrack mark.
*
* @return ctMark
*/
public long ctMark() {
return ctMark;
}
/**
* Gets the conntrack mark mask.
*
* @return ctMarkMask
*/
public long ctMarkMask() {
return ctMarkMask;
}
@Override
public ExtensionSelectorType type() {
return ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_MARK.type();
}
@Override
public void deserialize(byte[] data) {
Map<String, Object> values = appKryo.deserialize(data);
ctMark = (long) values.get("ctMark");
ctMarkMask = (long) values.get("ctMarkMask");
}
@Override
public byte[] serialize() {
Map<String, Object> values = Maps.newHashMap();
values.put("ctMark", ctMark);
values.put("ctMarkMask", ctMarkMask);
return appKryo.serialize(values);
}
@Override
public int hashCode() {
return Objects.hash(ctMark, ctMarkMask);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NiciraMatchCtMark) {
NiciraMatchCtMark that = (NiciraMatchCtMark) obj;
return Objects.equals(ctMark, that.ctMark)
&& Objects.equals(ctMarkMask, that.ctMarkMask);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("ctMark", ctMark)
.add("ctMarkMask", ctMarkMask)
.toString();
}
}

View File

@ -0,0 +1,121 @@
/*
* Copyright 2017-present 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 java.util.Map;
import java.util.Objects;
import com.google.common.collect.Maps;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
import com.google.common.base.MoreObjects;
/**
* Nicira conntrack state extension selector.
*/
public class NiciraMatchCtState extends AbstractExtension implements ExtensionSelector {
private long ctState;
private long ctStateMask;
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
/**
* Creates a new conntrack state selector.
*/
NiciraMatchCtState() {
ctState = 0L;
ctStateMask = ~0L;
}
/**
* Creates a new conntrack state selector with given state.
*
* @param ctState conntrack state
* @param mask conntrack state mask
*/
public NiciraMatchCtState(long ctState, long mask) {
this.ctState = ctState;
this.ctStateMask = mask;
}
/**
* Gets the conntrack state.
*
* @return ctState
*/
public long ctState() {
return ctState;
}
/**
* Gets the conntrack state mask.
*
* @return ctStateMask
*/
public long ctStateMask() {
return ctStateMask;
}
@Override
public ExtensionSelectorType type() {
return ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE.type();
}
@Override
public void deserialize(byte[] data) {
Map<String, Object> values = appKryo.deserialize(data);
ctState = (long) values.get("ctState");
ctStateMask = (long) values.get("ctStateMask");
}
@Override
public byte[] serialize() {
Map<String, Object> values = Maps.newHashMap();
values.put("ctState", ctState);
values.put("ctStateMask", ctStateMask);
return appKryo.serialize(values);
}
@Override
public int hashCode() {
return Objects.hash(ctState, ctStateMask);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NiciraMatchCtState) {
NiciraMatchCtState that = (NiciraMatchCtState) obj;
return Objects.equals(ctState, that.ctState)
&& Objects.equals(ctStateMask, that.ctStateMask);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("ctState", ctState)
.add("mask", ctStateMask)
.toString();
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright 2016-present 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 java.util.Objects;
import org.onlab.util.KryoNamespace;
import org.onosproject.net.flow.AbstractExtension;
import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.ExtensionSelectorType;
import com.google.common.base.MoreObjects;
/**
* Nicira conntrack zone extension selector.
*/
public class NiciraMatchCtZone extends AbstractExtension implements ExtensionSelector {
private int ctZone;
private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
/**
* Creates a new conntrack zone selector.
*/
NiciraMatchCtZone() {
ctZone = 0;
}
/**
* Creates a new conntrack zone selector with given zone.
*
* @param ctZone conntrack zone
*/
public NiciraMatchCtZone(int ctZone) {
this.ctZone = ctZone;
}
/**
* Gets the conntrack zone.
*
* @return ctZone
*/
public int ctZone() {
return ctZone;
}
@Override
public ExtensionSelectorType type() {
return ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_ZONE.type();
}
@Override
public void deserialize(byte[] data) {
ctZone = (int) (appKryo.deserialize(data));
}
@Override
public byte[] serialize() {
return appKryo.serialize(ctZone);
}
@Override
public int hashCode() {
return Objects.hash(ctZone);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NiciraMatchCtZone) {
NiciraMatchCtZone that = (NiciraMatchCtZone) obj;
return Objects.equals(ctZone, that.ctZone());
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass()).add("ctZone", ctZone).toString();
}
}

View File

@ -0,0 +1,187 @@
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.driver.extensions;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;
import org.onlab.packet.IpAddress;
import org.onlab.util.KryoNamespace;
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.IpAddressSerializer;
import java.util.Map;
import java.util.Objects;
/**
* Nicira nat extension instruction.
*/
public class NiciraNat extends AbstractExtension implements ExtensionTreatment {
private int flags;
private int presentFlags;
private int portMin;
private int portMax;
private IpAddress ipAddressMin;
private IpAddress ipAddressMax;
private final KryoNamespace appKryo = new KryoNamespace.Builder()
.register(new IpAddressSerializer(), IpAddress.class)
.register(byte[].class)
.build();
/**
* Creates a new nat instruction.
*/
public NiciraNat() {
flags = 0;
presentFlags = 0;
portMin = 0;
portMax = 0;
ipAddressMin = IpAddress.valueOf(0);
ipAddressMax = IpAddress.valueOf(0);
}
/**
* Creates a new nat instruction.
* @param flags nat flags
* @param presentFlags nat present flags
* @param portMin min port
* @param portMax max port
* @param ipAddressMin min ip address
* @param ipAddressMax max ip address
*/
public NiciraNat(int flags, int presentFlags, int portMin, int portMax, IpAddress ipAddressMin,
IpAddress ipAddressMax) {
this.flags = flags;
this.presentFlags = presentFlags;
this.portMin = portMin;
this.portMax = portMax;
this.ipAddressMin = ipAddressMin;
this.ipAddressMax = ipAddressMax;
}
@Override
public ExtensionTreatmentType type() {
return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NAT.type();
}
/**
* Get Nicira nat flags.
* @return flags
*/
public int niciraNatFlags() {
return flags;
}
/**
* Get Nicira present flags.
* @return present flags
*/
public int niciraNatPresentFlags() {
return presentFlags;
}
/**
* Get Nicira Nat min port.
* @return min port
*/
public int niciraNatPortMin() {
return portMin;
}
/**
* Get Nicira Nat max port.
* @return max port
*/
public int niciraNatPortMax() {
return portMax;
}
/**
* Get Nicira Nat min ip address.
* @return min ipaddress
*/
public IpAddress niciraNatIpAddressMin() {
return ipAddressMin;
}
/**
* Get Nicira Nat max ip address.
* @return max ipaddress
*/
public IpAddress niciraNatIpAddressMax() {
return ipAddressMax;
}
@Override
public void deserialize(byte[] data) {
Map<String, Object> values = appKryo.deserialize(data);
flags = (int) values.get("flags");
presentFlags = (int) values.get("presentFlags");
portMin = (int) values.get("portMin");
portMax = (int) values.get("portMax");
ipAddressMin = (IpAddress) values.get("ipAddressMin");
ipAddressMax = (IpAddress) values.get("ipAddressMax");
}
@Override
public byte[] serialize() {
Map<String, Object> values = Maps.newHashMap();
values.put("flags", flags);
values.put("presentFlags", presentFlags);
values.put("portMin", portMin);
values.put("portMax", portMax);
values.put("ipAddressMin", ipAddressMin);
values.put("ipAddressMax", ipAddressMax);
return appKryo.serialize(values);
}
@Override
public int hashCode() {
return Objects.hash(type(), flags, presentFlags, portMin, portMax, ipAddressMin, ipAddressMax);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof NiciraNat) {
NiciraNat that = (NiciraNat) obj;
return Objects.equals(flags, that.flags) &&
Objects.equals(presentFlags, that.presentFlags) &&
Objects.equals(portMin, that.portMin) &&
Objects.equals(portMax, that.portMax) &&
Objects.equals(ipAddressMin, that.ipAddressMin) &&
Objects.equals(ipAddressMax, that.ipAddressMax) &&
Objects.equals(this.type(), that.type());
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("flags", flags)
.add("present_flags", presentFlags)
.add("portMin", portMin)
.add("portMax", portMax)
.add("ipAddressMin", ipAddressMin)
.add("ipAddressMax", ipAddressMax)
.toString();
}
}

View File

@ -979,7 +979,7 @@ public class FlowEntryBuilder {
match.get(MatchField.EXP_ODU_SIG_ID).getTslen(),
match.get(MatchField.EXP_ODU_SIG_ID).getTsmap());
builder.add(matchOduSignalId(oduSignalId));
break;
break;
case EXP_ODU_SIGTYPE:
try {
U8 oduSigType = match.get(MatchField.EXP_ODU_SIGTYPE);
@ -1043,6 +1043,39 @@ public class FlowEntryBuilder {
}
}
break;
case CONNTRACK_STATE:
if (selectorInterpreter != null &&
selectorInterpreter.supported(ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE.type())) {
try {
OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.CONNTRACK_STATE);
builder.extension(selectorInterpreter.mapOxm(oxm), deviceId);
} catch (UnsupportedOperationException e) {
log.debug(e.getMessage());
}
}
break;
case CONNTRACK_ZONE:
if (selectorInterpreter != null &&
selectorInterpreter.supported(ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_ZONE.type())) {
try {
OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.CONNTRACK_ZONE);
builder.extension(selectorInterpreter.mapOxm(oxm), deviceId);
} catch (UnsupportedOperationException e) {
log.debug(e.getMessage());
}
}
break;
case CONNTRACK_MARK:
if (selectorInterpreter != null &&
selectorInterpreter.supported(ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_MARK.type())) {
try {
OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.CONNTRACK_MARK);
builder.extension(selectorInterpreter.mapOxm(oxm), deviceId);
} catch (UnsupportedOperationException e) {
log.debug(e.getMessage());
}
}
break;
case OFDPA_OVID:
if (selectorInterpreter != null &&
selectorInterpreter.supported(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {