Added isLinkLocal predicate to MacAddress and used it in ReactiveForwarding.
Showing
3 changed files
with
71 additions
and
97 deletions
... | @@ -137,6 +137,11 @@ public class ReactiveForwarding { | ... | @@ -137,6 +137,11 @@ public class ReactiveForwarding { |
137 | 137 | ||
138 | HostId id = HostId.hostId(ethPkt.getDestinationMAC()); | 138 | HostId id = HostId.hostId(ethPkt.getDestinationMAC()); |
139 | 139 | ||
140 | + // Do not process link-local addresses in any way. | ||
141 | + if (id.mac().isLinkLocal()) { | ||
142 | + return; | ||
143 | + } | ||
144 | + | ||
140 | // Do we know who this is for? If not, flood and bail. | 145 | // Do we know who this is for? If not, flood and bail. |
141 | Host dst = hostService.getHost(id); | 146 | Host dst = hostService.getHost(id); |
142 | if (dst == null) { | 147 | if (dst == null) { | ... | ... |
... | @@ -18,20 +18,6 @@ | ... | @@ -18,20 +18,6 @@ |
18 | */ | 18 | */ |
19 | package org.onlab.onos.provider.lldp.impl; | 19 | package org.onlab.onos.provider.lldp.impl; |
20 | 20 | ||
21 | - | ||
22 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
23 | -import static org.slf4j.LoggerFactory.getLogger; | ||
24 | - | ||
25 | -import java.nio.ByteBuffer; | ||
26 | -import java.util.Collections; | ||
27 | -import java.util.HashMap; | ||
28 | -import java.util.HashSet; | ||
29 | -import java.util.Iterator; | ||
30 | -import java.util.Map; | ||
31 | -import java.util.Set; | ||
32 | -import java.util.concurrent.TimeUnit; | ||
33 | -import java.util.concurrent.atomic.AtomicInteger; | ||
34 | - | ||
35 | import org.jboss.netty.util.Timeout; | 21 | import org.jboss.netty.util.Timeout; |
36 | import org.jboss.netty.util.TimerTask; | 22 | import org.jboss.netty.util.TimerTask; |
37 | import org.onlab.onos.mastership.MastershipService; | 23 | import org.onlab.onos.mastership.MastershipService; |
... | @@ -39,10 +25,8 @@ import org.onlab.onos.net.ConnectPoint; | ... | @@ -39,10 +25,8 @@ import org.onlab.onos.net.ConnectPoint; |
39 | import org.onlab.onos.net.Device; | 25 | import org.onlab.onos.net.Device; |
40 | import org.onlab.onos.net.DeviceId; | 26 | import org.onlab.onos.net.DeviceId; |
41 | import org.onlab.onos.net.Link.Type; | 27 | import org.onlab.onos.net.Link.Type; |
42 | -import org.onlab.onos.net.MastershipRole; | ||
43 | import org.onlab.onos.net.Port; | 28 | import org.onlab.onos.net.Port; |
44 | import org.onlab.onos.net.PortNumber; | 29 | import org.onlab.onos.net.PortNumber; |
45 | -import org.onlab.onos.net.flow.DefaultTrafficTreatment; | ||
46 | import org.onlab.onos.net.link.DefaultLinkDescription; | 30 | import org.onlab.onos.net.link.DefaultLinkDescription; |
47 | import org.onlab.onos.net.link.LinkDescription; | 31 | import org.onlab.onos.net.link.LinkDescription; |
48 | import org.onlab.onos.net.link.LinkProviderService; | 32 | import org.onlab.onos.net.link.LinkProviderService; |
... | @@ -55,7 +39,21 @@ import org.onlab.packet.ONOSLLDP; | ... | @@ -55,7 +39,21 @@ import org.onlab.packet.ONOSLLDP; |
55 | import org.onlab.util.Timer; | 39 | import org.onlab.util.Timer; |
56 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
57 | 41 | ||
42 | +import java.nio.ByteBuffer; | ||
43 | +import java.util.Collections; | ||
44 | +import java.util.HashMap; | ||
45 | +import java.util.HashSet; | ||
46 | +import java.util.Iterator; | ||
47 | +import java.util.Map; | ||
48 | +import java.util.Set; | ||
49 | +import java.util.concurrent.atomic.AtomicInteger; | ||
58 | 50 | ||
51 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
52 | +import static java.util.concurrent.TimeUnit.MILLISECONDS; | ||
53 | +import static org.onlab.onos.net.MastershipRole.MASTER; | ||
54 | +import static org.onlab.onos.net.PortNumber.portNumber; | ||
55 | +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | ||
56 | +import static org.slf4j.LoggerFactory.getLogger; | ||
59 | 57 | ||
60 | /** | 58 | /** |
61 | * Run discovery process from a physical switch. Ports are initially labeled as | 59 | * Run discovery process from a physical switch. Ports are initially labeled as |
... | @@ -63,7 +61,7 @@ import org.slf4j.Logger; | ... | @@ -63,7 +61,7 @@ import org.slf4j.Logger; |
63 | * fast. Every probeRate milliseconds, loop over all fast ports and send an | 61 | * fast. Every probeRate milliseconds, loop over all fast ports and send an |
64 | * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology | 62 | * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology |
65 | * discovery implementation. | 63 | * discovery implementation. |
66 | - * | 64 | + * <p/> |
67 | * TODO: add 'fast discovery' mode: drop LLDPs in destination switch but listen | 65 | * TODO: add 'fast discovery' mode: drop LLDPs in destination switch but listen |
68 | * for flow_removed messages | 66 | * for flow_removed messages |
69 | */ | 67 | */ |
... | @@ -93,13 +91,14 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -93,13 +91,14 @@ public class LinkDiscovery implements TimerTask { |
93 | * Instantiates discovery manager for the given physical switch. Creates a | 91 | * Instantiates discovery manager for the given physical switch. Creates a |
94 | * generic LLDP packet that will be customized for the port it is sent out on. | 92 | * generic LLDP packet that will be customized for the port it is sent out on. |
95 | * Starts the the timer for the discovery process. | 93 | * Starts the the timer for the discovery process. |
94 | + * | ||
96 | * @param device the physical switch | 95 | * @param device the physical switch |
97 | - * @param masterService | 96 | + * @param masterService mastership service |
98 | * @param useBDDP flag to also use BDDP for discovery | 97 | * @param useBDDP flag to also use BDDP for discovery |
99 | */ | 98 | */ |
100 | public LinkDiscovery(Device device, PacketService pktService, | 99 | public LinkDiscovery(Device device, PacketService pktService, |
101 | - MastershipService masterService, LinkProviderService providerService, Boolean... useBDDP) { | 100 | + MastershipService masterService, |
102 | - | 101 | + LinkProviderService providerService, Boolean... useBDDP) { |
103 | this.device = device; | 102 | this.device = device; |
104 | this.probeRate = 3000; | 103 | this.probeRate = 3000; |
105 | this.linkProvider = providerService; | 104 | this.linkProvider = providerService; |
... | @@ -142,16 +141,12 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -142,16 +141,12 @@ public class LinkDiscovery implements TimerTask { |
142 | * @param port the port | 141 | * @param port the port |
143 | */ | 142 | */ |
144 | public void addPort(final Port port) { | 143 | public void addPort(final Port port) { |
145 | - this.log.debug("sending init probe to port {}@{}", | 144 | + this.log.debug("Sending init probe to port {}@{}", |
146 | port.number().toLong(), device.id()); | 145 | port.number().toLong(), device.id()); |
147 | - | ||
148 | sendProbes(port.number().toLong()); | 146 | sendProbes(port.number().toLong()); |
149 | - | ||
150 | synchronized (this) { | 147 | synchronized (this) { |
151 | this.slowPorts.add(port.number().toLong()); | 148 | this.slowPorts.add(port.number().toLong()); |
152 | } | 149 | } |
153 | - | ||
154 | - | ||
155 | } | 150 | } |
156 | 151 | ||
157 | /** | 152 | /** |
... | @@ -172,8 +167,7 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -172,8 +167,7 @@ public class LinkDiscovery implements TimerTask { |
172 | this.portProbeCount.remove(portnum); | 167 | this.portProbeCount.remove(portnum); |
173 | // no iterator to update | 168 | // no iterator to update |
174 | } else { | 169 | } else { |
175 | - this.log.warn( | 170 | + this.log.warn("Tried to dynamically remove non-existing port {}", |
176 | - "tried to dynamically remove non-existing port {}", | ||
177 | portnum); | 171 | portnum); |
178 | } | 172 | } |
179 | } | 173 | } |
... | @@ -187,7 +181,6 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -187,7 +181,6 @@ public class LinkDiscovery implements TimerTask { |
187 | * @param portNumber the port | 181 | * @param portNumber the port |
188 | */ | 182 | */ |
189 | public void ackProbe(final Long portNumber) { | 183 | public void ackProbe(final Long portNumber) { |
190 | - | ||
191 | synchronized (this) { | 184 | synchronized (this) { |
192 | if (this.slowPorts.contains(portNumber)) { | 185 | if (this.slowPorts.contains(portNumber)) { |
193 | this.log.debug("Setting slow port to fast: {}:{}", | 186 | this.log.debug("Setting slow port to fast: {}:{}", |
... | @@ -198,10 +191,7 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -198,10 +191,7 @@ public class LinkDiscovery implements TimerTask { |
198 | } else if (this.fastPorts.contains(portNumber)) { | 191 | } else if (this.fastPorts.contains(portNumber)) { |
199 | this.portProbeCount.get(portNumber).set(0); | 192 | this.portProbeCount.get(portNumber).set(0); |
200 | } else { | 193 | } else { |
201 | - this.log.debug( | 194 | + this.log.debug("Got ackProbe for non-existing port: {}", portNumber); |
202 | - "Got ackProbe for non-existing port: {}", | ||
203 | - portNumber); | ||
204 | - | ||
205 | } | 195 | } |
206 | } | 196 | } |
207 | } | 197 | } |
... | @@ -217,7 +207,7 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -217,7 +207,7 @@ public class LinkDiscovery implements TimerTask { |
217 | if (onoslldp != null) { | 207 | if (onoslldp != null) { |
218 | final PortNumber dstPort = | 208 | final PortNumber dstPort = |
219 | context.inPacket().receivedFrom().port(); | 209 | context.inPacket().receivedFrom().port(); |
220 | - final PortNumber srcPort = PortNumber.portNumber(onoslldp.getPort()); | 210 | + final PortNumber srcPort = portNumber(onoslldp.getPort()); |
221 | final DeviceId srcDeviceId = DeviceId.deviceId(onoslldp.getDeviceString()); | 211 | final DeviceId srcDeviceId = DeviceId.deviceId(onoslldp.getDeviceString()); |
222 | final DeviceId dstDeviceId = context.inPacket().receivedFrom().deviceId(); | 212 | final DeviceId dstDeviceId = context.inPacket().receivedFrom().deviceId(); |
223 | this.ackProbe(dstPort.toLong()); | 213 | this.ackProbe(dstPort.toLong()); |
... | @@ -237,61 +227,48 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -237,61 +227,48 @@ public class LinkDiscovery implements TimerTask { |
237 | } | 227 | } |
238 | 228 | ||
239 | 229 | ||
240 | - | ||
241 | /** | 230 | /** |
242 | * Execute this method every t milliseconds. Loops over all ports | 231 | * Execute this method every t milliseconds. Loops over all ports |
243 | * labeled as fast and sends out an LLDP. Send out an LLDP on a single slow | 232 | * labeled as fast and sends out an LLDP. Send out an LLDP on a single slow |
244 | * port. | 233 | * port. |
245 | * | 234 | * |
246 | * @param t timeout | 235 | * @param t timeout |
247 | - * @throws Exception | ||
248 | */ | 236 | */ |
249 | @Override | 237 | @Override |
250 | public void run(final Timeout t) { | 238 | public void run(final Timeout t) { |
251 | - this.log.trace("sending probes from {}", device.id()); | 239 | + this.log.trace("Sending probes from {}", device.id()); |
252 | synchronized (this) { | 240 | synchronized (this) { |
253 | final Iterator<Long> fastIterator = this.fastPorts.iterator(); | 241 | final Iterator<Long> fastIterator = this.fastPorts.iterator(); |
254 | - Long portNumber; | ||
255 | - Integer probeCount; | ||
256 | while (fastIterator.hasNext()) { | 242 | while (fastIterator.hasNext()) { |
257 | - portNumber = fastIterator.next(); | 243 | + long portNumber = fastIterator.next(); |
258 | - probeCount = this.portProbeCount.get(portNumber) | 244 | + int probeCount = portProbeCount.get(portNumber).getAndIncrement(); |
259 | - .getAndIncrement(); | ||
260 | 245 | ||
261 | if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) { | 246 | if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) { |
262 | - this.log.trace("sending fast probe to port {}", portNumber); | 247 | + this.log.trace("Sending fast probe to port {}", portNumber); |
263 | sendProbes(portNumber); | 248 | sendProbes(portNumber); |
249 | + | ||
264 | } else { | 250 | } else { |
265 | // Update fast and slow ports | 251 | // Update fast and slow ports |
266 | fastIterator.remove(); | 252 | fastIterator.remove(); |
267 | this.slowPorts.add(portNumber); | 253 | this.slowPorts.add(portNumber); |
268 | this.portProbeCount.remove(portNumber); | 254 | this.portProbeCount.remove(portNumber); |
269 | 255 | ||
270 | - | 256 | + ConnectPoint cp = new ConnectPoint(device.id(), |
271 | - ConnectPoint cp = new ConnectPoint( | 257 | + portNumber(portNumber)); |
272 | - device.id(), | ||
273 | - PortNumber.portNumber(portNumber)); | ||
274 | log.debug("Link down -> {}", cp); | 258 | log.debug("Link down -> {}", cp); |
275 | linkProvider.linksVanished(cp); | 259 | linkProvider.linksVanished(cp); |
276 | } | 260 | } |
277 | } | 261 | } |
278 | 262 | ||
279 | // send a probe for the next slow port | 263 | // send a probe for the next slow port |
280 | - if (!this.slowPorts.isEmpty()) { | 264 | + for (long portNumber : slowPorts) { |
281 | - Iterator<Long> slowIterator = this.slowPorts.iterator(); | 265 | + this.log.trace("Sending slow probe to port {}", portNumber); |
282 | - while (slowIterator.hasNext()) { | ||
283 | - portNumber = slowIterator.next(); | ||
284 | - this.log.trace("sending slow probe to port {}", portNumber); | ||
285 | - | ||
286 | sendProbes(portNumber); | 266 | sendProbes(portNumber); |
287 | - | ||
288 | - } | ||
289 | } | 267 | } |
290 | } | 268 | } |
291 | 269 | ||
292 | // reschedule timer | 270 | // reschedule timer |
293 | - timeout = Timer.getTimer().newTimeout(this, this.probeRate, | 271 | + timeout = Timer.getTimer().newTimeout(this, this.probeRate, MILLISECONDS); |
294 | - TimeUnit.MILLISECONDS); | ||
295 | } | 272 | } |
296 | 273 | ||
297 | public void stop() { | 274 | public void stop() { |
... | @@ -300,8 +277,7 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -300,8 +277,7 @@ public class LinkDiscovery implements TimerTask { |
300 | } | 277 | } |
301 | 278 | ||
302 | public void start() { | 279 | public void start() { |
303 | - timeout = Timer.getTimer().newTimeout(this, 0, | 280 | + timeout = Timer.getTimer().newTimeout(this, 0, MILLISECONDS); |
304 | - TimeUnit.MILLISECONDS); | ||
305 | isStopped = false; | 281 | isStopped = false; |
306 | } | 282 | } |
307 | 283 | ||
... | @@ -319,12 +295,9 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -319,12 +295,9 @@ public class LinkDiscovery implements TimerTask { |
319 | this.ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11"); | 295 | this.ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11"); |
320 | 296 | ||
321 | final byte[] lldp = this.ethPacket.serialize(); | 297 | final byte[] lldp = this.ethPacket.serialize(); |
322 | - OutboundPacket outboundPacket = new DefaultOutboundPacket( | 298 | + return new DefaultOutboundPacket(this.device.id(), |
323 | - this.device.id(), | 299 | + builder().setOutput(portNumber(port)).build(), |
324 | - DefaultTrafficTreatment.builder().setOutput( | ||
325 | - PortNumber.portNumber(port)).build(), | ||
326 | ByteBuffer.wrap(lldp)); | 300 | ByteBuffer.wrap(lldp)); |
327 | - return outboundPacket; | ||
328 | } | 301 | } |
329 | 302 | ||
330 | /** | 303 | /** |
... | @@ -341,25 +314,15 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -341,25 +314,15 @@ public class LinkDiscovery implements TimerTask { |
341 | this.bddpEth.setSourceMACAddress("DE:AD:BE:EF:BA:11"); | 314 | this.bddpEth.setSourceMACAddress("DE:AD:BE:EF:BA:11"); |
342 | 315 | ||
343 | final byte[] bddp = this.bddpEth.serialize(); | 316 | final byte[] bddp = this.bddpEth.serialize(); |
344 | - OutboundPacket outboundPacket = new DefaultOutboundPacket( | 317 | + return new DefaultOutboundPacket(this.device.id(), |
345 | - this.device.id(), | 318 | + builder().setOutput(portNumber(port)).build(), |
346 | - DefaultTrafficTreatment.builder() | ||
347 | - .setOutput(PortNumber.portNumber(port)).build(), | ||
348 | ByteBuffer.wrap(bddp)); | 319 | ByteBuffer.wrap(bddp)); |
349 | - return outboundPacket; | ||
350 | } | 320 | } |
351 | 321 | ||
352 | private void sendProbes(Long portNumber) { | 322 | private void sendProbes(Long portNumber) { |
353 | - if (device == null) { | 323 | + boolean isMaster = mastershipService.getLocalRole(device.id()) == MASTER; |
354 | - log.warn("CRAZY SHIT"); | 324 | + if (isMaster && device.type() != Device.Type.ROADM) { |
355 | - } | 325 | + log.debug("Sending probes out to {}@{}", portNumber, device.id()); |
356 | - if (mastershipService == null) { | ||
357 | - log.warn("INSANE"); | ||
358 | - } | ||
359 | - if (device.type() != Device.Type.ROADM && | ||
360 | - mastershipService.getLocalRole(this.device.id()) == | ||
361 | - MastershipRole.MASTER) { | ||
362 | - log.debug("sending probes out to {}@{}", portNumber, device.id()); | ||
363 | OutboundPacket pkt = this.createOutBoundLLDP(portNumber); | 326 | OutboundPacket pkt = this.createOutBoundLLDP(portNumber); |
364 | pktService.emit(pkt); | 327 | pktService.emit(pkt); |
365 | if (useBDDP) { | 328 | if (useBDDP) { |
... | @@ -370,10 +333,7 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -370,10 +333,7 @@ public class LinkDiscovery implements TimerTask { |
370 | } | 333 | } |
371 | 334 | ||
372 | public boolean containsPort(Long portNumber) { | 335 | public boolean containsPort(Long portNumber) { |
373 | - if (slowPorts.contains(portNumber) || fastPorts.contains(portNumber)) { | 336 | + return slowPorts.contains(portNumber) || fastPorts.contains(portNumber); |
374 | - return true; | ||
375 | - } | ||
376 | - return false; | ||
377 | } | 337 | } |
378 | 338 | ||
379 | public boolean isStopped() { | 339 | public boolean isStopped() { | ... | ... |
... | @@ -22,7 +22,6 @@ import java.util.Arrays; | ... | @@ -22,7 +22,6 @@ import java.util.Arrays; |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * The class representing MAC address. | 24 | * The class representing MAC address. |
25 | - * | ||
26 | */ | 25 | */ |
27 | public class MacAddress { | 26 | public class MacAddress { |
28 | 27 | ||
... | @@ -32,6 +31,11 @@ public class MacAddress { | ... | @@ -32,6 +31,11 @@ public class MacAddress { |
32 | public static final byte[] ZERO_MAC_ADDRESS = ZERO.getAddress(); | 31 | public static final byte[] ZERO_MAC_ADDRESS = ZERO.getAddress(); |
33 | public static final byte[] BROADCAST_MAC = BROADCAST.getAddress(); | 32 | public static final byte[] BROADCAST_MAC = BROADCAST.getAddress(); |
34 | 33 | ||
34 | + private static final byte[] LL = new byte[]{ | ||
35 | + 0x01, (byte) 0x80, (byte) 0xc2, 0x00, 0x00, | ||
36 | + 0x00, 0x0e, 0x03 | ||
37 | + }; | ||
38 | + | ||
35 | public static final int MAC_ADDRESS_LENGTH = 6; | 39 | public static final int MAC_ADDRESS_LENGTH = 6; |
36 | private byte[] address = new byte[MacAddress.MAC_ADDRESS_LENGTH]; | 40 | private byte[] address = new byte[MacAddress.MAC_ADDRESS_LENGTH]; |
37 | 41 | ||
... | @@ -43,12 +47,10 @@ public class MacAddress { | ... | @@ -43,12 +47,10 @@ public class MacAddress { |
43 | * Returns a MAC address instance representing the value of the specified | 47 | * Returns a MAC address instance representing the value of the specified |
44 | * {@code String}. | 48 | * {@code String}. |
45 | * | 49 | * |
46 | - * @param address | 50 | + * @param address the String representation of the MAC Address to be parsed. |
47 | - * the String representation of the MAC Address to be parsed. | ||
48 | * @return a MAC Address instance representing the value of the specified | 51 | * @return a MAC Address instance representing the value of the specified |
49 | * {@code String}. | 52 | * {@code String}. |
50 | - * @throws IllegalArgumentException | 53 | + * @throws IllegalArgumentException if the string cannot be parsed as a MAC address. |
51 | - * if the string cannot be parsed as a MAC address. | ||
52 | */ | 54 | */ |
53 | public static MacAddress valueOf(final String address) { | 55 | public static MacAddress valueOf(final String address) { |
54 | final String[] elements = address.split(":"); | 56 | final String[] elements = address.split(":"); |
... | @@ -71,12 +73,10 @@ public class MacAddress { | ... | @@ -71,12 +73,10 @@ public class MacAddress { |
71 | * Returns a MAC address instance representing the specified {@code byte} | 73 | * Returns a MAC address instance representing the specified {@code byte} |
72 | * array. | 74 | * array. |
73 | * | 75 | * |
74 | - * @param address | 76 | + * @param address the byte array to be parsed. |
75 | - * the byte array to be parsed. | ||
76 | * @return a MAC address instance representing the specified {@code byte} | 77 | * @return a MAC address instance representing the specified {@code byte} |
77 | * array. | 78 | * array. |
78 | - * @throws IllegalArgumentException | 79 | + * @throws IllegalArgumentException if the byte array cannot be parsed as a MAC address. |
79 | - * if the byte array cannot be parsed as a MAC address. | ||
80 | */ | 80 | */ |
81 | public static MacAddress valueOf(final byte[] address) { | 81 | public static MacAddress valueOf(final byte[] address) { |
82 | if (address.length != MacAddress.MAC_ADDRESS_LENGTH) { | 82 | if (address.length != MacAddress.MAC_ADDRESS_LENGTH) { |
... | @@ -92,19 +92,17 @@ public class MacAddress { | ... | @@ -92,19 +92,17 @@ public class MacAddress { |
92 | * value. The lower 48 bits of the long value are used to parse as a MAC | 92 | * value. The lower 48 bits of the long value are used to parse as a MAC |
93 | * address. | 93 | * address. |
94 | * | 94 | * |
95 | - * @param address | 95 | + * @param address the long value to be parsed. The lower 48 bits are used for a |
96 | - * the long value to be parsed. The lower 48 bits are used for a | ||
97 | * MAC address. | 96 | * MAC address. |
98 | * @return a MAC address instance representing the specified {@code long} | 97 | * @return a MAC address instance representing the specified {@code long} |
99 | * value. | 98 | * value. |
100 | - * @throws IllegalArgumentException | 99 | + * @throws IllegalArgumentException if the long value cannot be parsed as a MAC address. |
101 | - * if the long value cannot be parsed as a MAC address. | ||
102 | */ | 100 | */ |
103 | public static MacAddress valueOf(final long address) { | 101 | public static MacAddress valueOf(final long address) { |
104 | - final byte[] addressInBytes = new byte[] { | 102 | + final byte[] addressInBytes = new byte[]{ |
105 | (byte) (address >> 40 & 0xff), (byte) (address >> 32 & 0xff), | 103 | (byte) (address >> 40 & 0xff), (byte) (address >> 32 & 0xff), |
106 | (byte) (address >> 24 & 0xff), (byte) (address >> 16 & 0xff), | 104 | (byte) (address >> 24 & 0xff), (byte) (address >> 16 & 0xff), |
107 | - (byte) (address >> 8 & 0xff), (byte) (address >> 0 & 0xff) }; | 105 | + (byte) (address >> 8 & 0xff), (byte) (address >> 0 & 0xff)}; |
108 | 106 | ||
109 | return new MacAddress(addressInBytes); | 107 | return new MacAddress(addressInBytes); |
110 | } | 108 | } |
... | @@ -169,6 +167,17 @@ public class MacAddress { | ... | @@ -169,6 +167,17 @@ public class MacAddress { |
169 | return (this.address[0] & 0x01) != 0; | 167 | return (this.address[0] & 0x01) != 0; |
170 | } | 168 | } |
171 | 169 | ||
170 | + /** | ||
171 | + * Returns true if this MAC address is link local. | ||
172 | + * | ||
173 | + * @return true if link local | ||
174 | + */ | ||
175 | + public boolean isLinkLocal() { | ||
176 | + return LL[0] == address[0] && LL[1] == address[1] && LL[2] == address[2] && | ||
177 | + LL[3] == address[3] && LL[4] == address[4] && | ||
178 | + (LL[5] == address[5] || LL[6] == address[5] || LL[7] == address[5]); | ||
179 | + } | ||
180 | + | ||
172 | @Override | 181 | @Override |
173 | public boolean equals(final Object o) { | 182 | public boolean equals(final Object o) { |
174 | if (o == this) { | 183 | if (o == this) { | ... | ... |
-
Please register or login to post a comment