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 java.math.BigInteger;
import java.nio.ByteBuffer;
import org.opendaylight.openflowplugin.openflow.md.util.ByteUtil;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
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.IetfInetUtil;
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.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
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.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
private static final short PROTO_ICMPV4 = 1;
private static final String NO_IP = "0.0.0.0/0";
+ // Pre-calculated masks for the 33 possible values. Do not give them out, but clone() them as they may
+ // end up being leaked and vulnerable.
+ private static final byte[][] IPV4_MASKS;
+ static {
+ final byte[][] tmp = new byte[33][];
+ for (int i = 0; i <= 32; ++i) {
+ final int mask = 0xffffffff << (32 - i);
+ tmp[i] = new byte[]{(byte) (mask >>> 24), (byte) (mask >>> 16), (byte) (mask >>> 8), (byte) mask};
+ }
+
+ IPV4_MASKS = tmp;
+ }
+
@Override
public List<MatchEntry> convert(
final org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match match, final BigInteger datapathid) {
}
- private void protocolMatchFields(List<MatchEntry> matchEntryList,
- ProtocolMatchFields protocolMatchFields) {
+ private static void protocolMatchFields(final List<MatchEntry> matchEntryList,
+ final ProtocolMatchFields protocolMatchFields) {
if (protocolMatchFields != null) {
if (protocolMatchFields.getMplsLabel() != null) {
matchEntryList.add(toOfMplsLabel(protocolMatchFields.getMplsLabel()));
}
- private void layer3Match(List<MatchEntry> matchEntryList,
- Layer3Match layer3Match) {
+ private static void layer3Match(final List<MatchEntry> matchEntryList, final Layer3Match layer3Match) {
if (layer3Match != null) {
- if (layer3Match instanceof Ipv4Match) {
+ if(layer3Match instanceof Ipv4MatchArbitraryBitMask) {
+ Ipv4MatchArbitraryBitMask ipv4MatchArbitraryBitMaskFields = (Ipv4MatchArbitraryBitMask) layer3Match;
+ if (ipv4MatchArbitraryBitMaskFields.getIpv4SourceAddressNoMask() != null) {
+ MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
+ matchEntryBuilder.setOxmClass(OpenflowBasicClass.class);
+ matchEntryBuilder.setOxmMatchField(Ipv4Src.class);
+
+ Ipv4SrcCaseBuilder ipv4SrcCaseBuilder = new Ipv4SrcCaseBuilder();
+ Ipv4SrcBuilder ipv4SrcBuilder = new Ipv4SrcBuilder();
+
+ ipv4SrcBuilder.setIpv4Address(ipv4MatchArbitraryBitMaskFields.getIpv4SourceAddressNoMask());
+ DottedQuad sourceArbitrarySubNetMask = ipv4MatchArbitraryBitMaskFields.getIpv4SourceArbitraryBitmask();
+
+ boolean hasMask = false;
+ if (sourceArbitrarySubNetMask != null) {
+ byte[] maskByteArray = IpConversionUtil.convertArbitraryMaskToByteArray(sourceArbitrarySubNetMask);
+ if (maskByteArray != null) {
+ ipv4SrcBuilder.setMask(maskByteArray);
+ hasMask = true;
+ }
+ }
+ matchEntryBuilder.setHasMask(hasMask);
+ ipv4SrcCaseBuilder.setIpv4Src(ipv4SrcBuilder.build());
+ matchEntryBuilder.setMatchEntryValue(ipv4SrcCaseBuilder.build());
+ matchEntryList.add(matchEntryBuilder.build());
+ }
+ if (ipv4MatchArbitraryBitMaskFields.getIpv4DestinationAddressNoMask() != null) {
+ MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
+ matchEntryBuilder.setOxmClass(OpenflowBasicClass.class);
+ matchEntryBuilder.setOxmMatchField(Ipv4Dst.class);
+
+ Ipv4DstCaseBuilder ipv4DstCaseBuilder = new Ipv4DstCaseBuilder();
+ Ipv4DstBuilder ipv4DstBuilder = new Ipv4DstBuilder();
+
+ ipv4DstBuilder.setIpv4Address(ipv4MatchArbitraryBitMaskFields.getIpv4DestinationAddressNoMask());
+ DottedQuad destArbitrarySubNetMask = ipv4MatchArbitraryBitMaskFields.getIpv4DestinationArbitraryBitmask();
+
+ boolean hasMask = false;
+ if (destArbitrarySubNetMask != null) {
+ byte[] maskByteArray = IpConversionUtil.convertArbitraryMaskToByteArray(destArbitrarySubNetMask);
+ if (maskByteArray != null) {
+ ipv4DstBuilder.setMask(maskByteArray);
+ hasMask = true;
+ }
+ }
+ matchEntryBuilder.setHasMask(hasMask);
+ ipv4DstCaseBuilder.setIpv4Dst(ipv4DstBuilder.build());
+ matchEntryBuilder.setMatchEntryValue(ipv4DstCaseBuilder.build());
+ matchEntryList.add(matchEntryBuilder.build());
+ }
+ }
+ if(layer3Match instanceof Ipv4Match){
Ipv4Match ipv4Match = (Ipv4Match) layer3Match;
if (ipv4Match.getIpv4Source() != null) {
Ipv4Prefix ipv4Prefix = ipv4Match.getIpv4Source();
}
- private void icmpv6Match(List<MatchEntry> matchEntryList,
- Icmpv6Match icmpv6Match) {
+ private static void icmpv6Match(final List<MatchEntry> matchEntryList, final Icmpv6Match icmpv6Match) {
if (icmpv6Match != null) {
if (icmpv6Match.getIcmpv6Type() != null) {
matchEntryList.add(toOfIcmpv6Type(icmpv6Match.getIcmpv6Type()));
}
- private void icmpv4Match(List<MatchEntry> matchEntryList,
- Icmpv4Match icmpv4Match) {
+ private static void icmpv4Match(final List<MatchEntry> matchEntryList, final Icmpv4Match icmpv4Match) {
if (icmpv4Match != null) {
if (icmpv4Match.getIcmpv4Type() != null) {
matchEntryList.add(toOfIcmpv4Type(icmpv4Match.getIcmpv4Type()));
}
- private void layer4Match(List<MatchEntry> matchEntryList,
- Layer4Match layer4Match) {
+ private static void layer4Match(final List<MatchEntry> matchEntryList, final Layer4Match layer4Match) {
if (layer4Match != null) {
if (layer4Match instanceof TcpMatch) {
TcpMatch tcpMatch = (TcpMatch) layer4Match;
}
- private void ipMatch(List<MatchEntry> matchEntryList, IpMatch ipMatch) {
+ private static void ipMatch(final List<MatchEntry> matchEntryList, final IpMatch ipMatch) {
if (ipMatch != null) {
if (ipMatch.getIpDscp() != null) {
matchEntryList.add(toOfIpDscp(ipMatch.getIpDscp()));
if (ipMatch.getIpProtocol() != null) {
matchEntryList.add(toOfIpProto(ipMatch.getIpProtocol()));
}
-
}
}
- private void vlanMatch(List<MatchEntry> matchEntryList,
- VlanMatch vlanMatch) {
+ private static void vlanMatch(final List<MatchEntry> matchEntryList, final VlanMatch vlanMatch) {
if (vlanMatch != null) {
if (vlanMatch.getVlanId() != null) {
VlanId vlanId = vlanMatch.getVlanId();
}
- private void ethernetMatch(List<MatchEntry> matchEntryList,
- EthernetMatch ethernetMatch) {
+ private static void ethernetMatch(final List<MatchEntry> matchEntryList, final EthernetMatch ethernetMatch) {
if (ethernetMatch != null) {
EthernetDestination ethernetDestination = ethernetMatch.getEthernetDestination();
if (ethernetDestination != null) {
}
if (prefix != 0) {
- int mask = 0xffffffff << (32 - prefix);
- byte[] maskBytes = new byte[]{(byte) (mask >>> 24), (byte) (mask >>> 16), (byte) (mask >>> 8),
- (byte) mask};
- return maskBytes;
+ // clone() is necessary to protect our constants
+ return IPV4_MASKS[prefix].clone();
}
return null;
}
/**
* Method convert Openflow 1.0 specific flow match to MD-SAL format flow
* match
- *
- * @param swMatch
- * @return
- * @author avishnoi@in.ibm.com
+ * @param swMatch source match
+ * @param datapathid datapath id
+ * @param ofVersion openflow version
+ * @return match builder
*/
public static MatchBuilder fromOFMatchV10ToSALMatch(@Nonnull final MatchV10 swMatch, @Nonnull final BigInteger datapathid, @Nonnull final OpenflowVersion ofVersion) {
MatchBuilder matchBuilder = new MatchBuilder();
matchBuilder.setVlanMatch(vlanMatchBuilder.build());
}
if (!swMatch.getWildcards().isDLTYPE().booleanValue() && swMatch.getNwSrc() != null) {
- String ipv4PrefixStr = swMatch.getNwSrc().getValue();
+ final Ipv4Prefix prefix;
if (swMatch.getNwSrcMask() != null) {
- ipv4PrefixStr += IpConversionUtil.PREFIX_SEPARATOR + swMatch.getNwSrcMask();
+ prefix = IetfInetUtil.INSTANCE.ipv4PrefixFor(swMatch.getNwSrc(), 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 += IpConversionUtil.PREFIX_SEPARATOR + "32";
+ prefix = IetfInetUtil.INSTANCE.ipv4PrefixFor(swMatch.getNwSrc());
}
- if (!NO_IP.equals(ipv4PrefixStr)) {
- ipv4MatchBuilder.setIpv4Source(new Ipv4Prefix(ipv4PrefixStr));
+ if (!NO_IP.equals(prefix.getValue())) {
+ ipv4MatchBuilder.setIpv4Source(prefix);
matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
}
}
if (!swMatch.getWildcards().isDLTYPE().booleanValue() && swMatch.getNwDst() != null) {
- String ipv4PrefixStr = swMatch.getNwDst().getValue();
+ final Ipv4Prefix prefix;
if (swMatch.getNwDstMask() != null) {
- ipv4PrefixStr += IpConversionUtil.PREFIX_SEPARATOR + swMatch.getNwDstMask();
+ prefix = IetfInetUtil.INSTANCE.ipv4PrefixFor(swMatch.getNwDst(), 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 += IpConversionUtil.PREFIX_SEPARATOR + "32";
+ prefix = IetfInetUtil.INSTANCE.ipv4PrefixFor(swMatch.getNwDst());
}
- if (!NO_IP.equals(ipv4PrefixStr)) {
- ipv4MatchBuilder.setIpv4Destination(new Ipv4Prefix(ipv4PrefixStr));
+ if (!NO_IP.equals(prefix.getValue())) {
+ ipv4MatchBuilder.setIpv4Destination(prefix);
matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
}
}
* Method converts Openflow 1.3+ specific flow match to MD-SAL format flow
* match
*
- * @param swMatch
- * @param swMatch
- * @param datapathid
- * @param ofVersion
+ * @param swMatch source match
+ * @param datapathid datapath id
+ * @param ofVersion openflow version
* @return md-sal match instance
* @author avishnoi@in.ibm.com
*/
Icmpv4MatchBuilder icmpv4MatchBuilder = new Icmpv4MatchBuilder();
Icmpv6MatchBuilder icmpv6MatchBuilder = new Icmpv6MatchBuilder();
Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder();
+ Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
ArpMatchBuilder arpMatchBuilder = new ArpMatchBuilder();
Ipv6MatchBuilder ipv6MatchBuilder = new Ipv6MatchBuilder();
ProtocolMatchFieldsBuilder protocolMatchFieldsBuilder = new ProtocolMatchFieldsBuilder();
org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.src._case.Ipv4Src ipv4Address = ((Ipv4SrcCase) ofMatch.getMatchEntryValue()).getIpv4Src();
if (ipv4Address != null) {
byte[] mask = ipv4Address.getMask();
- String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
- setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
- matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ if (mask != null && IpConversionUtil.isArbitraryBitMask(mask)) {
+ DottedQuad dottedQuadMask = IpConversionUtil.createArbitraryBitMask(mask);
+ String Ipv4Address = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder, ofMatch, dottedQuadMask, Ipv4Address);
+ matchBuilder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());
+ }
+ else {
+ String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
+ matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ }
}
} else if (ofMatch.getOxmMatchField().equals(Ipv4Dst.class)) {
org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.dst._case.Ipv4Dst ipv4Address = ((Ipv4DstCase) ofMatch.getMatchEntryValue()).getIpv4Dst();
if (ipv4Address != null) {
byte[] mask = ipv4Address.getMask();
- String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
- setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
- matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ if(mask != null && IpConversionUtil.isArbitraryBitMask(mask)) {
+ DottedQuad dottedQuadMask = IpConversionUtil.createArbitraryBitMask(mask);
+ String Ipv4Address = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder, ofMatch, dottedQuadMask, Ipv4Address);
+ matchBuilder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());
+ }
+ else {
+ String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
+ matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ }
}
} else if (ofMatch.getOxmMatchField().equals(TunnelIpv4Dst.class)
|| ofMatch.getOxmMatchField().equals(TunnelIpv4Src.class)) {
}
private static void setIpv4MatchBuilderFields(final Ipv4MatchBuilder ipv4MatchBuilder, final MatchEntry ofMatch, final byte[] mask, final String ipv4PrefixStr) {
- Ipv4Prefix ipv4Prefix;
+ final Ipv4Prefix ipv4Prefix;
if (mask != null) {
ipv4Prefix = IpConversionUtil.createPrefix(new Ipv4Address(ipv4PrefixStr), mask);
} else {
}
}
+ private static void setIpv4MatchArbitraryBitMaskBuilderFields(final Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder, final MatchEntry ofMatch, final DottedQuad mask, final String ipv4AddressStr) {
+ Ipv4Address ipv4Address;
+ DottedQuad dottedQuad;
+ if (mask != null) {
+ dottedQuad = mask;
+ if (ofMatch.getOxmMatchField().equals(Ipv4Src.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceArbitraryBitmask(dottedQuad);
+ }
+ if (ofMatch.getOxmMatchField().equals(Ipv4Dst.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationArbitraryBitmask(dottedQuad);
+ }
+ }
+ ipv4Address = new Ipv4Address(ipv4AddressStr);
+ if (ofMatch.getOxmMatchField().equals(Ipv4Src.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceAddressNoMask(ipv4Address);
+ }
+ if (ofMatch.getOxmMatchField().equals(Ipv4Dst.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationAddressNoMask(ipv4Address);
+ }
+ }
+
private static MatchEntry toOfMplsPbb(final Pbb pbb) {
MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
/**
* Method converts OF SetField action to SAL SetFiled action.
*
- * @param action
+ * @param action input action
* @param ofVersion current ofp version
- * @return
+ * @return set field builder
*/
public static SetField fromOFSetFieldToSALSetFieldAction(
final Action action, final OpenflowVersion ofVersion) {
return setField.build();
}
-
}