blob: a3c397b78dd05c06eebeef8f4be39f65a314dc82 [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent;
Brian O'Connor7f8e3012014-02-15 23:59:29 -08002
Komal Shah399a2922014-05-28 01:57:40 -07003import java.util.Objects;
Brian O'Connor6dc44e92014-02-24 21:23:46 -08004
Brian O'Connor7f8e3012014-02-15 23:59:29 -08005import net.floodlightcontroller.util.MACAddress;
Komal Shah399a2922014-05-28 01:57:40 -07006import net.onrc.onos.core.packet.Ethernet;
Jonathan Hart23701d12014-04-03 10:45:48 -07007import net.onrc.onos.core.util.FlowEntryMatch;
Komal Shah399a2922014-05-28 01:57:40 -07008import net.onrc.onos.core.util.IPv4;
9import net.onrc.onos.core.util.IPv4Net;
Yuta HIGUCHIfb564502014-06-16 21:29:00 -070010import net.onrc.onos.core.util.PortNumber;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080011
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070012import org.projectfloodlight.openflow.protocol.OFFactory;
13import org.projectfloodlight.openflow.protocol.match.Match.Builder;
14import org.projectfloodlight.openflow.protocol.match.MatchField;
15import org.projectfloodlight.openflow.types.EthType;
16import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
17import org.projectfloodlight.openflow.types.MacAddress;
18import org.projectfloodlight.openflow.types.OFPort;
19
Brian O'Connor7f8e3012014-02-15 23:59:29 -080020/**
Brian O'Connora84723c2014-06-13 00:26:49 -070021 * A class to represent the OpenFlow match.
22 * <p>
23 * At the moment, the supported match conditions are:
24 * <ul>
25 * <li>source port
26 * <li>source and destination MAC address
27 * <li>source and destination IP address
28 * </ul>
29 * <p>
30 * TODO: extend this object to allow more match conditions
Brian O'Connor7f8e3012014-02-15 23:59:29 -080031 */
32
33public class Match {
Komal Shah399a2922014-05-28 01:57:40 -070034 private static final short IPV4_PREFIX_LEN = 32;
Ray Milkey269ffb92014-04-03 14:43:30 -070035 protected long sw;
36 protected MACAddress srcMac;
37 protected MACAddress dstMac;
Komal Shah399a2922014-05-28 01:57:40 -070038 protected int srcIp;
39 protected int dstIp;
Ray Milkey269ffb92014-04-03 14:43:30 -070040 protected long srcPort;
Yuta HIGUCHIe80664e2014-02-20 22:41:57 -080041
Brian O'Connora84723c2014-06-13 00:26:49 -070042 /**
43 * Constructor for Ethernet-based matches.
44 *
45 * @param sw switch's DPID
46 * @param srcPort source port on switch
47 * @param srcMac source Ethernet MAC address
48 * @param dstMac destination Ethernet MAC address
49 */
Ray Milkey269ffb92014-04-03 14:43:30 -070050 public Match(long sw, long srcPort,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070051 MACAddress srcMac, MACAddress dstMac) {
52 this(sw, srcPort, srcMac, dstMac,
53 ShortestPathIntent.EMPTYIPADDRESS,
54 ShortestPathIntent.EMPTYIPADDRESS);
Komal Shah399a2922014-05-28 01:57:40 -070055 }
56
Brian O'Connora84723c2014-06-13 00:26:49 -070057 /**
58 * Generic constructor.
59 *
60 * @param sw switch's DPID
61 * @param srcPort source port on switch
62 * @param srcMac source Ethernet MAC address
63 * @param dstMac destination Ethernet MAC address
64 * @param srcIp source IP address
65 * @param dstIp destination IP address
66 */
Komal Shah399a2922014-05-28 01:57:40 -070067 public Match(long sw, long srcPort, MACAddress srcMac, MACAddress dstMac,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070068 int srcIp, int dstIp) {
Komal Shah399a2922014-05-28 01:57:40 -070069
Ray Milkey269ffb92014-04-03 14:43:30 -070070 this.sw = sw;
71 this.srcPort = srcPort;
72 this.srcMac = srcMac;
73 this.dstMac = dstMac;
Komal Shah399a2922014-05-28 01:57:40 -070074 this.srcIp = srcIp;
75 this.dstIp = dstIp;
Ray Milkey269ffb92014-04-03 14:43:30 -070076 }
Yuta HIGUCHIe80664e2014-02-20 22:41:57 -080077
Brian O'Connora84723c2014-06-13 00:26:49 -070078 /**
79 * Matches are equal if all object variables are equal.
80 *
81 * @return true if equal, false otherwise
82 */
Ray Milkey269ffb92014-04-03 14:43:30 -070083 @Override
84 public boolean equals(Object obj) {
85 if (obj instanceof Match) {
86 Match other = (Match) obj;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070087 // TODO: we might consider excluding sw from this comparison
Komal Shah399a2922014-05-28 01:57:40 -070088 if (this.sw != other.sw) {
89 return false;
90 }
91 if (!Objects.equals(srcMac, other.srcMac)) {
92 return false;
93 }
94 if (!Objects.equals(dstMac, other.dstMac)) {
95 return false;
96 }
97 if (srcIp != other.srcIp) {
98 return false;
99 }
100
101 if (dstIp != other.dstIp) {
102 return false;
103 }
104 if (this.srcPort != other.srcPort) {
105 return false;
106 }
107 return true;
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 } else {
109 return false;
110 }
111 }
Yuta HIGUCHIe80664e2014-02-20 22:41:57 -0800112
Brian O'Connora84723c2014-06-13 00:26:49 -0700113 /**
114 * Converts the Match into a legacy FlowEntryMatch object.
115 *
116 * @return an equivalent FlowEntryMatch object
117 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700118 public FlowEntryMatch getFlowEntryMatch() {
119 FlowEntryMatch match = new FlowEntryMatch();
Komal Shah399a2922014-05-28 01:57:40 -0700120 if (srcMac != null) {
121 match.enableSrcMac(srcMac);
122 }
123 if (dstMac != null) {
124 match.enableDstMac(dstMac);
125 }
126 if (srcIp != ShortestPathIntent.EMPTYIPADDRESS) {
127 match.enableEthernetFrameType(Ethernet.TYPE_IPV4);
128 IPv4 srcIPv4 = new IPv4(srcIp);
129 IPv4Net srcIP = new IPv4Net(srcIPv4, IPV4_PREFIX_LEN);
130 match.enableSrcIPv4Net(srcIP);
131 }
132 if (dstIp != ShortestPathIntent.EMPTYIPADDRESS) {
133 match.enableEthernetFrameType(Ethernet.TYPE_IPV4);
134 IPv4 dstIPv4 = new IPv4(dstIp);
135 IPv4Net dstIP = new IPv4Net(dstIPv4, IPV4_PREFIX_LEN);
136 match.enableDstIPv4Net(dstIP);
137 }
Yuta HIGUCHIfb564502014-06-16 21:29:00 -0700138 match.enableInPort(new PortNumber((short) srcPort));
Ray Milkey269ffb92014-04-03 14:43:30 -0700139 return match;
140 }
141
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700142 public Builder getOFMatchBuilder(OFFactory factory) {
143 Builder matchBuilder = factory.buildMatch();
144
145 if (srcMac != null) {
146 matchBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(srcMac.toLong()));
147 }
148 if (dstMac != null) {
149 matchBuilder.setExact(MatchField.ETH_DST, MacAddress.of(dstMac.toLong()));
150 }
151 if (srcIp != ShortestPathIntent.EMPTYIPADDRESS) {
152 matchBuilder.setExact(MatchField.ETH_TYPE, EthType.IPv4)
153 .setMasked(MatchField.IPV4_SRC,
154 IPv4AddressWithMask.of(srcIp, IPV4_PREFIX_LEN));
155 }
156 if (dstIp != ShortestPathIntent.EMPTYIPADDRESS) {
157 matchBuilder.setExact(MatchField.ETH_TYPE, EthType.IPv4)
158 .setMasked(MatchField.IPV4_DST,
159 IPv4AddressWithMask.of(dstIp, IPV4_PREFIX_LEN));
160 }
161 matchBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) srcPort));
162
163 return matchBuilder;
164 }
165
Brian O'Connora84723c2014-06-13 00:26:49 -0700166 /**
167 * Returns a String representation of this Match.
168 *
169 * @return the match as a String
170 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700171 @Override
172 public String toString() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700173 return "Sw:" + sw + " (" + srcPort + ","
174 + srcMac + "," + dstMac + ","
175 + srcIp + "," + dstIp + ")";
Ray Milkey269ffb92014-04-03 14:43:30 -0700176 }
177
Brian O'Connora84723c2014-06-13 00:26:49 -0700178 /**
179 * Generates hash using Objects.hash() to hash all object variables.
180 *
181 * @return hashcode
182 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700183 @Override
184 public int hashCode() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700185 // TODO: we might consider excluding sw from the hash function
186 // to make it easier to compare matches between switches
187 return Objects.hash(sw, srcPort, srcMac, dstMac, srcIp, dstIp);
Ray Milkey269ffb92014-04-03 14:43:30 -0700188 }
Brian O'Connor7f8e3012014-02-15 23:59:29 -0800189}