package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;
+import static org.opendaylight.openflowjava.util.ByteBufUtils.macAddressToString;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Splitter;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-
import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.extension.api.ConverterExtensionKey;
import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
-import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionResolvers;
import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
+import org.opendaylight.openflowplugin.openflow.md.util.ActionUtil;
import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
-import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
-import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-import com.google.common.base.Splitter;
-
/**
* Utility class for converting a MD-SAL Flow into the OF flow mod
*/
private static final Logger logger = LoggerFactory.getLogger(MatchConvertorImpl.class);
static final String PREFIX_SEPARATOR = "/";
static final Splitter PREFIX_SPLITTER = Splitter.on('/');
- private static final byte[] VLAN_VID_MASK = new byte[] { 16, 0 };
+ private static final byte[] VLAN_VID_MASK = new byte[]{16, 0};
private static final short PROTO_TCP = 6;
private static final short PROTO_UDP = 17;
private static final String noIp = "0.0.0.0/0";
matchEntriesList.add(toOfMacAddress(ArpTha.class, arpTargetHardwareAddress.getAddress(),
arpTargetHardwareAddress.getMask()));
}
- }
-
- else if (layer3Match instanceof Ipv6Match) {
+ } else if (layer3Match instanceof Ipv6Match) {
Ipv6Match ipv6Match = (Ipv6Match) layer3Match;
if (ipv6Match.getIpv6Source() != null) {
matchEntriesList.add(toOfIpv6Prefix(Ipv6Src.class, ipv6Match.getIpv6Source()));
if (tunnel != null) {
matchEntriesList.add(toOfMetadata(TunnelId.class, tunnel.getTunnelId(), tunnel.getTunnelMask()));
}
-
-
+
+
/**
* TODO: EXTENSION PROPOSAL (match, MD-SAL to OFJava)
* - we might need version for conversion and for key
for (ExtensionList extensionItem : extensionListOpt.get().getExtensionList()) {
// TODO: get real version
ConverterExtensionKey<? extends ExtensionKey> key = new ConverterExtensionKey<>(extensionItem.getExtensionKey(), OFConstants.OFP_VERSION_1_3);
- ConvertorToOFJava<MatchEntries> convertor =
+ ConvertorToOFJava<MatchEntries> convertor =
OFSessionUtil.getExtensionConvertorProvider().getConverter(key);
MatchEntries ofMatch = convertor.convert(extensionItem.getExtension());
matchEntriesList.add(ofMatch);
* @return
* @author avishnoi@in.ibm.com
*/
- public static Match fromOFMatchV10ToSALMatch(final MatchV10 swMatch, final BigInteger datapathid, final OpenflowVersion ofVersion) {
+ public static Match fromOFMatchV10ToSALMatch(final MatchV10 swMatch, final BigInteger datapathid, final OpenflowVersion ofVersion) {
MatchBuilder matchBuilder = new MatchBuilder();
EthernetMatchBuilder ethMatchBuilder = new EthernetMatchBuilder();
VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
int vlanId = (swMatch.getDlVlan() == ((int) 0xffff)) ? 0 : swMatch.getDlVlan();
vlanIdBuilder.setVlanId(new org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId(vlanId));
- vlanIdBuilder.setVlanIdPresent(vlanId == 0 ? false: true);
+ vlanIdBuilder.setVlanIdPresent(vlanId == 0 ? false : true);
vlanMatchBuilder.setVlanId(vlanIdBuilder.build());
matchBuilder.setVlanMatch(vlanMatchBuilder.build());
}
String ipv4PrefixStr = swMatch.getNwSrc().getValue();
if (swMatch.getNwSrcMask() != null) {
ipv4PrefixStr += PREFIX_SEPARATOR + swMatch.getNwSrcMask();
+ } else {
+ //Openflow Spec : 1.3.2
+ //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
+ // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
+ // statistics response.
+
+ ipv4PrefixStr += PREFIX_SEPARATOR + "32";
}
if (!ipv4PrefixStr.equals(noIp)) {
ipv4MatchBuilder.setIpv4Source(new Ipv4Prefix(ipv4PrefixStr));
String ipv4PrefixStr = swMatch.getNwDst().getValue();
if (swMatch.getNwDstMask() != null) {
ipv4PrefixStr += PREFIX_SEPARATOR + swMatch.getNwDstMask();
+ } else {
+ //Openflow Spec : 1.3.2
+ //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
+ // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
+ // statistics response.
+
+ ipv4PrefixStr += PREFIX_SEPARATOR + "32";
}
if (!ipv4PrefixStr.equals(noIp)) {
ipv4MatchBuilder.setIpv4Destination(new Ipv4Prefix(ipv4PrefixStr));
}
}
if (!swMatch.getWildcards().isNWTOS().booleanValue() && swMatch.getNwTos() != null) {
- // DSCP default value is 0 from the library but controller side it
- // is null.
- // look if there better solution
- if (0 != swMatch.getNwTos()) {
- ipMatchBuilder.setIpDscp(new Dscp(swMatch.getNwTos()));
- }
+ Short dscp = ActionUtil.tosToDscp(swMatch.getNwTos().shortValue());
+ ipMatchBuilder.setIpDscp(new Dscp(dscp));
matchBuilder.setIpMatch(ipMatchBuilder.build());
}
* match
*
* @param match
- * @param swMatch
- * @param datapathid
- * @param ofVersion
+ * @param swMatch
+ * @param datapathid
+ * @param ofVersion
* @return md-sal match instance
* @author avishnoi@in.ibm.com
*/
return OfMatchToSALMatchConvertor(swMatch.getMatchEntries(), datapathid, ofVersion);
}
- private static MatchBuilder OfMatchToSALMatchConvertor(List<MatchEntries> swMatchList, final BigInteger datapathid,
- OpenflowVersion ofVersion){
-
+ private static MatchBuilder OfMatchToSALMatchConvertor(List<MatchEntries> swMatchList, final BigInteger datapathid,
+ OpenflowVersion ofVersion) {
+
MatchBuilder matchBuilder = new MatchBuilder();
EthernetMatchBuilder ethMatchBuilder = new EthernetMatchBuilder();
VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
if (ofMatch.getOxmMatchField().equals(InPort.class)) {
PortNumberMatchEntry portNumber = ofMatch.getAugmentation(PortNumberMatchEntry.class);
- if(portNumber != null){
+ if (portNumber != null) {
Long portNo = portNumber.getPortNumber().getValue();
matchBuilder.setInPort(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathid, portNo, ofVersion));
}
}
} else if (ofMatch.getOxmMatchField().equals(EthSrc.class)) {
MacAddressMatchEntry macAddressMatchEntry = ofMatch.getAugmentation(MacAddressMatchEntry.class);
+ final MaskMatchEntry sourceMask = ofMatch.getAugmentation(MaskMatchEntry.class);
if (macAddressMatchEntry != null) {
EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
ethSourceBuilder.setAddress(macAddressMatchEntry.getMacAddress());
+ if (sourceMask != null) {
+ ethSourceBuilder.setMask(new MacAddress(macAddressToString(sourceMask.getMask())));
+ }
ethMatchBuilder.setEthernetSource(ethSourceBuilder.build());
matchBuilder.setEthernetMatch(ethMatchBuilder.build());
}
} else if (ofMatch.getOxmMatchField().equals(EthDst.class)) {
MacAddressMatchEntry macAddressMatchEntry = ofMatch.getAugmentation(MacAddressMatchEntry.class);
+ final MaskMatchEntry destinationMask = ofMatch.getAugmentation(MaskMatchEntry.class);
if (macAddressMatchEntry != null) {
EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
ethDestinationBuilder.setAddress(macAddressMatchEntry.getMacAddress());
+ if (destinationMask != null) {
+ ethDestinationBuilder.setMask(new MacAddress(macAddressToString(destinationMask.getMask())));
+ }
ethMatchBuilder.setEthernetDestination(ethDestinationBuilder.build());
matchBuilder.setEthernetMatch(ethMatchBuilder.build());
}
VlanIdBuilder vlanBuilder = new VlanIdBuilder();
vlanBuilder.setVlanId(new org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId(
vlanVidMatchEntry.getVlanVid()))
- .setVlanIdPresent(vlanVidMatchEntry.isCfiBit());
+ .setVlanIdPresent(vlanVidMatchEntry.isCfiBit());
vlanMatchBuilder.setVlanId(vlanBuilder.build());
matchBuilder.setVlanMatch(vlanMatchBuilder.build());
}
String ipv4PrefixStr = ipv4AddressMatchEntry.getIpv4Address().getValue();
MaskMatchEntry maskMatchEntry = ofMatch.getAugmentation(MaskMatchEntry.class);
if (maskMatchEntry != null) {
- int receivedMask = ByteBuffer.wrap(maskMatchEntry.getMask()).getInt();
- int shiftCount=0;
- while(receivedMask != 0xffffffff){
- receivedMask = receivedMask >> 1;
- shiftCount++;
- }
- ipv4PrefixStr += PREFIX_SEPARATOR + (32-shiftCount);
- }else{
+ ipv4PrefixStr += MatchConvertorUtil.getIpv4Mask(maskMatchEntry);
+ } else {
//Openflow Spec : 1.3.2
//An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
// So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
// statistics response.
- ipv4PrefixStr+=PREFIX_SEPARATOR + "32";
+ ipv4PrefixStr += PREFIX_SEPARATOR + "32";
}
if (ofMatch.getOxmMatchField().equals(Ipv4Src.class)) {
ipv4MatchBuilder.setIpv4Source(new Ipv4Prefix(ipv4PrefixStr));
}
matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
}
- }
-
- else if (ofMatch.getOxmMatchField().equals(TunnelIpv4Dst.class)
+ } else if (ofMatch.getOxmMatchField().equals(TunnelIpv4Dst.class)
|| ofMatch.getOxmMatchField().equals(TunnelIpv4Src.class)) {
Ipv4AddressMatchEntry ipv4AddressMatchEntry = ofMatch.getAugmentation(Ipv4AddressMatchEntry.class);
if (ipv4AddressMatchEntry != null) {
MaskMatchEntry maskMatchEntry = ofMatch.getAugmentation(MaskMatchEntry.class);
if (maskMatchEntry != null) {
ipv4PrefixStr += PREFIX_SEPARATOR + ByteBuffer.wrap(maskMatchEntry.getMask()).getInt();
+ } else {
+ //Openflow Spec : 1.3.2
+ //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
+ // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
+ // statistics response.
+
+ ipv4PrefixStr += PREFIX_SEPARATOR + "32";
}
if (ofMatch.getOxmMatchField().equals(TunnelIpv4Dst.class)) {
tunnelIpv4MatchBuilder.setTunnelIpv4Destination(new Ipv4Prefix(ipv4PrefixStr));
}
matchBuilder.setLayer3Match(tunnelIpv4MatchBuilder.build());
}
- }
- else if (ofMatch.getOxmMatchField().equals(ArpOp.class)) {
+ } else if (ofMatch.getOxmMatchField().equals(ArpOp.class)) {
OpCodeMatchEntry opCodeMatchEntry = ofMatch.getAugmentation(OpCodeMatchEntry.class);
if (opCodeMatchEntry != null) {
arpMatchBuilder.setArpOp(opCodeMatchEntry.getOpCode());
String ipv4PrefixStr = ipv4AddressMatchEntry.getIpv4Address().getValue();
MaskMatchEntry maskMatchEntry = ofMatch.getAugmentation(MaskMatchEntry.class);
if (maskMatchEntry != null) {
- ipv4PrefixStr += PREFIX_SEPARATOR + ByteBuffer.wrap(maskMatchEntry.getMask()).getInt();
+ ipv4PrefixStr += MatchConvertorUtil.getIpv4Mask(maskMatchEntry);
+ } else {
+ //Openflow Spec : 1.3.2
+ //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
+ // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
+ // statistics response.
+
+ ipv4PrefixStr += PREFIX_SEPARATOR + "32";
}
if (ofMatch.getOxmMatchField().equals(ArpSpa.class)) {
arpMatchBuilder.setArpSourceTransportAddress(new Ipv4Prefix(ipv4PrefixStr));
if (ipv6AddressMatchEntry != null) {
String ipv6PrefixStr = ipv6AddressMatchEntry.getIpv6Address().getValue();
MaskMatchEntry maskMatchEntry = ofMatch.getAugmentation(MaskMatchEntry.class);
- if(maskMatchEntry != null){
+ if (maskMatchEntry != null) {
ipv6PrefixStr += PREFIX_SEPARATOR
+ MatchConvertorUtil.ipv6NetmaskArrayToCIDRValue(maskMatchEntry.getMask());
}
-
+
if (ofMatch.getOxmMatchField().equals(Ipv6Src.class)) {
ipv6MatchBuilder.setIpv6Source(new Ipv6Prefix(ipv6PrefixStr));
}
pbbBuilder.setPbbIsid(isidMatchEntry.getIsid());
MaskMatchEntry maskMatchEntry = ofMatch.getAugmentation(MaskMatchEntry.class);
if (maskMatchEntry != null) {
- pbbBuilder.setPbbMask(ByteUtil.bytesToUnsignedInt(maskMatchEntry.getMask()));
+ pbbBuilder.setPbbMask(ByteUtil.bytesToUnsignedMedium(maskMatchEntry.getMask()));
}
protocolMatchFieldsBuilder.setPbb(pbbBuilder.build());
matchBuilder.setProtocolMatchFields(protocolMatchFieldsBuilder.build());
tcpFlagMatchBuilder.setTcpFlag(tcpFlagMatch.getTcpFlag());
matchBuilder.setTcpFlagMatch(tcpFlagMatchBuilder.build());
}
- }
+ }
}
return matchBuilder;
}
+
+
private static MatchEntries toOfMplsPbb(final Pbb pbb) {
MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
boolean hasmask = false;
matchEntriesBuilder.addAugmentation(IsidMatchEntry.class, isidBuilder.build());
if (pbb.getPbbMask() != null) {
hasmask = true;
- addMaskAugmentation(matchEntriesBuilder, ByteUtil.unsignedIntToBytes(pbb.getPbbMask()));
+ addMaskAugmentation(matchEntriesBuilder, ByteUtil.unsignedMediumToBytes(pbb.getPbbMask()));
}
matchEntriesBuilder.setHasMask(hasmask);
return matchEntriesBuilder.build();
}
private static MatchEntries toOfMetadata(final Class<? extends MatchField> field, final BigInteger metadata,
- final BigInteger metadataMask) {
+ final BigInteger metadataMask) {
MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
boolean hasmask = false;
matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
}
public static MatchEntries toOfMacAddress(final Class<? extends MatchField> field,
- final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress macAddress,
- final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress mask) {
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress macAddress,
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress mask) {
MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
boolean hasmask = false;
matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
}
private static MatchEntries toOfLayer3Port(final Class<? extends MatchField> field,
- final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber portNumber) {
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber portNumber) {
MatchEntriesBuilder matchEntriesBuilder = new MatchEntriesBuilder();
matchEntriesBuilder.setOxmClass(OpenflowBasicClass.class);
matchEntriesBuilder.setHasMask(false);
/**
* @return true if Ipv4Prefix contains prefix (and it is used in mask),
- * false otherwise
+ * false otherwise
*/
private static boolean addIpv4PrefixAugmentation(final MatchEntriesBuilder builder, final Ipv4Prefix address) {
boolean hasMask = false;
final int prefix;
if (addressParts.hasNext()) {
- prefix = Integer.parseInt(addressParts.next());
+ int potentionalPrefix = Integer.parseInt(addressParts.next());
+ prefix = potentionalPrefix < 32 ? potentionalPrefix : 0;
} else {
prefix = 0;
}
builder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());
if (prefix != 0) {
int mask = 0xffffffff << (32 - prefix);
- byte[] maskBytes = new byte[] { (byte) (mask >>> 24), (byte) (mask >>> 16), (byte) (mask >>> 8),
- (byte) mask };
+ byte[] maskBytes = new byte[]{(byte) (mask >>> 24), (byte) (mask >>> 16), (byte) (mask >>> 8),
+ (byte) mask};
addMaskAugmentation(builder, maskBytes);
hasMask = true;
}