Rob Vaterlaus | 934b4ad | 2013-11-12 10:08:59 -0800 | [diff] [blame^] | 1 | package org.projectfloodlight.protocol.match; |
| 2 | |
| 3 | import static org.hamcrest.CoreMatchers.is; |
| 4 | import static org.junit.Assert.assertThat; |
| 5 | import static org.junit.Assert.fail; |
| 6 | |
| 7 | import java.util.Iterator; |
| 8 | |
| 9 | import org.junit.Test; |
| 10 | import org.projectfloodlight.openflow.protocol.OFFactory; |
| 11 | import org.projectfloodlight.openflow.protocol.OFVersion; |
| 12 | import org.projectfloodlight.openflow.protocol.match.Match; |
| 13 | import org.projectfloodlight.openflow.protocol.match.MatchField; |
| 14 | import org.projectfloodlight.openflow.protocol.match.MatchFields; |
| 15 | import org.projectfloodlight.openflow.types.ArpOpcode; |
| 16 | import org.projectfloodlight.openflow.types.EthType; |
| 17 | import org.projectfloodlight.openflow.types.IPv4Address; |
| 18 | import org.projectfloodlight.openflow.types.IpProtocol; |
| 19 | import org.projectfloodlight.openflow.types.MacAddress; |
| 20 | import org.projectfloodlight.openflow.types.Masked; |
| 21 | import org.projectfloodlight.openflow.types.OFPort; |
| 22 | import org.projectfloodlight.openflow.types.TransportPort; |
| 23 | |
| 24 | import com.google.common.collect.Iterables; |
| 25 | |
| 26 | public class MatchFieldIterationBase { |
| 27 | |
| 28 | private OFFactory factory; |
| 29 | |
| 30 | protected MatchFieldIterationBase(OFFactory factory) { |
| 31 | this.factory = factory; |
| 32 | } |
| 33 | |
| 34 | @Test |
| 35 | public void iterateEmptyMatch() { |
| 36 | Match match = factory.buildMatch().build(); |
| 37 | Iterator<MatchField<?>> iter = match.getMatchFields().iterator(); |
| 38 | assertThat(iter.hasNext(), is(false)); |
| 39 | } |
| 40 | |
| 41 | @Test |
| 42 | public void iterateSingleExactMatchField() { |
| 43 | OFPort port5 = OFPort.of(5); |
| 44 | Match match = factory.buildMatch() |
| 45 | .setExact(MatchField.IN_PORT, port5) |
| 46 | .build(); |
| 47 | Iterator<MatchField<?>> iter = match.getMatchFields().iterator(); |
| 48 | assertThat(iter.hasNext(), is(true)); |
| 49 | MatchField<?> matchField = iter.next(); |
| 50 | assertThat(matchField.id, is(MatchFields.IN_PORT)); |
| 51 | assertThat(match.isExact(matchField), is(true)); |
| 52 | @SuppressWarnings("unchecked") |
| 53 | MatchField<OFPort> portMatchField = (MatchField<OFPort>) matchField; |
| 54 | OFPort port = match.get(portMatchField); |
| 55 | assertThat(port, is(port5)); |
| 56 | assertThat(iter.hasNext(), is(false)); |
| 57 | } |
| 58 | |
| 59 | @SuppressWarnings("unchecked") |
| 60 | @Test |
| 61 | public void iterateExactMatchFields() { |
| 62 | OFPort port5 = OFPort.of(5); |
| 63 | MacAddress macSrc = MacAddress.of("00:01:02:03:04:05"); |
| 64 | MacAddress macDst = MacAddress.of("01:01:02:02:03:03"); |
| 65 | IPv4Address ipSrc = IPv4Address.of("10.192.20.1"); |
| 66 | IPv4Address ipDst = IPv4Address.of("10.192.20.2"); |
| 67 | TransportPort tcpSrc = TransportPort.of(100); |
| 68 | TransportPort tcpDst = TransportPort.of(200); |
| 69 | Match match = factory.buildMatch() |
| 70 | .setExact(MatchField.IN_PORT, port5) |
| 71 | .setExact(MatchField.ETH_TYPE, EthType.IPv4) |
| 72 | .setExact(MatchField.ETH_SRC, macSrc) |
| 73 | .setExact(MatchField.ETH_DST, macDst) |
| 74 | .setExact(MatchField.IP_PROTO, IpProtocol.TCP) |
| 75 | .setExact(MatchField.IPV4_SRC, ipSrc) |
| 76 | .setExact(MatchField.IPV4_DST, ipDst) |
| 77 | .setExact(MatchField.TCP_SRC, tcpSrc) |
| 78 | .setExact(MatchField.TCP_DST, tcpDst) |
| 79 | .build(); |
| 80 | assertThat(Iterables.size(match.getMatchFields()), is(9)); |
| 81 | for (MatchField<?> matchField: match.getMatchFields()) { |
| 82 | switch (matchField.id) { |
| 83 | case IN_PORT: |
| 84 | OFPort port = match.get((MatchField<OFPort>) matchField); |
| 85 | assertThat(port, is(port5)); |
| 86 | break; |
| 87 | case ETH_TYPE: |
| 88 | EthType ethType = match.get((MatchField<EthType>) matchField); |
| 89 | assertThat(ethType, is(EthType.IPv4)); |
| 90 | break; |
| 91 | case ETH_SRC: |
| 92 | MacAddress mac = match.get((MatchField<MacAddress>) matchField); |
| 93 | assertThat(mac, is(macSrc)); |
| 94 | break; |
| 95 | case ETH_DST: |
| 96 | mac = match.get((MatchField<MacAddress>) matchField); |
| 97 | assertThat(mac, is(macDst)); |
| 98 | break; |
| 99 | case IP_PROTO: |
| 100 | IpProtocol ipProtocol = match.get((MatchField<IpProtocol>) matchField); |
| 101 | assertThat(ipProtocol, is(IpProtocol.TCP)); |
| 102 | break; |
| 103 | case IPV4_SRC: |
| 104 | IPv4Address ip = match.get((MatchField<IPv4Address>) matchField); |
| 105 | assertThat(ip, is(ipSrc)); |
| 106 | break; |
| 107 | case IPV4_DST: |
| 108 | ip = match.get((MatchField<IPv4Address>) matchField); |
| 109 | assertThat(ip, is(ipDst)); |
| 110 | break; |
| 111 | case TCP_SRC: |
| 112 | TransportPort tcp = match.get((MatchField<TransportPort>) matchField); |
| 113 | assertThat(tcp, is(tcpSrc)); |
| 114 | break; |
| 115 | case TCP_DST: |
| 116 | tcp = match.get((MatchField<TransportPort>) matchField); |
| 117 | assertThat(tcp, is(tcpDst)); |
| 118 | break; |
| 119 | default: |
| 120 | fail("Unexpected match field returned from iterator"); |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | @SuppressWarnings("unchecked") |
| 126 | @Test |
| 127 | public void iterateArpFields() { |
| 128 | MacAddress macSrc = MacAddress.of("00:01:02:03:04:05"); |
| 129 | MacAddress macDst = MacAddress.of("01:01:02:02:03:03"); |
| 130 | IPv4Address ipSrc = IPv4Address.of("10.192.20.1"); |
| 131 | IPv4Address ipDst = IPv4Address.of("10.192.20.2"); |
| 132 | OFVersion version = factory.getVersion(); |
| 133 | boolean supportsArpHardwareAddress = (version != OFVersion.OF_10) && |
| 134 | (version != OFVersion.OF_11) && (version != OFVersion.OF_12); |
| 135 | int matchFieldCount = 4; |
| 136 | Match.Builder builder = factory.buildMatch(); |
| 137 | builder.setExact(MatchField.ETH_TYPE, EthType.ARP) |
| 138 | .setExact(MatchField.ARP_OP, ArpOpcode.REPLY) |
| 139 | .setExact(MatchField.ARP_SPA, ipSrc) |
| 140 | .setExact(MatchField.ARP_TPA, ipDst); |
| 141 | if (supportsArpHardwareAddress) { |
| 142 | builder.setExact(MatchField.ARP_SHA, macSrc); |
| 143 | builder.setExact(MatchField.ARP_THA, macDst); |
| 144 | matchFieldCount += 2; |
| 145 | } |
| 146 | Match match = builder.build(); |
| 147 | assertThat(Iterables.size(match.getMatchFields()), is(matchFieldCount)); |
| 148 | for (MatchField<?> matchField: match.getMatchFields()) { |
| 149 | switch (matchField.id) { |
| 150 | case ETH_TYPE: |
| 151 | EthType ethType = match.get((MatchField<EthType>) matchField); |
| 152 | assertThat(ethType, is(EthType.ARP)); |
| 153 | break; |
| 154 | case ARP_OP: |
| 155 | ArpOpcode opcode = match.get((MatchField<ArpOpcode>) matchField); |
| 156 | assertThat(opcode, is(ArpOpcode.REPLY)); |
| 157 | break; |
| 158 | case ARP_SHA: |
| 159 | MacAddress mac = match.get((MatchField<MacAddress>) matchField); |
| 160 | assertThat(mac, is(macSrc)); |
| 161 | break; |
| 162 | case ARP_THA: |
| 163 | mac = match.get((MatchField<MacAddress>) matchField); |
| 164 | assertThat(mac, is(macDst)); |
| 165 | break; |
| 166 | case ARP_SPA: |
| 167 | IPv4Address ip = match.get((MatchField<IPv4Address>) matchField); |
| 168 | assertThat(ip, is(ipSrc)); |
| 169 | break; |
| 170 | case ARP_TPA: |
| 171 | ip = match.get((MatchField<IPv4Address>) matchField); |
| 172 | assertThat(ip, is(ipDst)); |
| 173 | break; |
| 174 | default: |
| 175 | fail("Unexpected match field returned from iterator"); |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | @SuppressWarnings("unchecked") |
| 181 | @Test |
| 182 | public void iterateMaskedFields() { |
| 183 | MacAddress macSrc = MacAddress.of("01:02:03:04:00:00"); |
| 184 | MacAddress macSrcMask = MacAddress.of("FF:FF:FF:FF:00:00"); |
| 185 | MacAddress macDst = MacAddress.of("11:22:33:00:00:00"); |
| 186 | MacAddress macDstMask = MacAddress.of("FF:FF:FF:00:00:00"); |
| 187 | IPv4Address ipSrc = IPv4Address.of("10.192.20.0"); |
| 188 | IPv4Address ipSrcMask = IPv4Address.of("255.255.255.0"); |
| 189 | IPv4Address ipDst = IPv4Address.of("10.192.20.0"); |
| 190 | IPv4Address ipDstMask = IPv4Address.of("255.255.255.128"); |
| 191 | TransportPort tcpSrcMask = TransportPort.of(0x01F0); |
| 192 | OFVersion version = factory.getVersion(); |
| 193 | boolean supportsAllMasks = (version != OFVersion.OF_10) && |
| 194 | (version != OFVersion.OF_11) && (version != OFVersion.OF_12); |
| 195 | int matchFieldCount = 4; |
| 196 | Match.Builder builder = factory.buildMatch() |
| 197 | .setExact(MatchField.ETH_TYPE, EthType.IPv4) |
| 198 | .setMasked(MatchField.IPV4_SRC, ipSrc, ipSrcMask) |
| 199 | .setMasked(MatchField.IPV4_DST, ipDst, ipDstMask) |
| 200 | .setExact(MatchField.IP_PROTO, IpProtocol.TCP); |
| 201 | if (supportsAllMasks) { |
| 202 | builder.setMasked(MatchField.ETH_SRC, macSrc, macSrcMask); |
| 203 | builder.setMasked(MatchField.ETH_DST, macDst, macDstMask); |
| 204 | builder.setMasked(MatchField.TCP_SRC, tcpSrcMask, tcpSrcMask); |
| 205 | matchFieldCount += 3; |
| 206 | } |
| 207 | Match match = builder.build(); |
| 208 | assertThat(Iterables.size(match.getMatchFields()), is(matchFieldCount)); |
| 209 | for (MatchField<?> matchField: match.getMatchFields()) { |
| 210 | switch (matchField.id) { |
| 211 | case ETH_TYPE: |
| 212 | EthType ethType = match.get((MatchField<EthType>) matchField); |
| 213 | assertThat(ethType, is(EthType.IPv4)); |
| 214 | break; |
| 215 | case ETH_SRC: |
| 216 | Masked<MacAddress> mac = match.getMasked((MatchField<MacAddress>) matchField); |
| 217 | assertThat(mac.getValue(), is(macSrc)); |
| 218 | assertThat(mac.getMask(), is(macSrcMask)); |
| 219 | break; |
| 220 | case ETH_DST: |
| 221 | mac = match.getMasked((MatchField<MacAddress>) matchField); |
| 222 | assertThat(mac.getValue(), is(macDst)); |
| 223 | assertThat(mac.getMask(), is(macDstMask)); |
| 224 | break; |
| 225 | case IP_PROTO: |
| 226 | IpProtocol ipProtocol = match.get((MatchField<IpProtocol>) matchField); |
| 227 | assertThat(ipProtocol, is(IpProtocol.TCP)); |
| 228 | break; |
| 229 | case IPV4_SRC: |
| 230 | Masked<IPv4Address> ip = match.getMasked((MatchField<IPv4Address>) matchField); |
| 231 | assertThat(ip.getValue(), is(ipSrc)); |
| 232 | assertThat(ip.getMask(), is(ipSrcMask)); |
| 233 | break; |
| 234 | case IPV4_DST: |
| 235 | ip = match.getMasked((MatchField<IPv4Address>) matchField); |
| 236 | assertThat(ip.getValue(), is(ipDst)); |
| 237 | assertThat(ip.getMask(), is(ipDstMask)); |
| 238 | break; |
| 239 | case TCP_SRC: |
| 240 | Masked<TransportPort> tcp = match.getMasked((MatchField<TransportPort>) matchField); |
| 241 | assertThat(tcp.getValue(), is(tcpSrcMask)); |
| 242 | assertThat(tcp.getMask(), is(tcpSrcMask)); |
| 243 | break; |
| 244 | default: |
| 245 | fail("Unexpected match field returned from iterator"); |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | } |