Showing
16 changed files
with
206 additions
and
319 deletions
... | @@ -36,7 +36,6 @@ import org.onlab.onos.net.host.InterfaceIpAddress; | ... | @@ -36,7 +36,6 @@ import org.onlab.onos.net.host.InterfaceIpAddress; |
36 | import org.onlab.onos.net.host.PortAddresses; | 36 | import org.onlab.onos.net.host.PortAddresses; |
37 | import org.onlab.packet.IpAddress; | 37 | import org.onlab.packet.IpAddress; |
38 | import org.onlab.packet.IpPrefix; | 38 | import org.onlab.packet.IpPrefix; |
39 | -import org.onlab.packet.Ip4Prefix; | ||
40 | import org.onlab.packet.MacAddress; | 39 | import org.onlab.packet.MacAddress; |
41 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
42 | 41 | ||
... | @@ -81,12 +80,8 @@ public class NetworkConfigReader { | ... | @@ -81,12 +80,8 @@ public class NetworkConfigReader { |
81 | if (splits.length != 2) { | 80 | if (splits.length != 2) { |
82 | throw new IllegalArgumentException("Invalid IP address and prefix length format"); | 81 | throw new IllegalArgumentException("Invalid IP address and prefix length format"); |
83 | } | 82 | } |
84 | - // | 83 | + // NOTE: IpPrefix will mask-out the bits after the prefix length. |
85 | - // TODO: For now we need Ip4Prefix to mask-out the | 84 | + IpPrefix subnet = IpPrefix.valueOf(strIp); |
86 | - // subnet address. | ||
87 | - // | ||
88 | - Ip4Prefix subnet4 = new Ip4Prefix(strIp); | ||
89 | - IpPrefix subnet = IpPrefix.valueOf(subnet4.toString()); | ||
90 | IpAddress addr = IpAddress.valueOf(splits[0]); | 85 | IpAddress addr = IpAddress.valueOf(splits[0]); |
91 | InterfaceIpAddress ia = | 86 | InterfaceIpAddress ia = |
92 | new InterfaceIpAddress(addr, subnet); | 87 | new InterfaceIpAddress(addr, subnet); | ... | ... |
... | @@ -73,7 +73,7 @@ public class RouteEntry { | ... | @@ -73,7 +73,7 @@ public class RouteEntry { |
73 | } | 73 | } |
74 | 74 | ||
75 | StringBuilder result = new StringBuilder(ip4Prefix.prefixLength()); | 75 | StringBuilder result = new StringBuilder(ip4Prefix.prefixLength()); |
76 | - long value = ip4Prefix.toInt(); | 76 | + long value = ip4Prefix.address().toInt() & 0xffffffffL; |
77 | for (int i = 0; i < ip4Prefix.prefixLength(); i++) { | 77 | for (int i = 0; i < ip4Prefix.prefixLength(); i++) { |
78 | long mask = 1 << (IpPrefix.MAX_INET_MASK_LENGTH - 1 - i); | 78 | long mask = 1 << (IpPrefix.MAX_INET_MASK_LENGTH - 1 - i); |
79 | result.append(((value & mask) == 0) ? "0" : "1"); | 79 | result.append(((value & mask) == 0) ? "0" : "1"); | ... | ... |
... | @@ -188,7 +188,7 @@ class TestBgpPeerChannelHandler extends SimpleChannelHandler { | ... | @@ -188,7 +188,7 @@ class TestBgpPeerChannelHandler extends SimpleChannelHandler { |
188 | int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up | 188 | int prefixBytelen = (prefixBitlen + 7) / 8; // Round-up |
189 | message.writeByte(prefixBitlen); | 189 | message.writeByte(prefixBitlen); |
190 | 190 | ||
191 | - IpAddress address = prefix.toIpAddress(); | 191 | + IpAddress address = prefix.address(); |
192 | long value = address.toInt() & 0xffffffffL; | 192 | long value = address.toInt() & 0xffffffffL; |
193 | for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) { | 193 | for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) { |
194 | if (prefixBytelen-- == 0) { | 194 | if (prefixBytelen-- == 0) { | ... | ... |
... | @@ -22,7 +22,7 @@ import java.util.Objects; | ... | @@ -22,7 +22,7 @@ import java.util.Objects; |
22 | import org.onlab.onos.net.PortNumber; | 22 | import org.onlab.onos.net.PortNumber; |
23 | import org.onlab.onos.net.flow.instructions.Instruction; | 23 | import org.onlab.onos.net.flow.instructions.Instruction; |
24 | import org.onlab.onos.net.flow.instructions.Instructions; | 24 | import org.onlab.onos.net.flow.instructions.Instructions; |
25 | -import org.onlab.packet.IpPrefix; | 25 | +import org.onlab.packet.IpAddress; |
26 | import org.onlab.packet.MacAddress; | 26 | import org.onlab.packet.MacAddress; |
27 | import org.onlab.packet.VlanId; | 27 | import org.onlab.packet.VlanId; |
28 | 28 | ||
... | @@ -181,12 +181,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -181,12 +181,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { |
181 | } | 181 | } |
182 | 182 | ||
183 | @Override | 183 | @Override |
184 | - public Builder setIpSrc(IpPrefix addr) { | 184 | + public Builder setIpSrc(IpAddress addr) { |
185 | return add(Instructions.modL3Src(addr)); | 185 | return add(Instructions.modL3Src(addr)); |
186 | } | 186 | } |
187 | 187 | ||
188 | @Override | 188 | @Override |
189 | - public Builder setIpDst(IpPrefix addr) { | 189 | + public Builder setIpDst(IpAddress addr) { |
190 | return add(Instructions.modL3Dst(addr)); | 190 | return add(Instructions.modL3Dst(addr)); |
191 | } | 191 | } |
192 | 192 | ... | ... |
... | @@ -19,7 +19,7 @@ import java.util.List; | ... | @@ -19,7 +19,7 @@ import java.util.List; |
19 | 19 | ||
20 | import org.onlab.onos.net.PortNumber; | 20 | import org.onlab.onos.net.PortNumber; |
21 | import org.onlab.onos.net.flow.instructions.Instruction; | 21 | import org.onlab.onos.net.flow.instructions.Instruction; |
22 | -import org.onlab.packet.IpPrefix; | 22 | +import org.onlab.packet.IpAddress; |
23 | import org.onlab.packet.MacAddress; | 23 | import org.onlab.packet.MacAddress; |
24 | import org.onlab.packet.VlanId; | 24 | import org.onlab.packet.VlanId; |
25 | 25 | ||
... | @@ -92,14 +92,14 @@ public interface TrafficTreatment { | ... | @@ -92,14 +92,14 @@ public interface TrafficTreatment { |
92 | * @param addr an ip | 92 | * @param addr an ip |
93 | * @return a treatment builder | 93 | * @return a treatment builder |
94 | */ | 94 | */ |
95 | - public Builder setIpSrc(IpPrefix addr); | 95 | + public Builder setIpSrc(IpAddress addr); |
96 | 96 | ||
97 | /** | 97 | /** |
98 | * Sets the dst l3 address. | 98 | * Sets the dst l3 address. |
99 | * @param addr an ip | 99 | * @param addr an ip |
100 | * @return a treatment builder | 100 | * @return a treatment builder |
101 | */ | 101 | */ |
102 | - public Builder setIpDst(IpPrefix addr); | 102 | + public Builder setIpDst(IpAddress addr); |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Sets the optical channel ID or lambda. | 105 | * Sets the optical channel ID or lambda. | ... | ... |
... | @@ -27,7 +27,7 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType; | ... | @@ -27,7 +27,7 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType; |
27 | import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; | 27 | import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; |
28 | import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType; | 28 | import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType; |
29 | import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; | 29 | import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; |
30 | -import org.onlab.packet.IpPrefix; | 30 | +import org.onlab.packet.IpAddress; |
31 | import org.onlab.packet.MacAddress; | 31 | import org.onlab.packet.MacAddress; |
32 | import org.onlab.packet.VlanId; | 32 | import org.onlab.packet.VlanId; |
33 | 33 | ||
... | @@ -115,7 +115,7 @@ public final class Instructions { | ... | @@ -115,7 +115,7 @@ public final class Instructions { |
115 | * @param addr the ip address to modify to. | 115 | * @param addr the ip address to modify to. |
116 | * @return a L3 modification | 116 | * @return a L3 modification |
117 | */ | 117 | */ |
118 | - public static L3ModificationInstruction modL3Src(IpPrefix addr) { | 118 | + public static L3ModificationInstruction modL3Src(IpAddress addr) { |
119 | checkNotNull(addr, "Src l3 address cannot be null"); | 119 | checkNotNull(addr, "Src l3 address cannot be null"); |
120 | return new ModIPInstruction(L3SubType.IP_SRC, addr); | 120 | return new ModIPInstruction(L3SubType.IP_SRC, addr); |
121 | } | 121 | } |
... | @@ -125,7 +125,7 @@ public final class Instructions { | ... | @@ -125,7 +125,7 @@ public final class Instructions { |
125 | * @param addr the ip address to modify to. | 125 | * @param addr the ip address to modify to. |
126 | * @return a L3 modification | 126 | * @return a L3 modification |
127 | */ | 127 | */ |
128 | - public static L3ModificationInstruction modL3Dst(IpPrefix addr) { | 128 | + public static L3ModificationInstruction modL3Dst(IpAddress addr) { |
129 | checkNotNull(addr, "Dst l3 address cannot be null"); | 129 | checkNotNull(addr, "Dst l3 address cannot be null"); |
130 | return new ModIPInstruction(L3SubType.IP_DST, addr); | 130 | return new ModIPInstruction(L3SubType.IP_DST, addr); |
131 | } | 131 | } | ... | ... |
... | @@ -19,7 +19,7 @@ import static com.google.common.base.MoreObjects.toStringHelper; | ... | @@ -19,7 +19,7 @@ import static com.google.common.base.MoreObjects.toStringHelper; |
19 | 19 | ||
20 | import java.util.Objects; | 20 | import java.util.Objects; |
21 | 21 | ||
22 | -import org.onlab.packet.IpPrefix; | 22 | +import org.onlab.packet.IpAddress; |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * Abstraction of a single traffic treatment step. | 25 | * Abstraction of a single traffic treatment step. |
... | @@ -60,9 +60,9 @@ public abstract class L3ModificationInstruction implements Instruction { | ... | @@ -60,9 +60,9 @@ public abstract class L3ModificationInstruction implements Instruction { |
60 | public static final class ModIPInstruction extends L3ModificationInstruction { | 60 | public static final class ModIPInstruction extends L3ModificationInstruction { |
61 | 61 | ||
62 | private final L3SubType subtype; | 62 | private final L3SubType subtype; |
63 | - private final IpPrefix ip; | 63 | + private final IpAddress ip; |
64 | 64 | ||
65 | - public ModIPInstruction(L3SubType subType, IpPrefix addr) { | 65 | + public ModIPInstruction(L3SubType subType, IpAddress addr) { |
66 | 66 | ||
67 | this.subtype = subType; | 67 | this.subtype = subType; |
68 | this.ip = addr; | 68 | this.ip = addr; |
... | @@ -73,7 +73,7 @@ public abstract class L3ModificationInstruction implements Instruction { | ... | @@ -73,7 +73,7 @@ public abstract class L3ModificationInstruction implements Instruction { |
73 | return this.subtype; | 73 | return this.subtype; |
74 | } | 74 | } |
75 | 75 | ||
76 | - public IpPrefix ip() { | 76 | + public IpAddress ip() { |
77 | return this.ip; | 77 | return this.ip; |
78 | } | 78 | } |
79 | 79 | ... | ... |
... | @@ -254,8 +254,7 @@ public class DeviceManager | ... | @@ -254,8 +254,7 @@ public class DeviceManager |
254 | // } | 254 | // } |
255 | return; | 255 | return; |
256 | } | 256 | } |
257 | - MastershipTerm term = mastershipService.requestTermService() | 257 | + MastershipTerm term = termService.getMastershipTerm(deviceId); |
258 | - .getMastershipTerm(deviceId); | ||
259 | 258 | ||
260 | final NodeId myNodeId = clusterService.getLocalNode().id(); | 259 | final NodeId myNodeId = clusterService.getLocalNode().id(); |
261 | if (!myNodeId.equals(term.master())) { | 260 | if (!myNodeId.equals(term.master())) { | ... | ... |
... | @@ -30,6 +30,9 @@ import org.onlab.onos.net.intent.IntentStore; | ... | @@ -30,6 +30,9 @@ import org.onlab.onos.net.intent.IntentStore; |
30 | import org.onlab.onos.net.intent.IntentStoreDelegate; | 30 | import org.onlab.onos.net.intent.IntentStoreDelegate; |
31 | import org.onlab.onos.store.hz.AbstractHazelcastStore; | 31 | import org.onlab.onos.store.hz.AbstractHazelcastStore; |
32 | import org.onlab.onos.store.hz.SMap; | 32 | import org.onlab.onos.store.hz.SMap; |
33 | +import org.onlab.onos.store.serializers.KryoNamespaces; | ||
34 | +import org.onlab.onos.store.serializers.KryoSerializer; | ||
35 | +import org.onlab.util.KryoNamespace; | ||
33 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
34 | 37 | ||
35 | import java.util.List; | 38 | import java.util.List; |
... | @@ -61,9 +64,21 @@ public class DistributedIntentStore | ... | @@ -61,9 +64,21 @@ public class DistributedIntentStore |
61 | @Activate | 64 | @Activate |
62 | public void activate() { | 65 | public void activate() { |
63 | // FIXME: We need a way to add serializer for intents which has been plugged-in. | 66 | // FIXME: We need a way to add serializer for intents which has been plugged-in. |
64 | - // TODO: As a short term workaround, relax Kryo config to | 67 | + // As a short term workaround, relax Kryo config to |
65 | - // registrationRequired=false? | 68 | + // registrationRequired=false |
66 | super.activate(); | 69 | super.activate(); |
70 | + super.serializer = new KryoSerializer() { | ||
71 | + | ||
72 | + @Override | ||
73 | + protected void setupKryoPool() { | ||
74 | + serializerPool = KryoNamespace.newBuilder() | ||
75 | + .setRegistrationRequired(false) | ||
76 | + .register(KryoNamespaces.API) | ||
77 | + .build() | ||
78 | + .populate(1); | ||
79 | + } | ||
80 | + | ||
81 | + }; | ||
67 | 82 | ||
68 | // TODO: enable near cache, allow read from backup for this IMap | 83 | // TODO: enable near cache, allow read from backup for this IMap |
69 | IMap<byte[], byte[]> rawIntents = super.theInstance.getMap("intents"); | 84 | IMap<byte[], byte[]> rawIntents = super.theInstance.getMap("intents"); | ... | ... |
... | @@ -38,7 +38,7 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> { | ... | @@ -38,7 +38,7 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> { |
38 | @Override | 38 | @Override |
39 | public void write(Kryo kryo, Output output, | 39 | public void write(Kryo kryo, Output output, |
40 | IpPrefix object) { | 40 | IpPrefix object) { |
41 | - byte[] octs = object.toOctets(); | 41 | + byte[] octs = object.address().toOctets(); |
42 | output.writeInt(octs.length); | 42 | output.writeInt(octs.length); |
43 | output.writeBytes(octs); | 43 | output.writeBytes(octs); |
44 | output.writeInt(object.prefixLength()); | 44 | output.writeInt(object.prefixLength()); | ... | ... |
... | @@ -31,6 +31,7 @@ import org.onlab.onos.net.flow.FlowRule; | ... | @@ -31,6 +31,7 @@ import org.onlab.onos.net.flow.FlowRule; |
31 | import org.onlab.onos.net.flow.TrafficSelector; | 31 | import org.onlab.onos.net.flow.TrafficSelector; |
32 | import org.onlab.onos.net.flow.TrafficTreatment; | 32 | import org.onlab.onos.net.flow.TrafficTreatment; |
33 | import org.onlab.onos.openflow.controller.Dpid; | 33 | import org.onlab.onos.openflow.controller.Dpid; |
34 | +import org.onlab.packet.IpAddress; | ||
34 | import org.onlab.packet.IpPrefix; | 35 | import org.onlab.packet.IpPrefix; |
35 | import org.onlab.packet.MacAddress; | 36 | import org.onlab.packet.MacAddress; |
36 | import org.onlab.packet.VlanId; | 37 | import org.onlab.packet.VlanId; |
... | @@ -167,24 +168,12 @@ public class FlowEntryBuilder { | ... | @@ -167,24 +168,12 @@ public class FlowEntryBuilder { |
167 | case SET_NW_DST: | 168 | case SET_NW_DST: |
168 | OFActionSetNwDst nwdst = (OFActionSetNwDst) act; | 169 | OFActionSetNwDst nwdst = (OFActionSetNwDst) act; |
169 | IPv4Address di = nwdst.getNwAddr(); | 170 | IPv4Address di = nwdst.getNwAddr(); |
170 | - if (di.isCidrMask()) { | 171 | + builder.setIpDst(IpAddress.valueOf(di.getInt())); |
171 | - builder.setIpDst(IpPrefix.valueOf(di.getInt(), | ||
172 | - di.asCidrMaskLength())); | ||
173 | - } else { | ||
174 | - builder.setIpDst(IpPrefix.valueOf(di.getInt(), | ||
175 | - IpPrefix.MAX_INET_MASK_LENGTH)); | ||
176 | - } | ||
177 | break; | 172 | break; |
178 | case SET_NW_SRC: | 173 | case SET_NW_SRC: |
179 | OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act; | 174 | OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act; |
180 | IPv4Address si = nwsrc.getNwAddr(); | 175 | IPv4Address si = nwsrc.getNwAddr(); |
181 | - if (si.isCidrMask()) { | 176 | + builder.setIpSrc(IpAddress.valueOf(si.getInt())); |
182 | - builder.setIpSrc(IpPrefix.valueOf(si.getInt(), | ||
183 | - si.asCidrMaskLength())); | ||
184 | - } else { | ||
185 | - builder.setIpSrc(IpPrefix.valueOf(si.getInt(), | ||
186 | - IpPrefix.MAX_INET_MASK_LENGTH)); | ||
187 | - } | ||
188 | break; | 177 | break; |
189 | case EXPERIMENTER: | 178 | case EXPERIMENTER: |
190 | OFActionExperimenter exp = (OFActionExperimenter) act; | 179 | OFActionExperimenter exp = (OFActionExperimenter) act; | ... | ... |
... | @@ -29,6 +29,8 @@ import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion; | ... | @@ -29,6 +29,8 @@ import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion; |
29 | import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion; | 29 | import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion; |
30 | import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion; | 30 | import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion; |
31 | import org.onlab.onos.net.flow.criteria.Criterion; | 31 | import org.onlab.onos.net.flow.criteria.Criterion; |
32 | +import org.onlab.packet.IpAddress; | ||
33 | +import org.onlab.packet.IpPrefix; | ||
32 | import org.projectfloodlight.openflow.protocol.OFFactory; | 34 | import org.projectfloodlight.openflow.protocol.OFFactory; |
33 | import org.projectfloodlight.openflow.protocol.OFFlowAdd; | 35 | import org.projectfloodlight.openflow.protocol.OFFlowAdd; |
34 | import org.projectfloodlight.openflow.protocol.OFFlowDelete; | 36 | import org.projectfloodlight.openflow.protocol.OFFlowDelete; |
... | @@ -141,22 +143,30 @@ public abstract class FlowModBuilder { | ... | @@ -141,22 +143,30 @@ public abstract class FlowModBuilder { |
141 | break; | 143 | break; |
142 | case IPV4_DST: | 144 | case IPV4_DST: |
143 | ip = (IPCriterion) c; | 145 | ip = (IPCriterion) c; |
144 | - if (ip.ip().isMasked()) { | 146 | + if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) { |
145 | - Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()), | 147 | + IpAddress maskAddr = |
146 | - IPv4Address.of(ip.ip().netmask().toInt())); | 148 | + IpAddress.makeMaskPrefix(ip.ip().prefixLength()); |
149 | + Masked<IPv4Address> maskedIp = | ||
150 | + Masked.of(IPv4Address.of(ip.ip().address().toInt()), | ||
151 | + IPv4Address.of(maskAddr.toInt())); | ||
147 | mBuilder.setMasked(MatchField.IPV4_DST, maskedIp); | 152 | mBuilder.setMasked(MatchField.IPV4_DST, maskedIp); |
148 | } else { | 153 | } else { |
149 | - mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt())); | 154 | + mBuilder.setExact(MatchField.IPV4_DST, |
155 | + IPv4Address.of(ip.ip().address().toInt())); | ||
150 | } | 156 | } |
151 | break; | 157 | break; |
152 | case IPV4_SRC: | 158 | case IPV4_SRC: |
153 | ip = (IPCriterion) c; | 159 | ip = (IPCriterion) c; |
154 | - if (ip.ip().isMasked()) { | 160 | + if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) { |
155 | - Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()), | 161 | + IpAddress maskAddr = |
156 | - IPv4Address.of(ip.ip().netmask().toInt())); | 162 | + IpAddress.makeMaskPrefix(ip.ip().prefixLength()); |
163 | + Masked<IPv4Address> maskedIp = | ||
164 | + Masked.of(IPv4Address.of(ip.ip().address().toInt()), | ||
165 | + IPv4Address.of(maskAddr.toInt())); | ||
157 | mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp); | 166 | mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp); |
158 | } else { | 167 | } else { |
159 | - mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt())); | 168 | + mBuilder.setExact(MatchField.IPV4_SRC, |
169 | + IPv4Address.of(ip.ip().address().toInt())); | ||
160 | } | 170 | } |
161 | break; | 171 | break; |
162 | case IP_PROTO: | 172 | case IP_PROTO: | ... | ... |
... | @@ -21,7 +21,8 @@ import java.util.Objects; | ... | @@ -21,7 +21,8 @@ import java.util.Objects; |
21 | import static com.google.common.base.Preconditions.checkNotNull; | 21 | import static com.google.common.base.Preconditions.checkNotNull; |
22 | 22 | ||
23 | /** | 23 | /** |
24 | - * A class representing an IPv4 address. | 24 | + * A class representing an IP address. |
25 | + * TODO: Add support for IPv6 as well. | ||
25 | */ | 26 | */ |
26 | public final class IpAddress implements Comparable<IpAddress> { | 27 | public final class IpAddress implements Comparable<IpAddress> { |
27 | // IP Versions | 28 | // IP Versions |
... | @@ -44,8 +45,6 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -44,8 +45,6 @@ public final class IpAddress implements Comparable<IpAddress> { |
44 | * @param value the IP address value | 45 | * @param value the IP address value |
45 | */ | 46 | */ |
46 | private IpAddress(Version version, byte[] value) { | 47 | private IpAddress(Version version, byte[] value) { |
47 | - checkNotNull(value); | ||
48 | - | ||
49 | this.version = version; | 48 | this.version = version; |
50 | this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH); | 49 | this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH); |
51 | } | 50 | } |
... | @@ -53,7 +52,7 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -53,7 +52,7 @@ public final class IpAddress implements Comparable<IpAddress> { |
53 | /** | 52 | /** |
54 | * Converts an integer into an IPv4 address. | 53 | * Converts an integer into an IPv4 address. |
55 | * | 54 | * |
56 | - * @param value an integer representing an IPv4 value | 55 | + * @param value an integer representing an IPv4 address value |
57 | * @return an IP address | 56 | * @return an IP address |
58 | */ | 57 | */ |
59 | public static IpAddress valueOf(int value) { | 58 | public static IpAddress valueOf(int value) { |
... | @@ -70,6 +69,7 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -70,6 +69,7 @@ public final class IpAddress implements Comparable<IpAddress> { |
70 | * @return an IP address | 69 | * @return an IP address |
71 | */ | 70 | */ |
72 | public static IpAddress valueOf(byte[] value) { | 71 | public static IpAddress valueOf(byte[] value) { |
72 | + checkNotNull(value); | ||
73 | return new IpAddress(Version.INET, value); | 73 | return new IpAddress(Version.INET, value); |
74 | } | 74 | } |
75 | 75 | ||
... | @@ -106,13 +106,13 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -106,13 +106,13 @@ public final class IpAddress implements Comparable<IpAddress> { |
106 | /** | 106 | /** |
107 | * Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. | 107 | * Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. |
108 | * | 108 | * |
109 | - * @param address a IP address in string form, e.g. "10.0.0.1". | 109 | + * @param address an IP address in string form, e.g. "10.0.0.1" |
110 | * @return an IP address | 110 | * @return an IP address |
111 | */ | 111 | */ |
112 | public static IpAddress valueOf(String address) { | 112 | public static IpAddress valueOf(String address) { |
113 | final String[] net = address.split("\\."); | 113 | final String[] net = address.split("\\."); |
114 | if (net.length != INET_BYTE_LENGTH) { | 114 | if (net.length != INET_BYTE_LENGTH) { |
115 | - String msg = "Malformed IPv4 address string; " + | 115 | + String msg = "Malformed IPv4 address string: " + address + "." + |
116 | "Address must have four decimal values separated by dots (.)"; | 116 | "Address must have four decimal values separated by dots (.)"; |
117 | throw new IllegalArgumentException(msg); | 117 | throw new IllegalArgumentException(msg); |
118 | } | 118 | } |
... | @@ -154,20 +154,21 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -154,20 +154,21 @@ public final class IpAddress implements Comparable<IpAddress> { |
154 | /** | 154 | /** |
155 | * Creates an IP network mask prefix. | 155 | * Creates an IP network mask prefix. |
156 | * | 156 | * |
157 | - * @param prefixLen the length of the mask prefix. Must be in the interval | 157 | + * @param prefixLength the length of the mask prefix. Must be in the |
158 | - * [0, 32] for IPv4 | 158 | + * interval [0, 32] for IPv4 |
159 | * @return a new IP address that contains a mask prefix of the | 159 | * @return a new IP address that contains a mask prefix of the |
160 | * specified length | 160 | * specified length |
161 | */ | 161 | */ |
162 | - public static IpAddress makeMaskPrefix(int prefixLen) { | 162 | + public static IpAddress makeMaskPrefix(int prefixLength) { |
163 | // Verify the prefix length | 163 | // Verify the prefix length |
164 | - if ((prefixLen < 0) || (prefixLen > INET_BIT_LENGTH)) { | 164 | + if ((prefixLength < 0) || (prefixLength > INET_BIT_LENGTH)) { |
165 | - final String msg = "Invalid IPv4 prefix length: " + prefixLen + | 165 | + final String msg = "Invalid IPv4 prefix length: " + prefixLength + |
166 | ". Must be in the interval [0, 32]."; | 166 | ". Must be in the interval [0, 32]."; |
167 | throw new IllegalArgumentException(msg); | 167 | throw new IllegalArgumentException(msg); |
168 | } | 168 | } |
169 | 169 | ||
170 | - long v = (0xffffffffL << (INET_BIT_LENGTH - prefixLen)) & 0xffffffffL; | 170 | + long v = |
171 | + (0xffffffffL << (INET_BIT_LENGTH - prefixLength)) & 0xffffffffL; | ||
171 | return IpAddress.valueOf((int) v); | 172 | return IpAddress.valueOf((int) v); |
172 | } | 173 | } |
173 | 174 | ||
... | @@ -176,14 +177,14 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -176,14 +177,14 @@ public final class IpAddress implements Comparable<IpAddress> { |
176 | * mask length. | 177 | * mask length. |
177 | * | 178 | * |
178 | * @param addr the address to mask | 179 | * @param addr the address to mask |
179 | - * @param prefixLen the length of the mask prefix. Must be in the interval | 180 | + * @param prefixLength the length of the mask prefix. Must be in the |
180 | - * [0, 32] for IPv4 | 181 | + * interval [0, 32] for IPv4 |
181 | * @return a new IP address that is masked with a mask prefix of the | 182 | * @return a new IP address that is masked with a mask prefix of the |
182 | * specified length | 183 | * specified length |
183 | */ | 184 | */ |
184 | public static IpAddress makeMaskedAddress(final IpAddress addr, | 185 | public static IpAddress makeMaskedAddress(final IpAddress addr, |
185 | - int prefixLen) { | 186 | + int prefixLength) { |
186 | - IpAddress mask = IpAddress.makeMaskPrefix(prefixLen); | 187 | + IpAddress mask = IpAddress.makeMaskPrefix(prefixLength); |
187 | byte[] net = new byte[INET_BYTE_LENGTH]; | 188 | byte[] net = new byte[INET_BYTE_LENGTH]; |
188 | 189 | ||
189 | // Mask each byte | 190 | // Mask each byte |
... | @@ -207,7 +208,7 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -207,7 +208,7 @@ public final class IpAddress implements Comparable<IpAddress> { |
207 | 208 | ||
208 | @Override | 209 | @Override |
209 | public boolean equals(Object obj) { | 210 | public boolean equals(Object obj) { |
210 | - if (obj == this) { | 211 | + if (this == obj) { |
211 | return true; | 212 | return true; |
212 | } | 213 | } |
213 | if ((obj == null) || (getClass() != obj.getClass())) { | 214 | if ((obj == null) || (getClass() != obj.getClass())) { |
... | @@ -221,7 +222,7 @@ public final class IpAddress implements Comparable<IpAddress> { | ... | @@ -221,7 +222,7 @@ public final class IpAddress implements Comparable<IpAddress> { |
221 | @Override | 222 | @Override |
222 | /* | 223 | /* |
223 | * (non-Javadoc) | 224 | * (non-Javadoc) |
224 | - * format is "x.x.x.x" for IPv4 addresses. | 225 | + * The format is "x.x.x.x" for IPv4 addresses. |
225 | * | 226 | * |
226 | * @see java.lang.Object#toString() | 227 | * @see java.lang.Object#toString() |
227 | */ | 228 | */ | ... | ... |
... | @@ -15,285 +15,174 @@ | ... | @@ -15,285 +15,174 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.packet; | 16 | package org.onlab.packet; |
17 | 17 | ||
18 | -import java.util.Arrays; | 18 | +import java.util.Objects; |
19 | 19 | ||
20 | /** | 20 | /** |
21 | - * A class representing an IPv4 prefix. | 21 | + * A class representing an IP prefix. |
22 | + * TODO: Add support for IPv6 as well. | ||
22 | * <p/> | 23 | * <p/> |
23 | * A prefix consists of an IP address and a subnet mask. | 24 | * A prefix consists of an IP address and a subnet mask. |
25 | + * NOTE: The stored IP address in the result IP prefix is masked to | ||
26 | + * contain zeroes in all bits after the prefix length. | ||
24 | */ | 27 | */ |
25 | public final class IpPrefix { | 28 | public final class IpPrefix { |
26 | - | ||
27 | - // TODO a comparator for netmasks? E.g. for sorting by prefix match order. | ||
28 | - | ||
29 | - // IP Versions: IPv4 and IPv6 | ||
30 | - public enum Version { INET, INET6 }; | ||
31 | - | ||
32 | // Maximum network mask length | 29 | // Maximum network mask length |
33 | public static final int MAX_INET_MASK_LENGTH = IpAddress.INET_BIT_LENGTH; | 30 | public static final int MAX_INET_MASK_LENGTH = IpAddress.INET_BIT_LENGTH; |
34 | public static final int MAX_INET6_MASK_LENGTH = IpAddress.INET6_BIT_LENGTH; | 31 | public static final int MAX_INET6_MASK_LENGTH = IpAddress.INET6_BIT_LENGTH; |
35 | 32 | ||
36 | - //no mask (no network), e.g. a simple address | 33 | + private final IpAddress address; |
37 | - private static final int DEFAULT_MASK = 0; | 34 | + private final short prefixLength; |
38 | 35 | ||
39 | /** | 36 | /** |
40 | - * Default value indicating an unspecified address. | 37 | + * Constructor for given IP address, and a prefix length. |
38 | + * | ||
39 | + * @param address the IP address | ||
40 | + * @param prefixLength the prefix length | ||
41 | */ | 41 | */ |
42 | - private static final byte[] ANY = new byte[] {0, 0, 0, 0}; | 42 | + private IpPrefix(IpAddress address, int prefixLength) { |
43 | - | 43 | + checkPrefixLength(prefixLength); |
44 | - private final Version version; | 44 | + this.address = IpAddress.makeMaskedAddress(address, prefixLength); |
45 | - private final byte[] octets; | 45 | + this.prefixLength = (short) prefixLength; |
46 | - private final int netmask; | 46 | + } |
47 | 47 | ||
48 | /** | 48 | /** |
49 | - * Constructor for given IP address version, prefix address octets, | 49 | + * Checks whether the prefix length is valid. |
50 | - * and network mask length. | ||
51 | * | 50 | * |
52 | - * @param ver the IP address version | 51 | + * @param prefixLength the prefix length value to check |
53 | - * @param octets the IP prefix address octets | 52 | + * @throws IllegalArgumentException if the prefix length value is invalid |
54 | - * @param netmask the network mask length | ||
55 | */ | 53 | */ |
56 | - private IpPrefix(Version ver, byte[] octets, int netmask) { | 54 | + private static void checkPrefixLength(int prefixLength) { |
57 | - this.version = ver; | 55 | + if ((prefixLength < 0) || (prefixLength > MAX_INET_MASK_LENGTH)) { |
58 | - this.octets = Arrays.copyOf(octets, IpAddress.INET_BYTE_LENGTH); | 56 | + String msg = "Invalid prefix length " + prefixLength + ". " + |
59 | - this.netmask = netmask; | 57 | + "The value must be in the interval [0, " + |
58 | + MAX_INET_MASK_LENGTH + "]"; | ||
59 | + throw new IllegalArgumentException(msg); | ||
60 | + } | ||
60 | } | 61 | } |
61 | 62 | ||
62 | /** | 63 | /** |
63 | - * Converts a byte array into an IP address. | 64 | + * Converts an integer and a prefix length into an IPv4 prefix. |
64 | * | 65 | * |
65 | - * @param address a byte array | 66 | + * @param address an integer representing the IPv4 address |
66 | - * @param netmask the CIDR value subnet mask | 67 | + * @param prefixLength the prefix length |
67 | - * @return an IP address | 68 | + * @return an IP prefix |
68 | */ | 69 | */ |
69 | - public static IpPrefix valueOf(byte[] address, int netmask) { | 70 | + public static IpPrefix valueOf(int address, int prefixLength) { |
70 | - return new IpPrefix(Version.INET, address, netmask); | 71 | + return new IpPrefix(IpAddress.valueOf(address), prefixLength); |
71 | } | 72 | } |
72 | 73 | ||
73 | /** | 74 | /** |
74 | - * Helper to convert an integer into a byte array. | 75 | + * Converts a byte array and a prefix length into an IP prefix. |
75 | * | 76 | * |
76 | - * @param address the integer to convert | 77 | + * @param address the IP address value stored in network byte order |
77 | - * @return a byte array | 78 | + * @param prefixLength the prefix length |
79 | + * @return an IP prefix | ||
78 | */ | 80 | */ |
79 | - private static byte[] bytes(int address) { | 81 | + public static IpPrefix valueOf(byte[] address, int prefixLength) { |
80 | - byte[] bytes = new byte [IpAddress.INET_BYTE_LENGTH]; | 82 | + return new IpPrefix(IpAddress.valueOf(address), prefixLength); |
81 | - for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) { | ||
82 | - bytes[i] = (byte) ((address >> (IpAddress.INET_BYTE_LENGTH | ||
83 | - - (i + 1)) * 8) & 0xff); | ||
84 | - } | ||
85 | - | ||
86 | - return bytes; | ||
87 | } | 83 | } |
88 | 84 | ||
89 | /** | 85 | /** |
90 | - * Converts an integer into an IPv4 address. | 86 | + * Converts an IP address and a prefix length into IP prefix. |
91 | * | 87 | * |
92 | - * @param address an integer representing an IP value | 88 | + * @param address the IP address |
93 | - * @param netmask the CIDR value subnet mask | 89 | + * @param prefixLength the prefix length |
94 | - * @return an IP address | 90 | + * @return an IP prefix |
95 | */ | 91 | */ |
96 | - public static IpPrefix valueOf(int address, int netmask) { | 92 | + public static IpPrefix valueOf(IpAddress address, int prefixLength) { |
97 | - return new IpPrefix(Version.INET, bytes(address), netmask); | 93 | + return new IpPrefix(address, prefixLength); |
98 | } | 94 | } |
99 | 95 | ||
100 | /** | 96 | /** |
101 | - * Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. The | 97 | + * Converts a CIDR (slash) notation string (e.g., "10.1.0.0/16") into an |
102 | - * string can also be in CIDR (slash) notation. If the netmask is omitted, | 98 | + * IP prefix. |
103 | - * it will be set to DEFAULT_MASK (0). | ||
104 | * | 99 | * |
105 | - * @param address a IP address in string form, e.g. "10.0.0.1", "10.0.0.1/24" | 100 | + * @param value an IP prefix in string form, e.g. "10.1.0.0/16" |
106 | - * @return an IP address | 101 | + * @return an IP prefix |
107 | */ | 102 | */ |
108 | public static IpPrefix valueOf(String address) { | 103 | public static IpPrefix valueOf(String address) { |
109 | - | 104 | + final String[] parts = address.split("/"); |
110 | - final String[] parts = address.split("\\/"); | 105 | + if (parts.length != 2) { |
111 | - if (parts.length > 2) { | 106 | + String msg = "Malformed IP prefix string: " + address + "." + |
112 | - throw new IllegalArgumentException("Malformed IP address string; " | 107 | + "Address must take form \"x.x.x.x/y\""; |
113 | - + "Address must take form \"x.x.x.x\" or \"x.x.x.x/y\""); | 108 | + throw new IllegalArgumentException(msg); |
114 | - } | ||
115 | - | ||
116 | - int mask = DEFAULT_MASK; | ||
117 | - if (parts.length == 2) { | ||
118 | - mask = Integer.parseInt(parts[1]); | ||
119 | - if (mask > MAX_INET_MASK_LENGTH) { | ||
120 | - throw new IllegalArgumentException( | ||
121 | - "Value of subnet mask cannot exceed " | ||
122 | - + MAX_INET_MASK_LENGTH); | ||
123 | - } | ||
124 | } | 109 | } |
110 | + IpAddress ipAddress = IpAddress.valueOf(parts[0]); | ||
111 | + int prefixLength = Integer.parseInt(parts[1]); | ||
125 | 112 | ||
126 | - final String[] net = parts[0].split("\\."); | 113 | + return new IpPrefix(ipAddress, prefixLength); |
127 | - if (net.length != IpAddress.INET_BYTE_LENGTH) { | ||
128 | - throw new IllegalArgumentException("Malformed IP address string; " | ||
129 | - + "Address must have four decimal values separated by dots (.)"); | ||
130 | - } | ||
131 | - final byte[] bytes = new byte[IpAddress.INET_BYTE_LENGTH]; | ||
132 | - for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) { | ||
133 | - bytes[i] = (byte) Short.parseShort(net[i], 10); | ||
134 | - } | ||
135 | - return new IpPrefix(Version.INET, bytes, mask); | ||
136 | } | 114 | } |
137 | 115 | ||
138 | /** | 116 | /** |
139 | - * Returns the IP version of this address. | 117 | + * Returns the IP version of the prefix. |
140 | * | 118 | * |
141 | - * @return the version | 119 | + * @return the IP version of the prefix |
142 | */ | 120 | */ |
143 | - public Version version() { | 121 | + public IpAddress.Version version() { |
144 | - return this.version; | 122 | + return address.version(); |
145 | } | 123 | } |
146 | 124 | ||
147 | /** | 125 | /** |
148 | - * Returns the IP address as a byte array. | 126 | + * Returns the IP address value of the prefix. |
149 | * | 127 | * |
150 | - * @return a byte array | 128 | + * @return the IP address value of the prefix |
151 | */ | 129 | */ |
152 | - public byte[] toOctets() { | 130 | + public IpAddress address() { |
153 | - return Arrays.copyOf(this.octets, IpAddress.INET_BYTE_LENGTH); | 131 | + return address; |
154 | } | 132 | } |
155 | 133 | ||
156 | /** | 134 | /** |
157 | * Returns the IP address prefix length. | 135 | * Returns the IP address prefix length. |
158 | * | 136 | * |
159 | - * @return prefix length | 137 | + * @return the IP address prefix length |
160 | */ | 138 | */ |
161 | public int prefixLength() { | 139 | public int prefixLength() { |
162 | - return netmask; | 140 | + return prefixLength; |
163 | } | 141 | } |
164 | 142 | ||
165 | /** | 143 | /** |
166 | - * Returns the integral value of this IP address. | 144 | + * Determines whether a given IP prefix is contained within this prefix. |
167 | * | 145 | * |
168 | - * @return the IP address's value as an integer | 146 | + * @param other the IP prefix to test |
147 | + * @return true if the other IP prefix is contained in this prefix, | ||
148 | + * otherwise false | ||
169 | */ | 149 | */ |
170 | - public int toInt() { | 150 | + public boolean contains(IpPrefix other) { |
171 | - int val = 0; | 151 | + if (this.prefixLength > other.prefixLength) { |
172 | - for (int i = 0; i < octets.length; i++) { | 152 | + return false; // This prefix has smaller prefix size |
173 | - val <<= 8; | ||
174 | - val |= octets[i] & 0xff; | ||
175 | - } | ||
176 | - return val; | ||
177 | - } | ||
178 | - | ||
179 | - /** | ||
180 | - * Helper for computing the mask value from CIDR. | ||
181 | - * | ||
182 | - * @return an integer bitmask | ||
183 | - */ | ||
184 | - private int mask() { | ||
185 | - int shift = MAX_INET_MASK_LENGTH - this.netmask; | ||
186 | - return ((Integer.MAX_VALUE >>> (shift - 1)) << shift); | ||
187 | - } | ||
188 | - | ||
189 | - /** | ||
190 | - * Returns the subnet mask in IpAddress form. | ||
191 | - * | ||
192 | - * @return the subnet mask as an IpAddress | ||
193 | - */ | ||
194 | - public IpAddress netmask() { | ||
195 | - return IpAddress.valueOf(mask()); | ||
196 | - } | ||
197 | - | ||
198 | - /** | ||
199 | - * Returns the network portion of this address as an IpAddress. | ||
200 | - * The netmask of the returned IpAddress is the current mask. If this | ||
201 | - * address doesn't have a mask, this returns an all-0 IpAddress. | ||
202 | - * | ||
203 | - * @return the network address or null | ||
204 | - */ | ||
205 | - public IpPrefix network() { | ||
206 | - if (netmask == DEFAULT_MASK) { | ||
207 | - return new IpPrefix(version, ANY, DEFAULT_MASK); | ||
208 | - } | ||
209 | - | ||
210 | - byte[] net = new byte [4]; | ||
211 | - byte[] mask = bytes(mask()); | ||
212 | - for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) { | ||
213 | - net[i] = (byte) (octets[i] & mask[i]); | ||
214 | - } | ||
215 | - return new IpPrefix(version, net, netmask); | ||
216 | - } | ||
217 | - | ||
218 | - /** | ||
219 | - * Returns the host portion of the IPAddress, as an IPAddress. | ||
220 | - * The netmask of the returned IpAddress is the current mask. If this | ||
221 | - * address doesn't have a mask, this returns a copy of the current | ||
222 | - * address. | ||
223 | - * | ||
224 | - * @return the host address | ||
225 | - */ | ||
226 | - public IpPrefix host() { | ||
227 | - if (netmask == DEFAULT_MASK) { | ||
228 | - new IpPrefix(version, octets, netmask); | ||
229 | - } | ||
230 | - | ||
231 | - byte[] host = new byte [IpAddress.INET_BYTE_LENGTH]; | ||
232 | - byte[] mask = bytes(mask()); | ||
233 | - for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) { | ||
234 | - host[i] = (byte) (octets[i] & ~mask[i]); | ||
235 | } | 153 | } |
236 | - return new IpPrefix(version, host, netmask); | ||
237 | - } | ||
238 | - | ||
239 | - /** | ||
240 | - * Returns an IpAddress of the bytes contained in this prefix. | ||
241 | - * FIXME this is a hack for now and only works because IpPrefix doesn't | ||
242 | - * mask the input bytes on creation. | ||
243 | - * | ||
244 | - * @return the IpAddress | ||
245 | - */ | ||
246 | - public IpAddress toIpAddress() { | ||
247 | - return IpAddress.valueOf(octets); | ||
248 | - } | ||
249 | 154 | ||
250 | - public boolean isMasked() { | 155 | + // |
251 | - return mask() != 0; | 156 | + // Mask the other address with my prefix length. |
157 | + // If the other prefix is within this prefix, the masked address must | ||
158 | + // be same as the address of this prefix. | ||
159 | + // | ||
160 | + IpAddress maskedAddr = | ||
161 | + IpAddress.makeMaskedAddress(other.address, this.prefixLength); | ||
162 | + return this.address.equals(maskedAddr); | ||
252 | } | 163 | } |
253 | 164 | ||
254 | /** | 165 | /** |
255 | - * Determines whether a given address is contained within this IpAddress' | 166 | + * Determines whether a given IP address is contained within this prefix. |
256 | - * network. | ||
257 | * | 167 | * |
258 | - * @param other another IP address that could be contained in this network | 168 | + * @param other the IP address to test |
259 | - * @return true if the other IP address is contained in this address' | 169 | + * @return true if the IP address is contained in this prefix, otherwise |
260 | - * network, otherwise false | 170 | + * false |
261 | */ | 171 | */ |
262 | - public boolean contains(IpPrefix other) { | 172 | + public boolean contains(IpAddress other) { |
263 | - if (this.netmask <= other.netmask) { | 173 | + // |
264 | - // Special case where they're both /32 addresses | 174 | + // Mask the other address with my prefix length. |
265 | - if (this.netmask == MAX_INET_MASK_LENGTH) { | 175 | + // If the other prefix is within this prefix, the masked address must |
266 | - return Arrays.equals(octets, other.octets); | 176 | + // be same as the address of this prefix. |
267 | - } | 177 | + // |
268 | - | 178 | + IpAddress maskedAddr = |
269 | - // Mask the other address with our network mask | 179 | + IpAddress.makeMaskedAddress(other, this.prefixLength); |
270 | - IpPrefix otherMasked = | 180 | + return this.address.equals(maskedAddr); |
271 | - IpPrefix.valueOf(other.octets, netmask).network(); | ||
272 | - | ||
273 | - return network().equals(otherMasked); | ||
274 | - } | ||
275 | - return false; | ||
276 | - } | ||
277 | - | ||
278 | - public boolean contains(IpAddress address) { | ||
279 | - // Need to get the network address because prefixes aren't automatically | ||
280 | - // masked on creation | ||
281 | - IpPrefix meMasked = network(); | ||
282 | - | ||
283 | - IpPrefix otherMasked = | ||
284 | - IpPrefix.valueOf(address.toOctets(), netmask).network(); | ||
285 | - | ||
286 | - return Arrays.equals(meMasked.octets, otherMasked.octets); | ||
287 | } | 181 | } |
288 | 182 | ||
289 | @Override | 183 | @Override |
290 | public int hashCode() { | 184 | public int hashCode() { |
291 | - final int prime = 31; | 185 | + return Objects.hash(address, prefixLength); |
292 | - int result = 1; | ||
293 | - result = prime * result + netmask; | ||
294 | - result = prime * result + Arrays.hashCode(octets); | ||
295 | - result = prime * result + ((version == null) ? 0 : version.hashCode()); | ||
296 | - return result; | ||
297 | } | 186 | } |
298 | 187 | ||
299 | @Override | 188 | @Override |
... | @@ -301,46 +190,26 @@ public final class IpPrefix { | ... | @@ -301,46 +190,26 @@ public final class IpPrefix { |
301 | if (this == obj) { | 190 | if (this == obj) { |
302 | return true; | 191 | return true; |
303 | } | 192 | } |
304 | - if (obj == null) { | 193 | + if ((obj == null) || (getClass() != obj.getClass())) { |
305 | - return false; | ||
306 | - } | ||
307 | - if (getClass() != obj.getClass()) { | ||
308 | return false; | 194 | return false; |
309 | } | 195 | } |
310 | IpPrefix other = (IpPrefix) obj; | 196 | IpPrefix other = (IpPrefix) obj; |
311 | - if (netmask != other.netmask) { | 197 | + return ((prefixLength == other.prefixLength) && |
312 | - return false; | 198 | + address.equals(other.address)); |
313 | - } | ||
314 | - // TODO not quite right until we mask the input | ||
315 | - if (!Arrays.equals(octets, other.octets)) { | ||
316 | - return false; | ||
317 | - } | ||
318 | - if (version != other.version) { | ||
319 | - return false; | ||
320 | - } | ||
321 | - return true; | ||
322 | } | 199 | } |
323 | 200 | ||
324 | @Override | 201 | @Override |
325 | /* | 202 | /* |
326 | * (non-Javadoc) | 203 | * (non-Javadoc) |
327 | - * format is "x.x.x.x" for non-masked (netmask 0) addresses, | 204 | + * The format is "x.x.x.x/y" for IPv4 prefixes. |
328 | - * and "x.x.x.x/y" for masked addresses. | ||
329 | * | 205 | * |
330 | * @see java.lang.Object#toString() | 206 | * @see java.lang.Object#toString() |
331 | */ | 207 | */ |
332 | public String toString() { | 208 | public String toString() { |
333 | final StringBuilder builder = new StringBuilder(); | 209 | final StringBuilder builder = new StringBuilder(); |
334 | - for (final byte b : this.octets) { | 210 | + builder.append(address.toString()); |
335 | - if (builder.length() > 0) { | 211 | + builder.append("/"); |
336 | - builder.append("."); | 212 | + builder.append(String.format("%d", prefixLength)); |
337 | - } | ||
338 | - builder.append(String.format("%d", b & 0xff)); | ||
339 | - } | ||
340 | - if (netmask != DEFAULT_MASK) { | ||
341 | - builder.append("/"); | ||
342 | - builder.append(String.format("%d", netmask)); | ||
343 | - } | ||
344 | return builder.toString(); | 213 | return builder.toString(); |
345 | } | 214 | } |
346 | } | 215 | } | ... | ... |
... | @@ -56,6 +56,7 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -56,6 +56,7 @@ public final class KryoNamespace implements KryoFactory { |
56 | public static final class Builder { | 56 | public static final class Builder { |
57 | 57 | ||
58 | private final List<Pair<Class<?>, Serializer<?>>> types = new ArrayList<>(); | 58 | private final List<Pair<Class<?>, Serializer<?>>> types = new ArrayList<>(); |
59 | + private boolean registrationRequired = true; | ||
59 | 60 | ||
60 | /** | 61 | /** |
61 | * Builds a {@link KryoNamespace} instance. | 62 | * Builds a {@link KryoNamespace} instance. |
... | @@ -63,7 +64,7 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -63,7 +64,7 @@ public final class KryoNamespace implements KryoFactory { |
63 | * @return KryoNamespace | 64 | * @return KryoNamespace |
64 | */ | 65 | */ |
65 | public KryoNamespace build() { | 66 | public KryoNamespace build() { |
66 | - return new KryoNamespace(types); | 67 | + return new KryoNamespace(types, registrationRequired); |
67 | } | 68 | } |
68 | 69 | ||
69 | /** | 70 | /** |
... | @@ -101,6 +102,11 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -101,6 +102,11 @@ public final class KryoNamespace implements KryoFactory { |
101 | types.addAll(pool.registeredTypes); | 102 | types.addAll(pool.registeredTypes); |
102 | return this; | 103 | return this; |
103 | } | 104 | } |
105 | + | ||
106 | + public Builder setRegistrationRequired(boolean registrationRequired) { | ||
107 | + this.registrationRequired = registrationRequired; | ||
108 | + return this; | ||
109 | + } | ||
104 | } | 110 | } |
105 | 111 | ||
106 | /** | 112 | /** |
... | @@ -116,11 +122,11 @@ public final class KryoNamespace implements KryoFactory { | ... | @@ -116,11 +122,11 @@ public final class KryoNamespace implements KryoFactory { |
116 | * Creates a Kryo instance pool. | 122 | * Creates a Kryo instance pool. |
117 | * | 123 | * |
118 | * @param registeredTypes types to register | 124 | * @param registeredTypes types to register |
125 | + * @param registrationRequired | ||
119 | */ | 126 | */ |
120 | - private KryoNamespace(final List<Pair<Class<?>, Serializer<?>>> registeredTypes) { | 127 | + private KryoNamespace(final List<Pair<Class<?>, Serializer<?>>> registeredTypes, boolean registrationRequired) { |
121 | this.registeredTypes = ImmutableList.copyOf(registeredTypes); | 128 | this.registeredTypes = ImmutableList.copyOf(registeredTypes); |
122 | - // always true for now | 129 | + this.registrationRequired = registrationRequired; |
123 | - this.registrationRequired = true; | ||
124 | } | 130 | } |
125 | 131 | ||
126 | /** | 132 | /** | ... | ... |
... | @@ -22,7 +22,7 @@ import static org.junit.Assert.assertTrue; | ... | @@ -22,7 +22,7 @@ import static org.junit.Assert.assertTrue; |
22 | import java.util.Arrays; | 22 | import java.util.Arrays; |
23 | 23 | ||
24 | import org.junit.Test; | 24 | import org.junit.Test; |
25 | -import org.onlab.packet.IpPrefix.Version; | 25 | +import org.onlab.packet.IpAddress.Version; |
26 | 26 | ||
27 | import com.google.common.testing.EqualsTester; | 27 | import com.google.common.testing.EqualsTester; |
28 | 28 | ||
... | @@ -30,8 +30,9 @@ public class IpPrefixTest { | ... | @@ -30,8 +30,9 @@ public class IpPrefixTest { |
30 | 30 | ||
31 | private static final byte [] BYTES1 = new byte [] {0xa, 0x0, 0x0, 0xa}; | 31 | private static final byte [] BYTES1 = new byte [] {0xa, 0x0, 0x0, 0xa}; |
32 | private static final byte [] BYTES2 = new byte [] {0xa, 0x0, 0x0, 0xb}; | 32 | private static final byte [] BYTES2 = new byte [] {0xa, 0x0, 0x0, 0xb}; |
33 | - private static final int INTVAL1 = 167772170; | 33 | + private static final int INTVAL0 = 0x0a000000; |
34 | - private static final int INTVAL2 = 167772171; | 34 | + private static final int INTVAL1 = 0x0a00000a; |
35 | + private static final int INTVAL2 = 0x0a00000b; | ||
35 | private static final String STRVAL = "10.0.0.12/16"; | 36 | private static final String STRVAL = "10.0.0.12/16"; |
36 | private static final int MASK_LENGTH = 16; | 37 | private static final int MASK_LENGTH = 16; |
37 | 38 | ||
... | @@ -59,27 +60,29 @@ public class IpPrefixTest { | ... | @@ -59,27 +60,29 @@ public class IpPrefixTest { |
59 | @Test | 60 | @Test |
60 | public void basics() { | 61 | public void basics() { |
61 | IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); | 62 | IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); |
62 | - final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0xa}; | 63 | + final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0x0}; |
63 | 64 | ||
64 | - //check fields | 65 | + // check fields |
65 | assertEquals("incorrect IP Version", Version.INET, ip1.version()); | 66 | assertEquals("incorrect IP Version", Version.INET, ip1.version()); |
66 | assertEquals("incorrect netmask", 16, ip1.prefixLength()); | 67 | assertEquals("incorrect netmask", 16, ip1.prefixLength()); |
67 | - assertTrue("faulty toOctets()", Arrays.equals(bytes, ip1.toOctets())); | 68 | + assertTrue("faulty toOctets()", |
68 | - assertEquals("faulty toInt()", INTVAL1, ip1.toInt()); | 69 | + Arrays.equals(bytes, ip1.address().toOctets())); |
69 | - assertEquals("faulty toString()", "10.0.0.10/16", ip1.toString()); | 70 | + assertEquals("faulty toInt()", INTVAL0, ip1.address().toInt()); |
71 | + assertEquals("faulty toString()", "10.0.0.0/16", ip1.toString()); | ||
70 | } | 72 | } |
71 | 73 | ||
72 | @Test | 74 | @Test |
73 | public void netmasks() { | 75 | public void netmasks() { |
74 | // masked | 76 | // masked |
75 | IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); | 77 | IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); |
76 | - | 78 | + IpPrefix ip2 = IpPrefix.valueOf("10.0.0.10/16"); |
77 | - IpPrefix host = IpPrefix.valueOf("0.0.0.10/16"); | 79 | + IpPrefix ip3 = IpPrefix.valueOf("10.0.0.0/16"); |
78 | - IpPrefix network = IpPrefix.valueOf("10.0.0.0/16"); | 80 | + assertEquals("incorrect binary masked address", |
79 | - assertEquals("incorrect host address", host, ip1.host()); | 81 | + ip1.toString(), "10.0.0.0/16"); |
80 | - assertEquals("incorrect network address", network, ip1.network()); | 82 | + assertEquals("incorrect string masked address", |
81 | - assertEquals("incorrect netmask", "255.255.0.0", ip1.netmask().toString()); | 83 | + ip2.toString(), "10.0.0.0/16"); |
82 | - | 84 | + assertEquals("incorrect network address", |
85 | + ip2.toString(), "10.0.0.0/16"); | ||
83 | } | 86 | } |
84 | 87 | ||
85 | @Test | 88 | @Test | ... | ... |
-
Please register or login to post a comment