Praseed Balakrishnan

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 80 changed files with 2070 additions and 552 deletions
...@@ -368,12 +368,12 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro ...@@ -368,12 +368,12 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro
368 } 368 }
369 369
370 @Override 370 @Override
371 - public void roleChanged(Device device, MastershipRole newRole) { 371 + public void roleChanged(DeviceId device, MastershipRole newRole) {
372 // TODO Auto-generated method stub. 372 // TODO Auto-generated method stub.
373 } 373 }
374 374
375 @Override 375 @Override
376 - public boolean isReachable(Device device) { 376 + public boolean isReachable(DeviceId device) {
377 return false; 377 return false;
378 } 378 }
379 } 379 }
......
...@@ -246,11 +246,13 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -246,11 +246,13 @@ public class BgpSession extends SimpleChannelHandler {
246 InetAddress inetAddr; 246 InetAddress inetAddr;
247 if (localAddress instanceof InetSocketAddress) { 247 if (localAddress instanceof InetSocketAddress) {
248 inetAddr = ((InetSocketAddress) localAddress).getAddress(); 248 inetAddr = ((InetSocketAddress) localAddress).getAddress();
249 - localIp4Address = IpAddress.valueOf(inetAddr.getAddress()); 249 + localIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
250 + inetAddr.getAddress());
250 } 251 }
251 if (remoteAddress instanceof InetSocketAddress) { 252 if (remoteAddress instanceof InetSocketAddress) {
252 inetAddr = ((InetSocketAddress) remoteAddress).getAddress(); 253 inetAddr = ((InetSocketAddress) remoteAddress).getAddress();
253 - remoteIp4Address = IpAddress.valueOf(inetAddr.getAddress()); 254 + remoteIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
255 + inetAddr.getAddress());
254 } 256 }
255 257
256 log.debug("BGP Session Connected from {} on {}", 258 log.debug("BGP Session Connected from {} on {}",
......
...@@ -105,7 +105,8 @@ public class BgpSessionManager { ...@@ -105,7 +105,8 @@ public class BgpSessionManager {
105 if (bgpSession.getLocalAddress() instanceof InetSocketAddress) { 105 if (bgpSession.getLocalAddress() instanceof InetSocketAddress) {
106 InetAddress inetAddr = 106 InetAddress inetAddr =
107 ((InetSocketAddress) bgpSession.getLocalAddress()).getAddress(); 107 ((InetSocketAddress) bgpSession.getLocalAddress()).getAddress();
108 - IpAddress ip4Address = IpAddress.valueOf(inetAddr.getAddress()); 108 + IpAddress ip4Address = IpAddress.valueOf(IpAddress.Version.INET,
109 + inetAddr.getAddress());
109 updateMyBgpId(ip4Address); 110 updateMyBgpId(ip4Address);
110 } 111 }
111 return true; 112 return true;
......
...@@ -74,7 +74,7 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand { ...@@ -74,7 +74,7 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand {
74 * @param deviceString string representing the device/port 74 * @param deviceString string representing the device/port
75 * @return port number as a string, empty string if the port is not found 75 * @return port number as a string, empty string if the port is not found
76 */ 76 */
77 - private String getPortNumber(String deviceString) { 77 + public static String getPortNumber(String deviceString) {
78 int slash = deviceString.indexOf('/'); 78 int slash = deviceString.indexOf('/');
79 if (slash <= 0) { 79 if (slash <= 0) {
80 return ""; 80 return "";
...@@ -88,7 +88,7 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand { ...@@ -88,7 +88,7 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand {
88 * @param deviceString string representing the device/port 88 * @param deviceString string representing the device/port
89 * @return device ID string 89 * @return device ID string
90 */ 90 */
91 - private String getDeviceId(String deviceString) { 91 + public static String getDeviceId(String deviceString) {
92 int slash = deviceString.indexOf('/'); 92 int slash = deviceString.indexOf('/');
93 if (slash <= 0) { 93 if (slash <= 0) {
94 return ""; 94 return "";
......
...@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.fasterxml.jackson.databind.node.ArrayNode; 20 import com.fasterxml.jackson.databind.node.ArrayNode;
21 import com.fasterxml.jackson.databind.node.ObjectNode; 21 import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Command; 22 import org.apache.karaf.shell.commands.Command;
23 +import org.apache.karaf.shell.commands.Option;
23 import org.onlab.onos.cli.AbstractShellCommand; 24 import org.onlab.onos.cli.AbstractShellCommand;
24 import org.onlab.onos.net.ConnectPoint; 25 import org.onlab.onos.net.ConnectPoint;
25 import org.onlab.onos.net.Link; 26 import org.onlab.onos.net.Link;
...@@ -44,6 +45,11 @@ import java.util.Set; ...@@ -44,6 +45,11 @@ import java.util.Set;
44 description = "Lists the inventory of intents and their states") 45 description = "Lists the inventory of intents and their states")
45 public class IntentsListCommand extends AbstractShellCommand { 46 public class IntentsListCommand extends AbstractShellCommand {
46 47
48 + @Option(name = "-i", aliases = "--installable", description = "Output Installable Intents",
49 + required = false, multiValued = false)
50 + private boolean showInstallable = false;
51 +
52 +
47 @Override 53 @Override
48 protected void execute() { 54 protected void execute() {
49 IntentService service = get(IntentService.class); 55 IntentService service = get(IntentService.class);
...@@ -93,7 +99,7 @@ public class IntentsListCommand extends AbstractShellCommand { ...@@ -93,7 +99,7 @@ public class IntentsListCommand extends AbstractShellCommand {
93 } 99 }
94 100
95 List<Intent> installable = service.getInstallableIntents(intent.id()); 101 List<Intent> installable = service.getInstallableIntents(intent.id());
96 - if (installable != null && !installable.isEmpty()) { 102 + if (showInstallable && installable != null && !installable.isEmpty()) {
97 print(" installable=%s", installable); 103 print(" installable=%s", installable);
98 } 104 }
99 } 105 }
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.cli.net;
17 +
18 +import org.apache.karaf.shell.commands.Argument;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onlab.onos.cli.AbstractShellCommand;
21 +import org.onlab.onos.net.ConnectPoint;
22 +import org.onlab.onos.net.DeviceId;
23 +import org.onlab.onos.net.Link;
24 +import org.onlab.onos.net.PortNumber;
25 +import org.onlab.onos.net.link.LinkService;
26 +import org.onlab.onos.net.resource.LinkResourceAllocations;
27 +import org.onlab.onos.net.resource.LinkResourceService;
28 +
29 +import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getDeviceId;
30 +import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getPortNumber;
31 +import static org.onlab.onos.net.DeviceId.deviceId;
32 +import static org.onlab.onos.net.PortNumber.portNumber;
33 +
34 +/**
35 + * Lists allocations by link.
36 + */
37 +@Command(scope = "onos", name = "resource-allocations",
38 + description = "Lists allocations by link")
39 +public class ResourceAllocationsCommand extends AbstractShellCommand {
40 +
41 + private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
42 + private static final String COMPACT = "%s/%s-%s/%s";
43 +
44 + @Argument(index = 0, name = "srcString", description = "Link source",
45 + required = false, multiValued = false)
46 + String srcString = null;
47 + @Argument(index = 1, name = "dstString", description = "Link destination",
48 + required = false, multiValued = false)
49 + String dstString = null;
50 +
51 + @Override
52 + protected void execute() {
53 + LinkResourceService resourceService = get(LinkResourceService.class);
54 + LinkService linkService = get(LinkService.class);
55 +
56 + Iterable<LinkResourceAllocations> itr = null;
57 + try {
58 + DeviceId ingressDeviceId = deviceId(getDeviceId(srcString));
59 + PortNumber ingressPortNumber = portNumber(getPortNumber(srcString));
60 + ConnectPoint src = new ConnectPoint(ingressDeviceId, ingressPortNumber);
61 +
62 + DeviceId egressDeviceId = deviceId(getDeviceId(dstString));
63 + PortNumber egressPortNumber = portNumber(getPortNumber(dstString));
64 + ConnectPoint dst = new ConnectPoint(egressDeviceId, egressPortNumber);
65 +
66 + Link link = linkService.getLink(src, dst);
67 +
68 + itr = resourceService.getAllocations(link);
69 +
70 + for (LinkResourceAllocations allocation : itr) {
71 + print("%s", allocation.getResourceAllocation(link));
72 + }
73 +
74 + } catch (Exception e) {
75 + print("----- Displaying all resource allocations -----", e.getMessage());
76 + itr = resourceService.getAllocations();
77 + for (LinkResourceAllocations allocation : itr) {
78 + print("%s", allocation);
79 + }
80 +
81 + }
82 + }
83 +}
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.cli.net;
17 +
18 +import org.apache.karaf.shell.commands.Argument;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onlab.onos.cli.AbstractShellCommand;
21 +import org.onlab.onos.net.ConnectPoint;
22 +import org.onlab.onos.net.DeviceId;
23 +import org.onlab.onos.net.Link;
24 +import org.onlab.onos.net.PortNumber;
25 +import org.onlab.onos.net.link.LinkService;
26 +import org.onlab.onos.net.resource.LinkResourceService;
27 +import org.onlab.onos.net.resource.ResourceRequest;
28 +
29 +import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getDeviceId;
30 +import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getPortNumber;
31 +import static org.onlab.onos.net.DeviceId.deviceId;
32 +import static org.onlab.onos.net.PortNumber.portNumber;
33 +
34 +/**
35 + * Lists allocations by link.
36 + */
37 +@Command(scope = "onos", name = "resource-available",
38 + description = "Lists available resources by link")
39 +public class ResourceAvailableCommand extends AbstractShellCommand {
40 +
41 + private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
42 + private static final String COMPACT = "%s/%s-%s/%s";
43 +
44 + @Argument(index = 0, name = "srcString", description = "Link source",
45 + required = false, multiValued = false)
46 + String srcString = null;
47 + @Argument(index = 1, name = "dstString", description = "Link destination",
48 + required = false, multiValued = false)
49 + String dstString = null;
50 +
51 + @Override
52 + protected void execute() {
53 + LinkResourceService resourceService = get(LinkResourceService.class);
54 + LinkService linkService = get(LinkService.class);
55 +
56 + Iterable<ResourceRequest> itr = null;
57 + try {
58 + DeviceId ingressDeviceId = deviceId(getDeviceId(srcString));
59 + PortNumber ingressPortNumber = portNumber(getPortNumber(srcString));
60 + ConnectPoint src = new ConnectPoint(ingressDeviceId, ingressPortNumber);
61 +
62 + DeviceId egressDeviceId = deviceId(getDeviceId(dstString));
63 + PortNumber egressPortNumber = portNumber(getPortNumber(dstString));
64 + ConnectPoint dst = new ConnectPoint(egressDeviceId, egressPortNumber);
65 +
66 + Link link = linkService.getLink(src, dst);
67 +
68 + itr = resourceService.getAvailableResources(link);
69 +
70 + int lambdaCount = 0;
71 + for (ResourceRequest req : itr) {
72 + switch (req.type()) {
73 + case LAMBDA:
74 + lambdaCount++;
75 + break;
76 + case BANDWIDTH:
77 + print("%s", req);
78 + break;
79 + default:
80 + break;
81 + }
82 + }
83 + if (lambdaCount > 0) {
84 + print("Number of available lambdas: %d", lambdaCount);
85 + }
86 +
87 + } catch (Exception e) {
88 + print("Invalid link", e.getMessage());
89 + }
90 + }
91 +}
...@@ -158,7 +158,22 @@ ...@@ -158,7 +158,22 @@
158 <null/> 158 <null/>
159 </completers> 159 </completers>
160 </command> 160 </command>
161 - 161 + <command>
162 + <action class="org.onlab.onos.cli.net.ResourceAllocationsCommand"/>
163 + <completers>
164 + <ref component-id="connectPointCompleter"/>
165 + <ref component-id="connectPointCompleter"/>
166 + <null/>
167 + </completers>
168 + </command>
169 + <command>
170 + <action class="org.onlab.onos.cli.net.ResourceAvailableCommand"/>
171 + <completers>
172 + <ref component-id="connectPointCompleter"/>
173 + <ref component-id="connectPointCompleter"/>
174 + <null/>
175 + </completers>
176 + </command>
162 <command> 177 <command>
163 <action class="org.onlab.onos.cli.net.ClustersListCommand"/> 178 <action class="org.onlab.onos.cli.net.ClustersListCommand"/>
164 </command> 179 </command>
......
...@@ -40,7 +40,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -40,7 +40,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
40 MASTER_CHANGED, 40 MASTER_CHANGED,
41 41
42 /** 42 /**
43 - * Signifies that the list of backup nodes has changed. 43 + * Signifies that the list of backup nodes has changed. If
44 + * the change in the backups list is accompanied by a change in
45 + * master, the event is subsumed by MASTER_CHANGED.
44 */ 46 */
45 BACKUPS_CHANGED 47 BACKUPS_CHANGED
46 } 48 }
...@@ -49,9 +51,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -49,9 +51,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
49 * Creates an event of a given type and for the specified device, 51 * Creates an event of a given type and for the specified device,
50 * role information, and the current time. 52 * role information, and the current time.
51 * 53 *
52 - * @param type device event type 54 + * @param type mastership event type
53 * @param device event device subject 55 * @param device event device subject
54 - * @param info mastership role information subject 56 + * @param info mastership role information
55 */ 57 */
56 public MastershipEvent(Type type, DeviceId device, RoleInfo info) { 58 public MastershipEvent(Type type, DeviceId device, RoleInfo info) {
57 super(type, device); 59 super(type, device);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 package org.onlab.onos.net; 16 package org.onlab.onos.net;
17 17
18 /** 18 /**
19 - * Representation of a network resource. 19 + * Representation of a network resource, e.g. a link, lambda, MPLS tag.
20 */ 20 */
21 public interface NetworkResource { 21 public interface NetworkResource {
22 } 22 }
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.onos.net;
17 +
18 +/**
19 + * Abstraction of a generalized network tunnel.
20 + */
21 +public interface Tunnel extends Link {
22 +
23 + /**
24 + * Tunnel technology type.
25 + */
26 + enum Type {
27 + MPLS, VLAN, VXLAN, GRE, OPTICAL
28 + }
29 +
30 + /**
31 + * Network resource backing the tunnel, e.g. lambda, VLAN id, MPLS tag.
32 + *
33 + * @return backing resource
34 + */
35 + NetworkResource resource();
36 +
37 +}
...@@ -25,6 +25,14 @@ import org.onlab.onos.net.DeviceId; ...@@ -25,6 +25,14 @@ import org.onlab.onos.net.DeviceId;
25 public interface DeviceClockProviderService { 25 public interface DeviceClockProviderService {
26 26
27 /** 27 /**
28 + * Checks if this service can issue Timestamp for specified device.
29 + *
30 + * @param deviceId device identifier.
31 + * @return true if timestamp can be issued for specified device
32 + */
33 + public boolean isTimestampAvailable(DeviceId deviceId);
34 +
35 + /**
28 * Updates the mastership term for the specified deviceId. 36 * Updates the mastership term for the specified deviceId.
29 * 37 *
30 * @param deviceId device identifier. 38 * @param deviceId device identifier.
......
...@@ -24,7 +24,16 @@ import org.onlab.onos.store.Timestamp; ...@@ -24,7 +24,16 @@ import org.onlab.onos.store.Timestamp;
24 public interface DeviceClockService { 24 public interface DeviceClockService {
25 25
26 /** 26 /**
27 + * Checks if this service can issue Timestamp for specified device.
28 + *
29 + * @param deviceId device identifier.
30 + * @return true if timestamp can be issued for specified device
31 + */
32 + public boolean isTimestampAvailable(DeviceId deviceId);
33 +
34 + /**
27 * Returns a new timestamp for the specified deviceId. 35 * Returns a new timestamp for the specified deviceId.
36 + *
28 * @param deviceId device identifier. 37 * @param deviceId device identifier.
29 * @return timestamp. 38 * @return timestamp.
30 */ 39 */
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onlab.onos.net.device; 16 package org.onlab.onos.net.device;
17 17
18 import org.onlab.onos.net.Device; 18 import org.onlab.onos.net.Device;
19 +import org.onlab.onos.net.DeviceId;
19 import org.onlab.onos.net.MastershipRole; 20 import org.onlab.onos.net.MastershipRole;
20 import org.onlab.onos.net.provider.Provider; 21 import org.onlab.onos.net.provider.Provider;
21 22
...@@ -42,16 +43,16 @@ public interface DeviceProvider extends Provider { ...@@ -42,16 +43,16 @@ public interface DeviceProvider extends Provider {
42 * Notifies the provider of a mastership role change for the specified 43 * Notifies the provider of a mastership role change for the specified
43 * device as decided by the core. 44 * device as decided by the core.
44 * 45 *
45 - * @param device affected device 46 + * @param deviceId device identifier
46 * @param newRole newly determined mastership role 47 * @param newRole newly determined mastership role
47 */ 48 */
48 - void roleChanged(Device device, MastershipRole newRole); 49 + void roleChanged(DeviceId deviceId, MastershipRole newRole);
49 50
50 /** 51 /**
51 * Checks the reachability (connectivity) of a device from this provider. 52 * Checks the reachability (connectivity) of a device from this provider.
52 * 53 *
53 - * @param device device to check 54 + * @param deviceId device identifier
54 * @return true if reachable, false otherwise 55 * @return true if reachable, false otherwise
55 */ 56 */
56 - boolean isReachable(Device device); 57 + boolean isReachable(DeviceId deviceId);
57 } 58 }
......
...@@ -61,12 +61,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> { ...@@ -61,12 +61,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> {
61 void portStatusChanged(DeviceId deviceId, PortDescription portDescription); 61 void portStatusChanged(DeviceId deviceId, PortDescription portDescription);
62 62
63 /** 63 /**
64 - * Notifies the core about the providers inability to assert the specified 64 + * Notifies the core about the result of a RoleRequest sent to a device.
65 - * mastership role on the device.
66 * 65 *
67 * @param deviceId identity of the device 66 * @param deviceId identity of the device
68 - * @param role mastership role that was asserted but failed 67 + * @param requested mastership role that was requested by the node
68 + * @param replied mastership role the switch accepted
69 */ 69 */
70 - void unableToAssertRole(DeviceId deviceId, MastershipRole role); 70 + void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response);
71 71
72 } 72 }
......
...@@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T ...@@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T
27 */ 27 */
28 public enum Type { 28 public enum Type {
29 29
30 + // Request has been forwarded to MASTER Node
30 /** 31 /**
31 * Signifies that a batch operation has been initiated. 32 * Signifies that a batch operation has been initiated.
32 */ 33 */
33 BATCH_OPERATION_REQUESTED, 34 BATCH_OPERATION_REQUESTED,
34 35
36 + // MASTER Node has pushed the batch down to the Device
37 + // (e.g., Received barrier reply)
35 /** 38 /**
36 * Signifies that a batch operation has completed. 39 * Signifies that a batch operation has completed.
37 */ 40 */
......
...@@ -25,29 +25,29 @@ import com.google.common.collect.Lists; ...@@ -25,29 +25,29 @@ import com.google.common.collect.Lists;
25 public class FlowRuleBatchRequest { 25 public class FlowRuleBatchRequest {
26 26
27 private final int batchId; 27 private final int batchId;
28 - private final List<FlowEntry> toAdd; 28 + private final List<FlowRule> toAdd;
29 - private final List<FlowEntry> toRemove; 29 + private final List<FlowRule> toRemove;
30 30
31 - public FlowRuleBatchRequest(int batchId, List<? extends FlowEntry> toAdd, List<? extends FlowEntry> toRemove) { 31 + public FlowRuleBatchRequest(int batchId, List<? extends FlowRule> toAdd, List<? extends FlowRule> toRemove) {
32 this.batchId = batchId; 32 this.batchId = batchId;
33 this.toAdd = Collections.unmodifiableList(toAdd); 33 this.toAdd = Collections.unmodifiableList(toAdd);
34 this.toRemove = Collections.unmodifiableList(toRemove); 34 this.toRemove = Collections.unmodifiableList(toRemove);
35 } 35 }
36 36
37 - public List<FlowEntry> toAdd() { 37 + public List<FlowRule> toAdd() {
38 return toAdd; 38 return toAdd;
39 } 39 }
40 40
41 - public List<FlowEntry> toRemove() { 41 + public List<FlowRule> toRemove() {
42 return toRemove; 42 return toRemove;
43 } 43 }
44 44
45 public FlowRuleBatchOperation asBatchOperation() { 45 public FlowRuleBatchOperation asBatchOperation() {
46 List<FlowRuleBatchEntry> entries = Lists.newArrayList(); 46 List<FlowRuleBatchEntry> entries = Lists.newArrayList();
47 - for (FlowEntry e : toAdd) { 47 + for (FlowRule e : toAdd) {
48 entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e)); 48 entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e));
49 } 49 }
50 - for (FlowEntry e : toRemove) { 50 + for (FlowRule e : toRemove) {
51 entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e)); 51 entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e));
52 } 52 }
53 return new FlowRuleBatchOperation(entries); 53 return new FlowRuleBatchOperation(entries);
......
...@@ -200,7 +200,7 @@ public final class Instructions { ...@@ -200,7 +200,7 @@ public final class Instructions {
200 } 200 }
201 if (obj instanceof OutputInstruction) { 201 if (obj instanceof OutputInstruction) {
202 OutputInstruction that = (OutputInstruction) obj; 202 OutputInstruction that = (OutputInstruction) obj;
203 - Objects.equals(port, that.port); 203 + return Objects.equals(port, that.port);
204 204
205 } 205 }
206 return false; 206 return false;
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.net.resource; 16 package org.onlab.onos.net.resource;
17 17
18 +import com.google.common.base.MoreObjects;
19 +
18 /** 20 /**
19 * Representation of allocated bandwidth resource. 21 * Representation of allocated bandwidth resource.
20 */ 22 */
...@@ -35,4 +37,11 @@ public class BandwidthResourceAllocation extends BandwidthResourceRequest ...@@ -35,4 +37,11 @@ public class BandwidthResourceAllocation extends BandwidthResourceRequest
35 public BandwidthResourceAllocation(Bandwidth bandwidth) { 37 public BandwidthResourceAllocation(Bandwidth bandwidth) {
36 super(bandwidth); 38 super(bandwidth);
37 } 39 }
40 +
41 + @Override
42 + public String toString() {
43 + return MoreObjects.toStringHelper(this)
44 + .add("bandwidth", bandwidth())
45 + .toString();
46 + }
38 } 47 }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.net.resource; 16 package org.onlab.onos.net.resource;
17 17
18 +import com.google.common.base.MoreObjects;
19 +
18 /** 20 /**
19 * Representation of a request for bandwidth resource. 21 * Representation of a request for bandwidth resource.
20 */ 22 */
...@@ -53,4 +55,11 @@ public class BandwidthResourceRequest implements ResourceRequest { ...@@ -53,4 +55,11 @@ public class BandwidthResourceRequest implements ResourceRequest {
53 public ResourceType type() { 55 public ResourceType type() {
54 return ResourceType.BANDWIDTH; 56 return ResourceType.BANDWIDTH;
55 } 57 }
58 +
59 + @Override
60 + public String toString() {
61 + return MoreObjects.toStringHelper(this)
62 + .add("bandwidth", bandwidth)
63 + .toString();
64 + }
56 } 65 }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.net.resource; 16 package org.onlab.onos.net.resource;
17 17
18 +import com.google.common.base.MoreObjects;
19 +
18 import java.util.Objects; 20 import java.util.Objects;
19 21
20 /** 22 /**
...@@ -64,4 +66,11 @@ public class LambdaResourceAllocation extends LambdaResourceRequest ...@@ -64,4 +66,11 @@ public class LambdaResourceAllocation extends LambdaResourceRequest
64 final LambdaResourceAllocation other = (LambdaResourceAllocation) obj; 66 final LambdaResourceAllocation other = (LambdaResourceAllocation) obj;
65 return Objects.equals(this.lambda, other.lambda); 67 return Objects.equals(this.lambda, other.lambda);
66 } 68 }
69 +
70 + @Override
71 + public String toString() {
72 + return MoreObjects.toStringHelper(this)
73 + .add("lambda", lambda)
74 + .toString();
75 + }
67 } 76 }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onlab.onos.net.resource; 16 package org.onlab.onos.net.resource;
17 17
18 +import com.google.common.base.MoreObjects;
19 +
18 /** 20 /**
19 * Representation of a request for lambda resource. 21 * Representation of a request for lambda resource.
20 */ 22 */
...@@ -25,4 +27,9 @@ public class LambdaResourceRequest implements ResourceRequest { ...@@ -25,4 +27,9 @@ public class LambdaResourceRequest implements ResourceRequest {
25 return ResourceType.LAMBDA; 27 return ResourceType.LAMBDA;
26 } 28 }
27 29
30 + @Override
31 + public String toString() {
32 + return MoreObjects.toStringHelper(this)
33 + .toString();
34 + }
28 } 35 }
......
...@@ -17,6 +17,7 @@ package org.onlab.onos.net.device.impl; ...@@ -17,6 +17,7 @@ package org.onlab.onos.net.device.impl;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED; 19 import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED;
20 +import static org.onlab.onos.net.MastershipRole.*;
20 import static org.slf4j.LoggerFactory.getLogger; 21 import static org.slf4j.LoggerFactory.getLogger;
21 22
22 import java.util.List; 23 import java.util.List;
...@@ -29,7 +30,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -29,7 +30,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
29 import org.apache.felix.scr.annotations.Service; 30 import org.apache.felix.scr.annotations.Service;
30 import org.onlab.onos.cluster.ClusterService; 31 import org.onlab.onos.cluster.ClusterService;
31 import org.onlab.onos.cluster.NodeId; 32 import org.onlab.onos.cluster.NodeId;
32 -import org.onlab.onos.cluster.RoleInfo;
33 import org.onlab.onos.event.AbstractListenerRegistry; 33 import org.onlab.onos.event.AbstractListenerRegistry;
34 import org.onlab.onos.event.EventDeliveryService; 34 import org.onlab.onos.event.EventDeliveryService;
35 import org.onlab.onos.mastership.MastershipEvent; 35 import org.onlab.onos.mastership.MastershipEvent;
...@@ -59,8 +59,6 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry; ...@@ -59,8 +59,6 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry;
59 import org.onlab.onos.net.provider.AbstractProviderService; 59 import org.onlab.onos.net.provider.AbstractProviderService;
60 import org.slf4j.Logger; 60 import org.slf4j.Logger;
61 61
62 -import com.google.common.collect.HashMultimap;
63 -
64 /** 62 /**
65 * Provides implementation of the device SB &amp; NB APIs. 63 * Provides implementation of the device SB &amp; NB APIs.
66 */ 64 */
...@@ -160,39 +158,15 @@ public class DeviceManager ...@@ -160,39 +158,15 @@ public class DeviceManager
160 return store.isAvailable(deviceId); 158 return store.isAvailable(deviceId);
161 } 159 }
162 160
163 - // Applies the specified role to the device; ignores NONE
164 - private void applyRole(DeviceId deviceId, MastershipRole newRole) {
165 - if (newRole.equals(MastershipRole.NONE)) {
166 - return;
167 - }
168 -
169 - Device device = store.getDevice(deviceId);
170 - // FIXME: Device might not be there yet. (eventual consistent)
171 - if (device == null) {
172 - return;
173 - }
174 -
175 - DeviceProvider provider = getProvider(device.providerId());
176 - if (provider != null) {
177 - provider.roleChanged(device, newRole);
178 - // only trigger event when request was sent to provider
179 - // TODO: consider removing this from Device event type?
180 - post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device));
181 -
182 - if (newRole.equals(MastershipRole.MASTER)) {
183 - provider.triggerProbe(device);
184 - }
185 - }
186 - }
187 -
188 // Check a device for control channel connectivity. 161 // Check a device for control channel connectivity.
189 - private boolean isReachable(Device device) { 162 + private boolean isReachable(DeviceId deviceId) {
190 - // FIXME: Device might not be there yet. (eventual consistent) 163 + DeviceProvider provider = getProvider(deviceId);
191 - if (device == null) { 164 + if (provider != null) {
165 + return provider.isReachable(deviceId);
166 + } else {
167 + log.error("Provider not found for {}", deviceId);
192 return false; 168 return false;
193 } 169 }
194 - DeviceProvider provider = getProvider(device.providerId());
195 - return provider.isReachable(device);
196 } 170 }
197 171
198 @Override 172 @Override
...@@ -234,6 +208,32 @@ public class DeviceManager ...@@ -234,6 +208,32 @@ public class DeviceManager
234 super(provider); 208 super(provider);
235 } 209 }
236 210
211 + /**
212 + * Apply role in reaction to provider event.
213 + *
214 + * @param deviceId device identifier
215 + * @param newRole new role to apply to the device
216 + * @return true if the request was sent to provider
217 + */
218 + private boolean applyRole(DeviceId deviceId, MastershipRole newRole) {
219 +
220 + if (newRole.equals(MastershipRole.NONE)) {
221 + //no-op
222 + return true;
223 + }
224 +
225 + DeviceProvider provider = provider();
226 + if (provider == null) {
227 + log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole);
228 + return false;
229 + }
230 + provider.roleChanged(deviceId, newRole);
231 + // not triggering probe when triggered by provider service event
232 +
233 + return true;
234 + }
235 +
236 +
237 @Override 237 @Override
238 public void deviceConnected(DeviceId deviceId, 238 public void deviceConnected(DeviceId deviceId,
239 DeviceDescription deviceDescription) { 239 DeviceDescription deviceDescription) {
...@@ -242,26 +242,19 @@ public class DeviceManager ...@@ -242,26 +242,19 @@ public class DeviceManager
242 checkValidity(); 242 checkValidity();
243 243
244 log.info("Device {} connected", deviceId); 244 log.info("Device {} connected", deviceId);
245 - // check my Role
246 - MastershipRole role = mastershipService.requestRoleFor(deviceId);
247 - if (role != MastershipRole.MASTER) {
248 - // TODO: Do we need to explicitly tell the Provider that
249 - // this instance is no longer the MASTER? probably not
250 -// Device device = getDevice(deviceId);
251 -// if (device != null) {
252 -// // FIXME roleChanged should take DeviceId instead of Device
253 -// provider().roleChanged(device, role);
254 -// }
255 - return;
256 - }
257 - MastershipTerm term = termService.getMastershipTerm(deviceId);
258 -
259 final NodeId myNodeId = clusterService.getLocalNode().id(); 245 final NodeId myNodeId = clusterService.getLocalNode().id();
246 +
247 + // check my Role
248 + mastershipService.requestRoleFor(deviceId);
249 + final MastershipTerm term = termService.getMastershipTerm(deviceId);
260 if (!myNodeId.equals(term.master())) { 250 if (!myNodeId.equals(term.master())) {
261 - // lost mastership after requestRole told this instance was MASTER. 251 + log.info("Role of this node is STANDBY for {}", deviceId);
262 - log.info("lost mastership before getting term info."); 252 + // TODO: Do we need to explicitly tell the Provider that
253 + // this instance is not the MASTER
254 + applyRole(deviceId, MastershipRole.STANDBY);
263 return; 255 return;
264 } 256 }
257 + log.info("Role of this node is MASTER for {}", deviceId);
265 258
266 // tell clock provider if this instance is the master 259 // tell clock provider if this instance is the master
267 deviceClockProviderService.setMastershipTerm(deviceId, term); 260 deviceClockProviderService.setMastershipTerm(deviceId, term);
...@@ -269,24 +262,15 @@ public class DeviceManager ...@@ -269,24 +262,15 @@ public class DeviceManager
269 DeviceEvent event = store.createOrUpdateDevice(provider().id(), 262 DeviceEvent event = store.createOrUpdateDevice(provider().id(),
270 deviceId, deviceDescription); 263 deviceId, deviceDescription);
271 264
265 + applyRole(deviceId, MastershipRole.MASTER);
266 +
272 // If there was a change of any kind, tell the provider 267 // If there was a change of any kind, tell the provider
273 // that this instance is the master. 268 // that this instance is the master.
274 - // Note: event can be null, if mastership was lost between
275 - // roleRequest and store update calls.
276 if (event != null) { 269 if (event != null) {
277 - // TODO: Check switch reconnected case. Is it assured that 270 + log.trace("event: {} {}", event.type(), event);
278 - // event will never be null?
279 - // Could there be a situation MastershipService told this
280 - // instance is the new Master, but
281 - // event returned from the store is null?
282 -
283 - // FIXME: 1st argument should be deviceId, to allow setting
284 - // certain roles even if the store returned null.
285 - log.info("event: {} {}", event.type(), event);
286 - provider().roleChanged(event.subject(), role);
287 post(event); 271 post(event);
288 } else { 272 } else {
289 - log.info("No event to publish"); 273 + post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, store.getDevice(deviceId)));
290 } 274 }
291 } 275 }
292 276
...@@ -295,6 +279,7 @@ public class DeviceManager ...@@ -295,6 +279,7 @@ public class DeviceManager
295 checkNotNull(deviceId, DEVICE_ID_NULL); 279 checkNotNull(deviceId, DEVICE_ID_NULL);
296 checkValidity(); 280 checkValidity();
297 281
282 + log.info("Device {} disconnected from this node", deviceId);
298 283
299 DeviceEvent event = null; 284 DeviceEvent event = null;
300 try { 285 try {
...@@ -318,18 +303,18 @@ public class DeviceManager ...@@ -318,18 +303,18 @@ public class DeviceManager
318 final NodeId myNodeId = clusterService.getLocalNode().id(); 303 final NodeId myNodeId = clusterService.getLocalNode().id();
319 // TODO: Move this type of check inside device clock manager, etc. 304 // TODO: Move this type of check inside device clock manager, etc.
320 if (myNodeId.equals(term.master())) { 305 if (myNodeId.equals(term.master())) {
321 - log.info("Marking {} offline", deviceId); 306 + log.info("Retry marking {} offline", deviceId);
322 deviceClockProviderService.setMastershipTerm(deviceId, term); 307 deviceClockProviderService.setMastershipTerm(deviceId, term);
323 event = store.markOffline(deviceId); 308 event = store.markOffline(deviceId);
324 } else { 309 } else {
325 - log.error("Failed again marking {} offline. {}", deviceId, role); 310 + log.info("Failed again marking {} offline. {}", deviceId, role);
326 } 311 }
327 } finally { 312 } finally {
328 //relinquish master role and ability to be backup. 313 //relinquish master role and ability to be backup.
329 mastershipService.relinquishMastership(deviceId); 314 mastershipService.relinquishMastership(deviceId);
330 315
331 if (event != null) { 316 if (event != null) {
332 - log.info("Device {} disconnected", deviceId); 317 + log.info("Device {} disconnected from cluster", deviceId);
333 post(event); 318 post(event);
334 } 319 }
335 } 320 }
...@@ -343,6 +328,13 @@ public class DeviceManager ...@@ -343,6 +328,13 @@ public class DeviceManager
343 "Port descriptions list cannot be null"); 328 "Port descriptions list cannot be null");
344 checkValidity(); 329 checkValidity();
345 330
331 + if (!deviceClockProviderService.isTimestampAvailable(deviceId)) {
332 + // Never been a master for this device
333 + // any update will be ignored.
334 + log.trace("Ignoring {} port updates on standby node. {}", deviceId, portDescriptions);
335 + return;
336 + }
337 +
346 List<DeviceEvent> events = store.updatePorts(this.provider().id(), 338 List<DeviceEvent> events = store.updatePorts(this.provider().id(),
347 deviceId, portDescriptions); 339 deviceId, portDescriptions);
348 for (DeviceEvent event : events) { 340 for (DeviceEvent event : events) {
...@@ -357,6 +349,13 @@ public class DeviceManager ...@@ -357,6 +349,13 @@ public class DeviceManager
357 checkNotNull(portDescription, PORT_DESCRIPTION_NULL); 349 checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
358 checkValidity(); 350 checkValidity();
359 351
352 + if (!deviceClockProviderService.isTimestampAvailable(deviceId)) {
353 + // Never been a master for this device
354 + // any update will be ignored.
355 + log.trace("Ignoring {} port update on standby node. {}", deviceId, portDescription);
356 + return;
357 + }
358 +
360 final DeviceEvent event = store.updatePortStatus(this.provider().id(), 359 final DeviceEvent event = store.updatePortStatus(this.provider().id(),
361 deviceId, portDescription); 360 deviceId, portDescription);
362 if (event != null) { 361 if (event != null) {
...@@ -367,17 +366,49 @@ public class DeviceManager ...@@ -367,17 +366,49 @@ public class DeviceManager
367 } 366 }
368 367
369 @Override 368 @Override
370 - public void unableToAssertRole(DeviceId deviceId, MastershipRole role) { 369 + public void receivedRoleReply(
370 + DeviceId deviceId, MastershipRole requested, MastershipRole response) {
371 + // Several things can happen here:
372 + // 1. request and response match
373 + // 2. request and response don't match
374 + // 3. MastershipRole and requested match (and 1 or 2 are true)
375 + // 4. MastershipRole and requested don't match (and 1 or 2 are true)
376 + //
377 + // 2, 4, and 3 with case 2 are failure modes.
378 +
371 // FIXME: implement response to this notification 379 // FIXME: implement response to this notification
372 - log.warn("Failed to assert role [{}] onto Device {}", role, 380 +
373 - deviceId); 381 + log.info("got reply to a role request for {}: asked for {}, and got {}",
374 - if (role == MastershipRole.MASTER) { 382 + deviceId, requested, response);
383 +
384 + if (requested == null && response == null) {
385 + // something was off with DeviceProvider, maybe check channel too?
386 + log.warn("Failed to assert role [{}] onto Device {}", requested, deviceId);
387 + mastershipService.relinquishMastership(deviceId);
388 + return;
389 + }
390 +
391 + if (requested.equals(response)) {
392 + if (requested.equals(mastershipService.getLocalRole(deviceId))) {
393 +
394 + return;
395 + } else {
396 + return;
397 + // FIXME roleManager got the device to comply, but doesn't agree with
398 + // the store; use the store's view, then try to reassert.
399 + }
400 + } else {
401 + // we didn't get back what we asked for. Reelect someone else.
402 + log.warn("Failed to assert role [{}] onto Device {}", response, deviceId);
403 + if (response == MastershipRole.MASTER) {
375 mastershipService.relinquishMastership(deviceId); 404 mastershipService.relinquishMastership(deviceId);
376 // TODO: Shouldn't we be triggering event? 405 // TODO: Shouldn't we be triggering event?
377 //final Device device = getDevice(deviceId); 406 //final Device device = getDevice(deviceId);
378 //post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device)); 407 //post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device));
379 } 408 }
380 } 409 }
410 +
411 + }
381 } 412 }
382 413
383 // Posts the specified event to the local event dispatcher. 414 // Posts the specified event to the local event dispatcher.
...@@ -390,118 +421,134 @@ public class DeviceManager ...@@ -390,118 +421,134 @@ public class DeviceManager
390 // Intercepts mastership events 421 // Intercepts mastership events
391 private class InternalMastershipListener implements MastershipListener { 422 private class InternalMastershipListener implements MastershipListener {
392 423
393 - // random cache size 424 + // Applies the specified role to the device; ignores NONE
394 - private final int cacheSize = 5; 425 + /**
395 - // temporarily stores term number + events to check for duplicates. A hack. 426 + * Apply role in reaction to mastership event.
396 - private HashMultimap<Integer, RoleInfo> eventCache = 427 + *
397 - HashMultimap.create(); 428 + * @param deviceId device identifier
429 + * @param newRole new role to apply to the device
430 + * @return true if the request was sent to provider
431 + */
432 + private boolean applyRole(DeviceId deviceId, MastershipRole newRole) {
433 + if (newRole.equals(MastershipRole.NONE)) {
434 + //no-op
435 + return true;
436 + }
398 437
399 - @Override 438 + Device device = store.getDevice(deviceId);
400 - public void event(MastershipEvent event) { 439 + // FIXME: Device might not be there yet. (eventual consistent)
401 - final DeviceId did = event.subject(); 440 + // FIXME relinquish role
402 - final NodeId myNodeId = clusterService.getLocalNode().id(); 441 + if (device == null) {
442 + log.warn("{} was not there. Cannot apply role {}", deviceId, newRole);
443 + return false;
444 + }
403 445
404 - if (myNodeId.equals(event.roleInfo().master())) { 446 + DeviceProvider provider = getProvider(device.providerId());
405 - MastershipTerm term = termService.getMastershipTerm(did); 447 + if (provider == null) {
448 + log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole);
449 + return false;
450 + }
451 + provider.roleChanged(deviceId, newRole);
406 452
407 - // TODO duplicate suppression should probably occur in the MastershipManager 453 + if (newRole.equals(MastershipRole.MASTER)) {
408 - // itself, so listeners that can't deal with duplicates don't have to 454 + // only trigger event when request was sent to provider
409 - // so this check themselves. 455 + // TODO: consider removing this from Device event type?
410 -// if (checkDuplicate(event.roleInfo(), term.termNumber())) { 456 + post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device));
411 -// return;
412 -// }
413 457
414 - if (!myNodeId.equals(term.master())) { 458 + provider.triggerProbe(device);
415 - // something went wrong in consistency, let go 459 + }
416 - log.warn("Mastership has changed after this event." 460 + return true;
417 - + "Term Service suggests {} for {}", term, did);
418 - // FIXME: Is it possible to let go of MASTER role
419 - // but remain on STANDBY list?
420 - mastershipService.relinquishMastership(did);
421 - applyRole(did, MastershipRole.STANDBY);
422 - return;
423 } 461 }
424 462
425 - // only set the new term if I am the master 463 + @Override
426 - deviceClockProviderService.setMastershipTerm(did, term); 464 + public void event(MastershipEvent event) {
427 465
428 - // if the device is null here, we are the first master to claim the 466 + if (event.type() != MastershipEvent.Type.MASTER_CHANGED) {
429 - // device. No worries, the DeviceManager will create one soon. 467 + // Don't care if backup list changed.
430 - Device device = getDevice(did);
431 - if ((device != null) && !isAvailable(did)) {
432 - if (!isReachable(device)) {
433 - log.warn("Device {} has disconnected after this event", did);
434 - mastershipService.relinquishMastership(did);
435 return; 468 return;
436 } 469 }
437 - //flag the device as online. Is there a better way to do this? 470 +
438 - DeviceEvent devEvent = 471 + final DeviceId did = event.subject();
439 - store.createOrUpdateDevice(device.providerId(), did, 472 + final NodeId myNodeId = clusterService.getLocalNode().id();
440 - new DefaultDeviceDescription( 473 +
441 - did.uri(), device.type(), device.manufacturer(), 474 + // myRole suggested by MastershipService
442 - device.hwVersion(), device.swVersion(), 475 + MastershipRole myNextRole;
443 - device.serialNumber(), device.chassisId())); 476 + if (myNodeId.equals(event.roleInfo().master())) {
444 - post(devEvent); 477 + // confirm latest info
478 + MastershipTerm term = termService.getMastershipTerm(did);
479 + final boolean iHaveControl = myNodeId.equals(term.master());
480 + if (iHaveControl) {
481 + deviceClockProviderService.setMastershipTerm(did, term);
482 + myNextRole = MASTER;
483 + } else {
484 + myNextRole = STANDBY;
445 } 485 }
446 - applyRole(did, MastershipRole.MASTER);
447 } else if (event.roleInfo().backups().contains(myNodeId)) { 486 } else if (event.roleInfo().backups().contains(myNodeId)) {
448 - if (!isReachable(getDevice(did))) { 487 + myNextRole = STANDBY;
449 - log.warn("Device {} has disconnected after this event", did); 488 + } else {
489 + myNextRole = NONE;
490 + }
491 +
492 +
493 + final boolean isReachable = isReachable(did);
494 + if (!isReachable) {
495 + // device is not connected to this node
496 + if (myNextRole != NONE) {
497 + log.warn("Node was instructed to be {} role for {}, "
498 + + "but this node cannot reach the device. "
499 + + "Relinquishing role. ",
500 + myNextRole, did);
450 mastershipService.relinquishMastership(did); 501 mastershipService.relinquishMastership(did);
451 - return; 502 + // FIXME disconnect?
452 } 503 }
453 - applyRole(did, MastershipRole.STANDBY);
454 - } else {
455 - // Event suggests that this Node has no connection to this Device
456 - // confirm.
457 - final Device device = getDevice(did);
458 - if (!isReachable(device)) {
459 - // not connection to device, as expected
460 return; 504 return;
461 } 505 }
462 - // connection seems to exist 506 +
463 - log.info("Detected mastership info mismatch, requesting Role"); 507 + // device is connected to this node:
508 +
509 + if (myNextRole == NONE) {
464 mastershipService.requestRoleFor(did); 510 mastershipService.requestRoleFor(did);
465 - final MastershipTerm term = termService.getMastershipTerm(did); 511 + MastershipTerm term = termService.getMastershipTerm(did);
466 if (myNodeId.equals(term.master())) { 512 if (myNodeId.equals(term.master())) {
467 - // became MASTER 513 + myNextRole = MASTER;
468 - // TODO: consider slicing out method for applying MASTER role 514 + } else {
469 - deviceClockProviderService.setMastershipTerm(did, term); 515 + myNextRole = STANDBY;
516 + }
517 + }
470 518
519 + switch (myNextRole) {
520 + case MASTER:
521 + final Device device = getDevice(did);
522 + if ((device != null) && !isAvailable(did)) {
471 //flag the device as online. Is there a better way to do this? 523 //flag the device as online. Is there a better way to do this?
524 + DefaultDeviceDescription deviceDescription
525 + = new DefaultDeviceDescription(did.uri(),
526 + device.type(),
527 + device.manufacturer(),
528 + device.hwVersion(),
529 + device.swVersion(),
530 + device.serialNumber(),
531 + device.chassisId());
472 DeviceEvent devEvent = 532 DeviceEvent devEvent =
473 store.createOrUpdateDevice(device.providerId(), did, 533 store.createOrUpdateDevice(device.providerId(), did,
474 - new DefaultDeviceDescription( 534 + deviceDescription);
475 - did.uri(), device.type(), device.manufacturer(),
476 - device.hwVersion(), device.swVersion(),
477 - device.serialNumber(), device.chassisId()));
478 - applyRole(did, MastershipRole.MASTER);
479 post(devEvent); 535 post(devEvent);
480 - } else {
481 - applyRole(did, MastershipRole.STANDBY);
482 } 536 }
537 + // TODO: should apply role only if there is mismatch
538 + log.info("Applying role {} to {}", myNextRole, did);
539 + applyRole(did, MASTER);
540 + break;
541 + case STANDBY:
542 + log.info("Applying role {} to {}", myNextRole, did);
543 + applyRole(did, STANDBY);
544 + break;
545 + case NONE:
546 + default:
547 + // should never reach here
548 + log.error("You didn't see anything. I did not exist.");
549 + break;
483 } 550 }
484 } 551 }
485 -
486 - // checks for duplicate event, returning true if one is found.
487 - private boolean checkDuplicate(RoleInfo roleInfo, int term) {
488 - // turning off duplicate check
489 - return false;
490 -// synchronized (eventCache) {
491 -// if (eventCache.get(term).contains(roleInfo)) {
492 -// log.info("duplicate event detected; ignoring");
493 -// return true;
494 -// } else {
495 -// eventCache.put(term, roleInfo);
496 -// // purge by-term oldest entries to keep the cache size under limit
497 -// if (eventCache.size() > cacheSize) {
498 -// eventCache.removeAll(term - cacheSize);
499 -// }
500 -// return false;
501 -// }
502 -// }
503 - }
504 -
505 } 552 }
506 553
507 // Store delegate to re-post events emitted from the store. 554 // Store delegate to re-post events emitted from the store.
......
...@@ -371,10 +371,11 @@ public class FlowRuleManager ...@@ -371,10 +371,11 @@ public class FlowRuleManager
371 final FlowRuleBatchRequest request = event.subject(); 371 final FlowRuleBatchRequest request = event.subject();
372 switch (event.type()) { 372 switch (event.type()) {
373 case BATCH_OPERATION_REQUESTED: 373 case BATCH_OPERATION_REQUESTED:
374 - for (FlowEntry entry : request.toAdd()) { 374 + // Request has been forwarded to MASTER Node, and was
375 + for (FlowRule entry : request.toAdd()) {
375 eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry)); 376 eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry));
376 } 377 }
377 - for (FlowEntry entry : request.toRemove()) { 378 + for (FlowRule entry : request.toRemove()) {
378 eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry)); 379 eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry));
379 } 380 }
380 // FIXME: what about op.equals(FlowRuleOperation.MODIFY) ? 381 // FIXME: what about op.equals(FlowRuleOperation.MODIFY) ?
...@@ -392,21 +393,15 @@ public class FlowRuleManager ...@@ -392,21 +393,15 @@ public class FlowRuleManager
392 Futures.getUnchecked(result))); 393 Futures.getUnchecked(result)));
393 } 394 }
394 }, futureListeners); 395 }, futureListeners);
395 -
396 break; 396 break;
397 +
397 case BATCH_OPERATION_COMPLETED: 398 case BATCH_OPERATION_COMPLETED:
398 - Set<FlowRule> failedItems = event.result().failedItems(); 399 + // MASTER Node has pushed the batch down to the Device
399 - for (FlowEntry entry : request.toAdd()) { 400 +
400 - if (!failedItems.contains(entry)) { 401 + // Note: RULE_ADDED will be posted
401 - eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED, entry)); 402 + // when Flow was actually confirmed by stats reply.
402 - }
403 - }
404 - for (FlowEntry entry : request.toRemove()) {
405 - if (!failedItems.contains(entry)) {
406 - eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVED, entry));
407 - }
408 - }
409 break; 403 break;
404 +
410 default: 405 default:
411 break; 406 break;
412 } 407 }
......
...@@ -67,6 +67,7 @@ public class HostMonitor implements TimerTask { ...@@ -67,6 +67,7 @@ public class HostMonitor implements TimerTask {
67 private final ConcurrentMap<ProviderId, HostProvider> hostProviders; 67 private final ConcurrentMap<ProviderId, HostProvider> hostProviders;
68 68
69 private static final long DEFAULT_PROBE_RATE = 30000; // milliseconds 69 private static final long DEFAULT_PROBE_RATE = 30000; // milliseconds
70 + private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
70 private long probeRate = DEFAULT_PROBE_RATE; 71 private long probeRate = DEFAULT_PROBE_RATE;
71 72
72 private Timeout timeout; 73 private Timeout timeout;
...@@ -215,15 +216,15 @@ public class HostMonitor implements TimerTask { ...@@ -215,15 +216,15 @@ public class HostMonitor implements TimerTask {
215 .setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH) 216 .setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH)
216 .setOpCode(ARP.OP_REQUEST); 217 .setOpCode(ARP.OP_REQUEST);
217 218
218 - arp.setSenderHardwareAddress(sourceMac.getAddress()) 219 + arp.setSenderHardwareAddress(sourceMac.toBytes())
219 .setSenderProtocolAddress(sourceIp.toOctets()) 220 .setSenderProtocolAddress(sourceIp.toOctets())
220 - .setTargetHardwareAddress(MacAddress.ZERO_MAC_ADDRESS) 221 + .setTargetHardwareAddress(ZERO_MAC_ADDRESS)
221 .setTargetProtocolAddress(targetIp.toOctets()); 222 .setTargetProtocolAddress(targetIp.toOctets());
222 223
223 Ethernet ethernet = new Ethernet(); 224 Ethernet ethernet = new Ethernet();
224 ethernet.setEtherType(Ethernet.TYPE_ARP) 225 ethernet.setEtherType(Ethernet.TYPE_ARP)
225 - .setDestinationMACAddress(MacAddress.BROADCAST_MAC) 226 + .setDestinationMACAddress(MacAddress.BROADCAST)
226 - .setSourceMACAddress(sourceMac.getAddress()) 227 + .setSourceMACAddress(sourceMac)
227 .setPayload(arp); 228 .setPayload(arp);
228 229
229 return ethernet; 230 return ethernet;
......
...@@ -132,7 +132,8 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -132,7 +132,8 @@ public class ProxyArpManager implements ProxyArpService {
132 // for one of our external addresses. 132 // for one of our external addresses.
133 if (isOutsidePort(inPort)) { 133 if (isOutsidePort(inPort)) {
134 IpAddress target = 134 IpAddress target =
135 - IpAddress.valueOf(arp.getTargetProtocolAddress()); 135 + IpAddress.valueOf(IpAddress.Version.INET,
136 + arp.getTargetProtocolAddress());
136 PortAddresses addresses = 137 PortAddresses addresses =
137 hostService.getAddressBindingsForPort(inPort); 138 hostService.getAddressBindingsForPort(inPort);
138 139
...@@ -149,7 +150,8 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -149,7 +150,8 @@ public class ProxyArpManager implements ProxyArpService {
149 // it could be a request from an internal host to an external 150 // it could be a request from an internal host to an external
150 // address. Forward it over to the correct port. 151 // address. Forward it over to the correct port.
151 IpAddress source = 152 IpAddress source =
152 - IpAddress.valueOf(arp.getSenderProtocolAddress()); 153 + IpAddress.valueOf(IpAddress.Version.INET,
154 + arp.getSenderProtocolAddress());
153 PortAddresses sourceAddresses = findPortInSubnet(source); 155 PortAddresses sourceAddresses = findPortInSubnet(source);
154 if (sourceAddresses != null) { 156 if (sourceAddresses != null) {
155 for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) { 157 for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) {
...@@ -164,8 +166,9 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -164,8 +166,9 @@ public class ProxyArpManager implements ProxyArpService {
164 // Continue with normal proxy ARP case 166 // Continue with normal proxy ARP case
165 167
166 VlanId vlan = VlanId.vlanId(eth.getVlanID()); 168 VlanId vlan = VlanId.vlanId(eth.getVlanID());
167 - Set<Host> hosts = hostService.getHostsByIp(IpAddress.valueOf(arp 169 + Set<Host> hosts =
168 - .getTargetProtocolAddress())); 170 + hostService.getHostsByIp(IpAddress.valueOf(IpAddress.Version.INET,
171 + arp.getTargetProtocolAddress()));
169 172
170 Host dst = null; 173 Host dst = null;
171 Host src = hostService.getHost(HostId.hostId(eth.getSourceMAC(), 174 Host src = hostService.getHost(HostId.hostId(eth.getSourceMAC(),
...@@ -357,8 +360,8 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -357,8 +360,8 @@ public class ProxyArpManager implements ProxyArpService {
357 Ethernet request) { 360 Ethernet request) {
358 361
359 Ethernet eth = new Ethernet(); 362 Ethernet eth = new Ethernet();
360 - eth.setDestinationMACAddress(request.getSourceMACAddress()); 363 + eth.setDestinationMACAddress(request.getSourceMAC());
361 - eth.setSourceMACAddress(srcMac.getAddress()); 364 + eth.setSourceMACAddress(srcMac);
362 eth.setEtherType(Ethernet.TYPE_ARP); 365 eth.setEtherType(Ethernet.TYPE_ARP);
363 eth.setVlanID(request.getVlanID()); 366 eth.setVlanID(request.getVlanID());
364 367
...@@ -369,7 +372,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -369,7 +372,7 @@ public class ProxyArpManager implements ProxyArpService {
369 372
370 arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH); 373 arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH);
371 arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH); 374 arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
372 - arp.setSenderHardwareAddress(srcMac.getAddress()); 375 + arp.setSenderHardwareAddress(srcMac.toBytes());
373 arp.setTargetHardwareAddress(request.getSourceMACAddress()); 376 arp.setTargetHardwareAddress(request.getSourceMACAddress());
374 377
375 arp.setTargetProtocolAddress(((ARP) request.getPayload()) 378 arp.setTargetProtocolAddress(((ARP) request.getPayload())
......
...@@ -15,11 +15,7 @@ ...@@ -15,11 +15,7 @@
15 */ 15 */
16 package org.onlab.onos.net.resource.impl; 16 package org.onlab.onos.net.resource.impl;
17 17
18 -import java.util.Collection; 18 +import com.google.common.base.MoreObjects;
19 -import java.util.Collections;
20 -import java.util.Map;
21 -import java.util.Set;
22 -
23 import org.onlab.onos.net.Link; 19 import org.onlab.onos.net.Link;
24 import org.onlab.onos.net.intent.IntentId; 20 import org.onlab.onos.net.intent.IntentId;
25 import org.onlab.onos.net.resource.LinkResourceAllocations; 21 import org.onlab.onos.net.resource.LinkResourceAllocations;
...@@ -28,6 +24,11 @@ import org.onlab.onos.net.resource.ResourceAllocation; ...@@ -28,6 +24,11 @@ import org.onlab.onos.net.resource.ResourceAllocation;
28 import org.onlab.onos.net.resource.ResourceRequest; 24 import org.onlab.onos.net.resource.ResourceRequest;
29 import org.onlab.onos.net.resource.ResourceType; 25 import org.onlab.onos.net.resource.ResourceType;
30 26
27 +import java.util.Collection;
28 +import java.util.Collections;
29 +import java.util.Map;
30 +import java.util.Set;
31 +
31 /** 32 /**
32 * Implementation of {@link LinkResourceAllocations}. 33 * Implementation of {@link LinkResourceAllocations}.
33 */ 34 */
...@@ -76,4 +77,10 @@ public class DefaultLinkResourceAllocations implements LinkResourceAllocations { ...@@ -76,4 +77,10 @@ public class DefaultLinkResourceAllocations implements LinkResourceAllocations {
76 return result; 77 return result;
77 } 78 }
78 79
80 + @Override
81 + public String toString() {
82 + return MoreObjects.toStringHelper(this)
83 + .add("allocations", allocations)
84 + .toString();
85 + }
79 } 86 }
......
...@@ -19,7 +19,6 @@ import com.google.common.collect.Sets; ...@@ -19,7 +19,6 @@ import com.google.common.collect.Sets;
19 19
20 import org.junit.After; 20 import org.junit.After;
21 import org.junit.Before; 21 import org.junit.Before;
22 -import org.junit.Ignore;
23 import org.junit.Test; 22 import org.junit.Test;
24 import org.onlab.onos.cluster.ClusterEventListener; 23 import org.onlab.onos.cluster.ClusterEventListener;
25 import org.onlab.onos.cluster.ClusterService; 24 import org.onlab.onos.cluster.ClusterService;
...@@ -181,16 +180,6 @@ public class DeviceManagerTest { ...@@ -181,16 +180,6 @@ public class DeviceManagerTest {
181 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1)); 180 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
182 } 181 }
183 182
184 - @Ignore("disabled until we settle the device-mastership wiring")
185 - @Test
186 - public void setRole() throws InterruptedException {
187 - connectDevice(DID1, SW1);
188 - validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
189 - assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
190 - assertEquals("incorrect device", DID1, provider.deviceReceived.id());
191 - assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
192 - }
193 -
194 @Test 183 @Test
195 public void updatePorts() { 184 public void updatePorts() {
196 connectDevice(DID1, SW1); 185 connectDevice(DID1, SW1);
...@@ -262,7 +251,7 @@ public class DeviceManagerTest { ...@@ -262,7 +251,7 @@ public class DeviceManagerTest {
262 251
263 252
264 private class TestProvider extends AbstractProvider implements DeviceProvider { 253 private class TestProvider extends AbstractProvider implements DeviceProvider {
265 - private Device deviceReceived; 254 + private DeviceId deviceReceived;
266 private MastershipRole roleReceived; 255 private MastershipRole roleReceived;
267 256
268 public TestProvider() { 257 public TestProvider() {
...@@ -274,13 +263,13 @@ public class DeviceManagerTest { ...@@ -274,13 +263,13 @@ public class DeviceManagerTest {
274 } 263 }
275 264
276 @Override 265 @Override
277 - public void roleChanged(Device device, MastershipRole newRole) { 266 + public void roleChanged(DeviceId device, MastershipRole newRole) {
278 deviceReceived = device; 267 deviceReceived = device;
279 roleReceived = newRole; 268 roleReceived = newRole;
280 } 269 }
281 270
282 @Override 271 @Override
283 - public boolean isReachable(Device device) { 272 + public boolean isReachable(DeviceId device) {
284 return false; 273 return false;
285 } 274 }
286 } 275 }
...@@ -360,9 +349,16 @@ public class DeviceManagerTest { ...@@ -360,9 +349,16 @@ public class DeviceManagerTest {
360 private final class TestClockProviderService implements 349 private final class TestClockProviderService implements
361 DeviceClockProviderService { 350 DeviceClockProviderService {
362 351
352 + private Set<DeviceId> registerdBefore = Sets.newConcurrentHashSet();
353 +
363 @Override 354 @Override
364 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) { 355 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
365 - // TODO Auto-generated method stub 356 + registerdBefore.add(deviceId);
357 + }
358 +
359 + @Override
360 + public boolean isTimestampAvailable(DeviceId deviceId) {
361 + return registerdBefore.contains(deviceId);
366 } 362 }
367 } 363 }
368 } 364 }
......
...@@ -148,7 +148,7 @@ public class FlowRuleManagerTest { ...@@ -148,7 +148,7 @@ public class FlowRuleManagerTest {
148 int i = 0; 148 int i = 0;
149 System.err.println("events :" + listener.events); 149 System.err.println("events :" + listener.events);
150 for (FlowRuleEvent e : listener.events) { 150 for (FlowRuleEvent e : listener.events) {
151 - assertTrue("unexpected event", e.type().equals(events[i])); 151 + assertEquals("unexpected event", events[i], e.type());
152 i++; 152 i++;
153 } 153 }
154 154
...@@ -178,15 +178,13 @@ public class FlowRuleManagerTest { ...@@ -178,15 +178,13 @@ public class FlowRuleManagerTest {
178 RULE_ADDED, RULE_ADDED); 178 RULE_ADDED, RULE_ADDED);
179 179
180 addFlowRule(1); 180 addFlowRule(1);
181 + System.err.println("events :" + listener.events);
181 assertEquals("should still be 2 rules", 2, flowCount()); 182 assertEquals("should still be 2 rules", 2, flowCount());
182 183
183 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1)); 184 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
184 validateEvents(RULE_UPDATED); 185 validateEvents(RULE_UPDATED);
185 } 186 }
186 187
187 -
188 - // TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
189 - //backing store is sensitive to the order of additions/removals
190 private boolean validateState(Map<FlowRule, FlowEntryState> expected) { 188 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
191 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); 189 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
192 Iterable<FlowEntry> rules = service.getFlowEntries(DID); 190 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
...@@ -539,17 +537,17 @@ public class FlowRuleManagerTest { ...@@ -539,17 +537,17 @@ public class FlowRuleManagerTest {
539 537
540 @Override 538 @Override
541 public boolean cancel(boolean mayInterruptIfRunning) { 539 public boolean cancel(boolean mayInterruptIfRunning) {
542 - return true; 540 + return false;
543 } 541 }
544 542
545 @Override 543 @Override
546 public boolean isCancelled() { 544 public boolean isCancelled() {
547 - return true; 545 + return false;
548 } 546 }
549 547
550 @Override 548 @Override
551 public boolean isDone() { 549 public boolean isDone() {
552 - return false; 550 + return true;
553 } 551 }
554 552
555 @Override 553 @Override
...@@ -562,12 +560,14 @@ public class FlowRuleManagerTest { ...@@ -562,12 +560,14 @@ public class FlowRuleManagerTest {
562 public CompletedBatchOperation get(long timeout, TimeUnit unit) 560 public CompletedBatchOperation get(long timeout, TimeUnit unit)
563 throws InterruptedException, 561 throws InterruptedException,
564 ExecutionException, TimeoutException { 562 ExecutionException, TimeoutException {
565 - return null; 563 + return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet());
566 } 564 }
567 565
568 @Override 566 @Override
569 public void addListener(Runnable task, Executor executor) { 567 public void addListener(Runnable task, Executor executor) {
570 - // TODO: add stuff. 568 + if (isDone()) {
569 + executor.execute(task);
570 + }
571 } 571 }
572 } 572 }
573 573
......
...@@ -20,11 +20,9 @@ import static org.easymock.EasyMock.expect; ...@@ -20,11 +20,9 @@ import static org.easymock.EasyMock.expect;
20 import static org.easymock.EasyMock.expectLastCall; 20 import static org.easymock.EasyMock.expectLastCall;
21 import static org.easymock.EasyMock.replay; 21 import static org.easymock.EasyMock.replay;
22 import static org.easymock.EasyMock.verify; 22 import static org.easymock.EasyMock.verify;
23 -import static org.junit.Assert.assertEquals; 23 +import static org.junit.Assert.*;
24 -import static org.junit.Assert.assertTrue;
25 24
26 import java.util.ArrayList; 25 import java.util.ArrayList;
27 -import java.util.Arrays;
28 import java.util.Collections; 26 import java.util.Collections;
29 import java.util.List; 27 import java.util.List;
30 import java.util.Set; 28 import java.util.Set;
...@@ -155,17 +153,20 @@ public class HostMonitorTest { ...@@ -155,17 +153,20 @@ public class HostMonitorTest {
155 Instruction instruction = packet.treatment().instructions().get(0); 153 Instruction instruction = packet.treatment().instructions().get(0);
156 assertTrue(instruction instanceof OutputInstruction); 154 assertTrue(instruction instanceof OutputInstruction);
157 OutputInstruction oi = (OutputInstruction) instruction; 155 OutputInstruction oi = (OutputInstruction) instruction;
158 - assertTrue(oi.port().equals(portNum)); 156 + assertEquals(portNum, oi.port());
159 157
160 // Check the output packet is correct (well the important bits anyway) 158 // Check the output packet is correct (well the important bits anyway)
161 Ethernet eth = new Ethernet(); 159 Ethernet eth = new Ethernet();
162 - eth.deserialize(packet.data().array(), 0, packet.data().array().length); 160 + final byte[] pktData = new byte[packet.data().remaining()];
161 + packet.data().get(pktData);
162 + eth.deserialize(pktData, 0, pktData.length);
163 ARP arp = (ARP) eth.getPayload(); 163 ARP arp = (ARP) eth.getPayload();
164 - assertTrue(Arrays.equals(arp.getSenderProtocolAddress(), 164 + assertArrayEquals(SOURCE_ADDR.toOctets(),
165 - SOURCE_ADDR.toOctets())); 165 + arp.getSenderProtocolAddress());
166 - assertTrue(Arrays.equals(arp.getSenderHardwareAddress(), sourceMac.toBytes())); 166 + assertArrayEquals(sourceMac.toBytes(),
167 - assertTrue(Arrays.equals(arp.getTargetProtocolAddress(), 167 + arp.getSenderHardwareAddress());
168 - TARGET_IP_ADDR.toOctets())); 168 + assertArrayEquals(TARGET_IP_ADDR.toOctets(),
169 + arp.getTargetProtocolAddress());
169 } 170 }
170 171
171 class TestPacketService implements PacketService { 172 class TestPacketService implements PacketService {
......
...@@ -19,12 +19,9 @@ import static org.easymock.EasyMock.anyObject; ...@@ -19,12 +19,9 @@ import static org.easymock.EasyMock.anyObject;
19 import static org.easymock.EasyMock.createMock; 19 import static org.easymock.EasyMock.createMock;
20 import static org.easymock.EasyMock.expect; 20 import static org.easymock.EasyMock.expect;
21 import static org.easymock.EasyMock.replay; 21 import static org.easymock.EasyMock.replay;
22 -import static org.junit.Assert.assertEquals; 22 +import static org.junit.Assert.*;
23 -import static org.junit.Assert.assertFalse;
24 -import static org.junit.Assert.assertTrue;
25 23
26 import java.util.ArrayList; 24 import java.util.ArrayList;
27 -import java.util.Arrays;
28 import java.util.Collections; 25 import java.util.Collections;
29 import java.util.Comparator; 26 import java.util.Comparator;
30 import java.util.List; 27 import java.util.List;
...@@ -91,6 +88,7 @@ public class ProxyArpManagerTest { ...@@ -91,6 +88,7 @@ public class ProxyArpManagerTest {
91 private static final PortNumber P1 = PortNumber.portNumber(1); 88 private static final PortNumber P1 = PortNumber.portNumber(1);
92 private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L); 89 private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
93 private static final HostLocation LOC2 = new HostLocation(DID2, P1, 123L); 90 private static final HostLocation LOC2 = new HostLocation(DID2, P1, 123L);
91 + private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
94 92
95 private ProxyArpManager proxyArp; 93 private ProxyArpManager proxyArp;
96 94
...@@ -483,7 +481,7 @@ public class ProxyArpManagerTest { ...@@ -483,7 +481,7 @@ public class ProxyArpManagerTest {
483 */ 481 */
484 private void verifyPacketOut(Ethernet expected, ConnectPoint outPort, 482 private void verifyPacketOut(Ethernet expected, ConnectPoint outPort,
485 OutboundPacket actual) { 483 OutboundPacket actual) {
486 - assertTrue(Arrays.equals(expected.serialize(), actual.data().array())); 484 + assertArrayEquals(expected.serialize(), actual.data().array());
487 assertEquals(1, actual.treatment().instructions().size()); 485 assertEquals(1, actual.treatment().instructions().size());
488 assertEquals(outPort.deviceId(), actual.sendThrough()); 486 assertEquals(outPort.deviceId(), actual.sendThrough());
489 Instruction instruction = actual.treatment().instructions().get(0); 487 Instruction instruction = actual.treatment().instructions().get(0);
...@@ -520,12 +518,12 @@ public class ProxyArpManagerTest { ...@@ -520,12 +518,12 @@ public class ProxyArpManagerTest {
520 Ethernet eth = new Ethernet(); 518 Ethernet eth = new Ethernet();
521 519
522 if (dstMac == null) { 520 if (dstMac == null) {
523 - eth.setDestinationMACAddress(MacAddress.BROADCAST_MAC); 521 + eth.setDestinationMACAddress(MacAddress.BROADCAST);
524 } else { 522 } else {
525 - eth.setDestinationMACAddress(dstMac.getAddress()); 523 + eth.setDestinationMACAddress(dstMac);
526 } 524 }
527 525
528 - eth.setSourceMACAddress(srcMac.getAddress()); 526 + eth.setSourceMACAddress(srcMac);
529 eth.setEtherType(Ethernet.TYPE_ARP); 527 eth.setEtherType(Ethernet.TYPE_ARP);
530 eth.setVlanID(VLAN1.toShort()); 528 eth.setVlanID(VLAN1.toShort());
531 529
...@@ -536,12 +534,12 @@ public class ProxyArpManagerTest { ...@@ -536,12 +534,12 @@ public class ProxyArpManagerTest {
536 534
537 arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH); 535 arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH);
538 arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH); 536 arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
539 - arp.setSenderHardwareAddress(srcMac.getAddress()); 537 + arp.setSenderHardwareAddress(srcMac.toBytes());
540 538
541 if (dstMac == null) { 539 if (dstMac == null) {
542 - arp.setTargetHardwareAddress(MacAddress.ZERO_MAC_ADDRESS); 540 + arp.setTargetHardwareAddress(ZERO_MAC_ADDRESS);
543 } else { 541 } else {
544 - arp.setTargetHardwareAddress(dstMac.getAddress()); 542 + arp.setTargetHardwareAddress(dstMac.toBytes());
545 } 543 }
546 544
547 arp.setSenderProtocolAddress(srcIp.toOctets()); 545 arp.setSenderProtocolAddress(srcIp.toOctets());
......
...@@ -147,8 +147,7 @@ public class DistributedClusterStore ...@@ -147,8 +147,7 @@ public class DistributedClusterStore
147 } 147 }
148 148
149 private IpAddress memberAddress(Member member) { 149 private IpAddress memberAddress(Member member) {
150 - byte[] address = member.getSocketAddress().getAddress().getAddress(); 150 + return IpAddress.valueOf(member.getSocketAddress().getAddress());
151 - return IpAddress.valueOf(address);
152 } 151 }
153 152
154 // Interceptor for membership events. 153 // Interceptor for membership events.
......
...@@ -85,7 +85,6 @@ public class ClusterCommunicationManager ...@@ -85,7 +85,6 @@ public class ClusterCommunicationManager
85 try { 85 try {
86 netty.activate(); 86 netty.activate();
87 } catch (Exception e) { 87 } catch (Exception e) {
88 - // TODO Auto-generated catch block
89 log.error("NettyMessagingService#activate", e); 88 log.error("NettyMessagingService#activate", e);
90 } 89 }
91 messagingService = netty; 90 messagingService = netty;
...@@ -95,6 +94,12 @@ public class ClusterCommunicationManager ...@@ -95,6 +94,12 @@ public class ClusterCommunicationManager
95 @Deactivate 94 @Deactivate
96 public void deactivate() { 95 public void deactivate() {
97 // TODO: cleanup messageingService if needed. 96 // TODO: cleanup messageingService if needed.
97 + // FIXME: workaround until it becomes a service.
98 + try {
99 + ((NettyMessagingService) messagingService).deactivate();
100 + } catch (Exception e) {
101 + log.error("NettyMessagingService#deactivate", e);
102 + }
98 log.info("Stopped"); 103 log.info("Stopped");
99 } 104 }
100 105
......
...@@ -72,4 +72,9 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid ...@@ -72,4 +72,9 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid
72 log.info("adding term info {} {}", deviceId, term.master()); 72 log.info("adding term info {} {}", deviceId, term.master());
73 deviceMastershipTerms.put(deviceId, term); 73 deviceMastershipTerms.put(deviceId, term);
74 } 74 }
75 +
76 + @Override
77 + public boolean isTimestampAvailable(DeviceId deviceId) {
78 + return deviceMastershipTerms.containsKey(deviceId);
79 + }
75 } 80 }
......
...@@ -1216,7 +1216,7 @@ public class GossipDeviceStore ...@@ -1216,7 +1216,7 @@ public class GossipDeviceStore
1216 @Override 1216 @Override
1217 public void handle(ClusterMessage message) { 1217 public void handle(ClusterMessage message) {
1218 1218
1219 - log.info("Received device update event from peer: {}", message.sender()); 1219 + log.debug("Received device update event from peer: {}", message.sender());
1220 InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload()); 1220 InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload());
1221 1221
1222 ProviderId providerId = event.providerId(); 1222 ProviderId providerId = event.providerId();
...@@ -1231,7 +1231,7 @@ public class GossipDeviceStore ...@@ -1231,7 +1231,7 @@ public class GossipDeviceStore
1231 @Override 1231 @Override
1232 public void handle(ClusterMessage message) { 1232 public void handle(ClusterMessage message) {
1233 1233
1234 - log.info("Received device offline event from peer: {}", message.sender()); 1234 + log.debug("Received device offline event from peer: {}", message.sender());
1235 InternalDeviceOfflineEvent event = (InternalDeviceOfflineEvent) SERIALIZER.decode(message.payload()); 1235 InternalDeviceOfflineEvent event = (InternalDeviceOfflineEvent) SERIALIZER.decode(message.payload());
1236 1236
1237 DeviceId deviceId = event.deviceId(); 1237 DeviceId deviceId = event.deviceId();
...@@ -1245,7 +1245,7 @@ public class GossipDeviceStore ...@@ -1245,7 +1245,7 @@ public class GossipDeviceStore
1245 @Override 1245 @Override
1246 public void handle(ClusterMessage message) { 1246 public void handle(ClusterMessage message) {
1247 1247
1248 - log.info("Received device removed event from peer: {}", message.sender()); 1248 + log.debug("Received device removed event from peer: {}", message.sender());
1249 InternalDeviceRemovedEvent event = (InternalDeviceRemovedEvent) SERIALIZER.decode(message.payload()); 1249 InternalDeviceRemovedEvent event = (InternalDeviceRemovedEvent) SERIALIZER.decode(message.payload());
1250 1250
1251 DeviceId deviceId = event.deviceId(); 1251 DeviceId deviceId = event.deviceId();
...@@ -1259,13 +1259,19 @@ public class GossipDeviceStore ...@@ -1259,13 +1259,19 @@ public class GossipDeviceStore
1259 @Override 1259 @Override
1260 public void handle(ClusterMessage message) { 1260 public void handle(ClusterMessage message) {
1261 1261
1262 - log.info("Received port update event from peer: {}", message.sender()); 1262 + log.debug("Received port update event from peer: {}", message.sender());
1263 InternalPortEvent event = (InternalPortEvent) SERIALIZER.decode(message.payload()); 1263 InternalPortEvent event = (InternalPortEvent) SERIALIZER.decode(message.payload());
1264 1264
1265 ProviderId providerId = event.providerId(); 1265 ProviderId providerId = event.providerId();
1266 DeviceId deviceId = event.deviceId(); 1266 DeviceId deviceId = event.deviceId();
1267 Timestamped<List<PortDescription>> portDescriptions = event.portDescriptions(); 1267 Timestamped<List<PortDescription>> portDescriptions = event.portDescriptions();
1268 1268
1269 + if (getDevice(deviceId) == null) {
1270 + log.info("{} not found on this node yet, ignoring.", deviceId);
1271 + // Note: dropped information will be recovered by anti-entropy
1272 + return;
1273 + }
1274 +
1269 notifyDelegate(updatePortsInternal(providerId, deviceId, portDescriptions)); 1275 notifyDelegate(updatePortsInternal(providerId, deviceId, portDescriptions));
1270 } 1276 }
1271 } 1277 }
...@@ -1274,14 +1280,19 @@ public class GossipDeviceStore ...@@ -1274,14 +1280,19 @@ public class GossipDeviceStore
1274 @Override 1280 @Override
1275 public void handle(ClusterMessage message) { 1281 public void handle(ClusterMessage message) {
1276 1282
1277 - log.info("Received port status update event from peer: {}", message.sender()); 1283 + log.debug("Received port status update event from peer: {}", message.sender());
1278 InternalPortStatusEvent event = (InternalPortStatusEvent) SERIALIZER.decode(message.payload()); 1284 InternalPortStatusEvent event = (InternalPortStatusEvent) SERIALIZER.decode(message.payload());
1279 - log.info("{}", event);
1280 1285
1281 ProviderId providerId = event.providerId(); 1286 ProviderId providerId = event.providerId();
1282 DeviceId deviceId = event.deviceId(); 1287 DeviceId deviceId = event.deviceId();
1283 Timestamped<PortDescription> portDescription = event.portDescription(); 1288 Timestamped<PortDescription> portDescription = event.portDescription();
1284 1289
1290 + if (getDevice(deviceId) == null) {
1291 + log.info("{} not found on this node yet, ignoring.", deviceId);
1292 + // Note: dropped information will be recovered by anti-entropy
1293 + return;
1294 + }
1295 +
1285 notifyDelegateIfNotNull(updatePortStatusInternal(providerId, deviceId, portDescription)); 1296 notifyDelegateIfNotNull(updatePortStatusInternal(providerId, deviceId, portDescription));
1286 } 1297 }
1287 } 1298 }
......
...@@ -36,7 +36,7 @@ public class ReplicaInfoEvent extends AbstractEvent<ReplicaInfoEvent.Type, Devic ...@@ -36,7 +36,7 @@ public class ReplicaInfoEvent extends AbstractEvent<ReplicaInfoEvent.Type, Devic
36 */ 36 */
37 MASTER_CHANGED, 37 MASTER_CHANGED,
38 // 38 //
39 - // BACKUPS_CHANGED? 39 + BACKUPS_CHANGED,
40 } 40 }
41 41
42 42
......
...@@ -284,9 +284,10 @@ public class DistributedFlowRuleStore ...@@ -284,9 +284,10 @@ public class DistributedFlowRuleStore
284 284
285 if (!replicaInfo.master().isPresent()) { 285 if (!replicaInfo.master().isPresent()) {
286 log.warn("No master for {}", deviceId); 286 log.warn("No master for {}", deviceId);
287 - // TODO: revisit if this should be returning empty collection. 287 + // TODO: revisit if this should be returning empty collection or throwing exception.
288 // FIXME: throw a FlowStoreException 288 // FIXME: throw a FlowStoreException
289 - throw new RuntimeException("No master for " + deviceId); 289 + //throw new RuntimeException("No master for " + deviceId);
290 + return Collections.emptyList();
290 } 291 }
291 292
292 if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) { 293 if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
......
...@@ -18,10 +18,9 @@ package org.onlab.onos.store.flow.impl; ...@@ -18,10 +18,9 @@ package org.onlab.onos.store.flow.impl;
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static org.slf4j.LoggerFactory.getLogger; 19 import static org.slf4j.LoggerFactory.getLogger;
20 import static org.onlab.onos.store.flow.ReplicaInfoEvent.Type.MASTER_CHANGED; 20 import static org.onlab.onos.store.flow.ReplicaInfoEvent.Type.MASTER_CHANGED;
21 +import static org.onlab.onos.store.flow.ReplicaInfoEvent.Type.BACKUPS_CHANGED;
21 22
22 import java.util.Collections; 23 import java.util.Collections;
23 -import java.util.List;
24 -
25 import org.apache.felix.scr.annotations.Activate; 24 import org.apache.felix.scr.annotations.Activate;
26 import org.apache.felix.scr.annotations.Component; 25 import org.apache.felix.scr.annotations.Component;
27 import org.apache.felix.scr.annotations.Deactivate; 26 import org.apache.felix.scr.annotations.Deactivate;
...@@ -96,12 +95,24 @@ public class ReplicaInfoManager implements ReplicaInfoService { ...@@ -96,12 +95,24 @@ public class ReplicaInfoManager implements ReplicaInfoService {
96 95
97 @Override 96 @Override
98 public void event(MastershipEvent event) { 97 public void event(MastershipEvent event) {
99 - // TODO: distinguish stby list update, when MastershipService, 98 + final ReplicaInfo replicaInfo
100 - // start publishing them 99 + = new ReplicaInfo(event.roleInfo().master(),
101 - final List<NodeId> standbyList = Collections.<NodeId>emptyList(); 100 + event.roleInfo().backups());
101 +
102 + switch (event.type()) {
103 + case MASTER_CHANGED:
102 eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED, 104 eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
103 event.subject(), 105 event.subject(),
104 - new ReplicaInfo(event.roleInfo().master(), standbyList))); 106 + replicaInfo));
107 + break;
108 + case BACKUPS_CHANGED:
109 + eventDispatcher.post(new ReplicaInfoEvent(BACKUPS_CHANGED,
110 + event.subject(),
111 + replicaInfo));
112 + break;
113 + default:
114 + break;
115 + }
105 } 116 }
106 } 117 }
107 118
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onlab.onos.store.mastership.impl; 16 package org.onlab.onos.store.mastership.impl;
17 17
18 import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED; 18 import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED;
19 +import static org.onlab.onos.mastership.MastershipEvent.Type.BACKUPS_CHANGED;
19 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent; 20 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent;
20 21
21 import java.util.HashSet; 22 import java.util.HashSet;
...@@ -43,6 +44,7 @@ import org.onlab.onos.store.serializers.KryoNamespaces; ...@@ -43,6 +44,7 @@ import org.onlab.onos.store.serializers.KryoNamespaces;
43 import org.onlab.onos.store.serializers.KryoSerializer; 44 import org.onlab.onos.store.serializers.KryoSerializer;
44 import org.onlab.util.KryoNamespace; 45 import org.onlab.util.KryoNamespace;
45 46
47 +import com.google.common.base.Objects;
46 import com.hazelcast.core.EntryEvent; 48 import com.hazelcast.core.EntryEvent;
47 import com.hazelcast.core.EntryListener; 49 import com.hazelcast.core.EntryListener;
48 import com.hazelcast.core.IAtomicLong; 50 import com.hazelcast.core.IAtomicLong;
...@@ -297,8 +299,7 @@ implements MastershipStore { ...@@ -297,8 +299,7 @@ implements MastershipStore {
297 case NONE: 299 case NONE:
298 rv.reassign(nodeId, NONE, STANDBY); 300 rv.reassign(nodeId, NONE, STANDBY);
299 roleMap.put(deviceId, rv); 301 roleMap.put(deviceId, rv);
300 - // TODO: BACKUPS_CHANGED? 302 + return new MastershipEvent(BACKUPS_CHANGED, deviceId, rv.roleInfo());
301 - return null;
302 default: 303 default:
303 log.warn("unknown Mastership Role {}", currentRole); 304 log.warn("unknown Mastership Role {}", currentRole);
304 } 305 }
...@@ -327,7 +328,8 @@ implements MastershipStore { ...@@ -327,7 +328,8 @@ implements MastershipStore {
327 roleMap.put(deviceId, rv); 328 roleMap.put(deviceId, rv);
328 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); 329 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
329 } else { 330 } else {
330 - // no master candidate 331 + // No master candidate - no more backups, device is likely
332 + // fully disconnected
331 roleMap.put(deviceId, rv); 333 roleMap.put(deviceId, rv);
332 // Should there be new event type? 334 // Should there be new event type?
333 return null; 335 return null;
...@@ -338,8 +340,7 @@ implements MastershipStore { ...@@ -338,8 +340,7 @@ implements MastershipStore {
338 boolean modified = rv.reassign(nodeId, STANDBY, NONE); 340 boolean modified = rv.reassign(nodeId, STANDBY, NONE);
339 if (modified) { 341 if (modified) {
340 roleMap.put(deviceId, rv); 342 roleMap.put(deviceId, rv);
341 - // TODO: BACKUPS_CHANGED? 343 + return new MastershipEvent(BACKUPS_CHANGED, deviceId, rv.roleInfo());
342 - return null;
343 } 344 }
344 return null; 345 return null;
345 default: 346 default:
...@@ -441,8 +442,24 @@ implements MastershipStore { ...@@ -441,8 +442,24 @@ implements MastershipStore {
441 442
442 @Override 443 @Override
443 public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) { 444 public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) {
445 + // compare old and current RoleValues. If master is different,
446 + // emit MASTER_CHANGED. else, emit BACKUPS_CHANGED.
447 + RoleValue oldValue = event.getOldValue();
448 + RoleValue newValue = event.getValue();
449 +
450 + NodeId oldMaster = null;
451 + if (oldValue != null) {
452 + oldMaster = oldValue.get(MASTER);
453 + }
454 + NodeId newMaster = newValue.get(MASTER);
455 +
456 + if (Objects.equal(oldMaster, newMaster)) {
444 notifyDelegate(new MastershipEvent( 457 notifyDelegate(new MastershipEvent(
445 MASTER_CHANGED, event.getKey(), event.getValue().roleInfo())); 458 MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
459 + } else {
460 + notifyDelegate(new MastershipEvent(
461 + BACKUPS_CHANGED, event.getKey(), event.getValue().roleInfo()));
462 + }
446 } 463 }
447 464
448 @Override 465 @Override
......
...@@ -55,6 +55,13 @@ final class RoleValue { ...@@ -55,6 +55,13 @@ final class RoleValue {
55 return value.get(type); 55 return value.get(type);
56 } 56 }
57 57
58 + /**
59 + * Returns the first node to match the MastershipRole, or if there
60 + * are none, null.
61 + *
62 + * @param type the role
63 + * @return a node ID or null
64 + */
58 public NodeId get(MastershipRole type) { 65 public NodeId get(MastershipRole type) {
59 return value.get(type).isEmpty() ? null : value.get(type).get(0); 66 return value.get(type).isEmpty() ? null : value.get(type).get(0);
60 } 67 }
......
...@@ -214,11 +214,11 @@ public class DistributedMastershipStoreTest { ...@@ -214,11 +214,11 @@ public class DistributedMastershipStoreTest {
214 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); 214 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size());
215 215
216 //If STANDBY, should drop to NONE 216 //If STANDBY, should drop to NONE
217 - assertNull("wrong event:", dms.relinquishRole(N1, DID1)); 217 + assertEquals("wrong event:", Type.BACKUPS_CHANGED, dms.relinquishRole(N1, DID1).type());
218 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1)); 218 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
219 219
220 //NONE - nothing happens 220 //NONE - nothing happens
221 - assertNull("wrong event:", dms.relinquishRole(N1, DID2)); 221 + assertEquals("wrong event:", Type.BACKUPS_CHANGED, dms.relinquishRole(N1, DID2).type());
222 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); 222 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
223 223
224 } 224 }
......
...@@ -46,7 +46,13 @@ public class IpAddressSerializer extends Serializer<IpAddress> { ...@@ -46,7 +46,13 @@ public class IpAddressSerializer extends Serializer<IpAddress> {
46 final int octLen = input.readInt(); 46 final int octLen = input.readInt();
47 byte[] octs = new byte[octLen]; 47 byte[] octs = new byte[octLen];
48 input.readBytes(octs); 48 input.readBytes(octs);
49 - return IpAddress.valueOf(octs); 49 + // Use the address size to decide whether it is IPv4 or IPv6 address
50 + if (octLen == IpAddress.INET_BYTE_LENGTH) {
51 + return IpAddress.valueOf(IpAddress.Version.INET, octs);
52 + }
53 + if (octLen == IpAddress.INET6_BYTE_LENGTH) {
54 + return IpAddress.valueOf(IpAddress.Version.INET6, octs);
55 + }
56 + return null; // Shouldn't be reached
50 } 57 }
51 -
52 } 58 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onlab.onos.store.serializers; 16 package org.onlab.onos.store.serializers;
17 17
18 +import org.onlab.packet.IpAddress;
18 import org.onlab.packet.IpPrefix; 19 import org.onlab.packet.IpPrefix;
19 20
20 import com.esotericsoftware.kryo.Kryo; 21 import com.esotericsoftware.kryo.Kryo;
...@@ -51,6 +52,13 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> { ...@@ -51,6 +52,13 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> {
51 byte[] octs = new byte[octLen]; 52 byte[] octs = new byte[octLen];
52 input.readBytes(octs); 53 input.readBytes(octs);
53 int prefLen = input.readInt(); 54 int prefLen = input.readInt();
54 - return IpPrefix.valueOf(octs, prefLen); 55 + // Use the address size to decide whether it is IPv4 or IPv6 address
56 + if (octLen == IpAddress.INET_BYTE_LENGTH) {
57 + return IpPrefix.valueOf(IpAddress.Version.INET, octs, prefLen);
58 + }
59 + if (octLen == IpAddress.INET6_BYTE_LENGTH) {
60 + return IpPrefix.valueOf(IpAddress.Version.INET6, octs, prefLen);
61 + }
62 + return null; // Shouldn't be reached
55 } 63 }
56 } 64 }
......
...@@ -36,7 +36,7 @@ public class MacAddressSerializer extends Serializer<MacAddress> { ...@@ -36,7 +36,7 @@ public class MacAddressSerializer extends Serializer<MacAddress> {
36 36
37 @Override 37 @Override
38 public void write(Kryo kryo, Output output, MacAddress object) { 38 public void write(Kryo kryo, Output output, MacAddress object) {
39 - output.writeBytes(object.getAddress()); 39 + output.writeBytes(object.toBytes());
40 } 40 }
41 41
42 @Override 42 @Override
......
...@@ -15,13 +15,16 @@ ...@@ -15,13 +15,16 @@
15 */ 15 */
16 package org.onlab.onos.store.trivial.impl; 16 package org.onlab.onos.store.trivial.impl;
17 17
18 +import java.util.Set;
19 +
18 import org.apache.felix.scr.annotations.Component; 20 import org.apache.felix.scr.annotations.Component;
19 import org.apache.felix.scr.annotations.Service; 21 import org.apache.felix.scr.annotations.Service;
20 import org.onlab.onos.mastership.MastershipTerm; 22 import org.onlab.onos.mastership.MastershipTerm;
21 import org.onlab.onos.net.DeviceId; 23 import org.onlab.onos.net.DeviceId;
22 import org.onlab.onos.net.device.DeviceClockProviderService; 24 import org.onlab.onos.net.device.DeviceClockProviderService;
23 25
24 -//FIXME: Code clone in onos-core-trivial, onos-core-hz-net 26 +import com.google.common.collect.Sets;
27 +
25 /** 28 /**
26 * Dummy implementation of {@link DeviceClockProviderService}. 29 * Dummy implementation of {@link DeviceClockProviderService}.
27 */ 30 */
...@@ -29,7 +32,15 @@ import org.onlab.onos.net.device.DeviceClockProviderService; ...@@ -29,7 +32,15 @@ import org.onlab.onos.net.device.DeviceClockProviderService;
29 @Service 32 @Service
30 public class NoOpClockProviderService implements DeviceClockProviderService { 33 public class NoOpClockProviderService implements DeviceClockProviderService {
31 34
35 + private Set<DeviceId> registerdBefore = Sets.newConcurrentHashSet();
36 +
32 @Override 37 @Override
33 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) { 38 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
39 + registerdBefore.add(deviceId);
40 + }
41 +
42 + @Override
43 + public boolean isTimestampAvailable(DeviceId deviceId) {
44 + return registerdBefore.contains(deviceId);
34 } 45 }
35 } 46 }
......
...@@ -16,8 +16,12 @@ ...@@ -16,8 +16,12 @@
16 package org.onlab.onos.store.trivial.impl; 16 package org.onlab.onos.store.trivial.impl;
17 17
18 import com.google.common.base.Function; 18 import com.google.common.base.Function;
19 +import com.google.common.cache.Cache;
20 +import com.google.common.cache.CacheBuilder;
19 import com.google.common.collect.FluentIterable; 21 import com.google.common.collect.FluentIterable;
20 import com.google.common.util.concurrent.Futures; 22 import com.google.common.util.concurrent.Futures;
23 +import com.google.common.util.concurrent.SettableFuture;
24 +
21 import org.apache.felix.scr.annotations.Activate; 25 import org.apache.felix.scr.annotations.Activate;
22 import org.apache.felix.scr.annotations.Component; 26 import org.apache.felix.scr.annotations.Component;
23 import org.apache.felix.scr.annotations.Deactivate; 27 import org.apache.felix.scr.annotations.Deactivate;
...@@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore; ...@@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore;
43 import org.onlab.util.NewConcurrentHashMap; 47 import org.onlab.util.NewConcurrentHashMap;
44 import org.slf4j.Logger; 48 import org.slf4j.Logger;
45 49
46 -import java.util.Arrays; 50 +import java.util.ArrayList;
47 import java.util.Collections; 51 import java.util.Collections;
48 import java.util.List; 52 import java.util.List;
49 import java.util.concurrent.ConcurrentHashMap; 53 import java.util.concurrent.ConcurrentHashMap;
50 import java.util.concurrent.ConcurrentMap; 54 import java.util.concurrent.ConcurrentMap;
51 import java.util.concurrent.CopyOnWriteArrayList; 55 import java.util.concurrent.CopyOnWriteArrayList;
52 import java.util.concurrent.Future; 56 import java.util.concurrent.Future;
57 +import java.util.concurrent.TimeUnit;
58 +import java.util.concurrent.atomic.AtomicInteger;
53 59
54 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; 60 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked;
55 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; 61 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
...@@ -72,6 +78,18 @@ public class SimpleFlowRuleStore ...@@ -72,6 +78,18 @@ public class SimpleFlowRuleStore
72 private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>> 78 private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>>
73 flowEntries = new ConcurrentHashMap<>(); 79 flowEntries = new ConcurrentHashMap<>();
74 80
81 + private final AtomicInteger localBatchIdGen = new AtomicInteger();
82 +
83 + // TODO: make this configurable
84 + private int pendingFutureTimeoutMinutes = 5;
85 +
86 + private Cache<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures =
87 + CacheBuilder.newBuilder()
88 + .expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES)
89 + // TODO Explicitly fail the future if expired?
90 + //.removalListener(listener)
91 + .build();
92 +
75 @Activate 93 @Activate
76 public void activate() { 94 public void activate() {
77 log.info("Started"); 95 log.info("Started");
...@@ -173,10 +191,6 @@ public class SimpleFlowRuleStore ...@@ -173,10 +191,6 @@ public class SimpleFlowRuleStore
173 } 191 }
174 // new flow rule added 192 // new flow rule added
175 existing.add(f); 193 existing.add(f);
176 - notifyDelegate(FlowRuleBatchEvent.requested(
177 - new FlowRuleBatchRequest(1, /* FIXME generate something */
178 - Arrays.<FlowEntry>asList(f),
179 - Collections.<FlowEntry>emptyList())));
180 } 194 }
181 } 195 }
182 196
...@@ -190,11 +204,6 @@ public class SimpleFlowRuleStore ...@@ -190,11 +204,6 @@ public class SimpleFlowRuleStore
190 if (entry.equals(rule)) { 204 if (entry.equals(rule)) {
191 synchronized (entry) { 205 synchronized (entry) {
192 entry.setState(FlowEntryState.PENDING_REMOVE); 206 entry.setState(FlowEntryState.PENDING_REMOVE);
193 - // TODO: Should we notify only if it's "remote" event?
194 - notifyDelegate(FlowRuleBatchEvent.requested(
195 - new FlowRuleBatchRequest(1, /* FIXME generate something */
196 - Collections.<FlowEntry>emptyList(),
197 - Arrays.<FlowEntry>asList(entry))));
198 } 207 }
199 } 208 }
200 } 209 }
...@@ -251,20 +260,47 @@ public class SimpleFlowRuleStore ...@@ -251,20 +260,47 @@ public class SimpleFlowRuleStore
251 @Override 260 @Override
252 public Future<CompletedBatchOperation> storeBatch( 261 public Future<CompletedBatchOperation> storeBatch(
253 FlowRuleBatchOperation batchOperation) { 262 FlowRuleBatchOperation batchOperation) {
263 + List<FlowRule> toAdd = new ArrayList<>();
264 + List<FlowRule> toRemove = new ArrayList<>();
254 for (FlowRuleBatchEntry entry : batchOperation.getOperations()) { 265 for (FlowRuleBatchEntry entry : batchOperation.getOperations()) {
266 + final FlowRule flowRule = entry.getTarget();
255 if (entry.getOperator().equals(FlowRuleOperation.ADD)) { 267 if (entry.getOperator().equals(FlowRuleOperation.ADD)) {
256 - storeFlowRule(entry.getTarget()); 268 + if (!getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) {
269 + storeFlowRule(flowRule);
270 + toAdd.add(flowRule);
271 + }
257 } else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) { 272 } else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) {
258 - deleteFlowRule(entry.getTarget()); 273 + if (getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) {
274 + deleteFlowRule(flowRule);
275 + toRemove.add(flowRule);
276 + }
259 } else { 277 } else {
260 throw new UnsupportedOperationException("Unsupported operation type"); 278 throw new UnsupportedOperationException("Unsupported operation type");
261 } 279 }
262 } 280 }
263 - return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet())); 281 +
282 + if (toAdd.isEmpty() && toRemove.isEmpty()) {
283 + return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowRule>emptySet()));
284 + }
285 +
286 + SettableFuture<CompletedBatchOperation> r = SettableFuture.create();
287 + final int batchId = localBatchIdGen.incrementAndGet();
288 +
289 + pendingFutures.put(batchId, r);
290 + notifyDelegate(FlowRuleBatchEvent.requested(new FlowRuleBatchRequest(batchId, toAdd, toRemove)));
291 +
292 + return r;
264 } 293 }
265 294
266 @Override 295 @Override
267 public void batchOperationComplete(FlowRuleBatchEvent event) { 296 public void batchOperationComplete(FlowRuleBatchEvent event) {
297 + final Integer batchId = event.subject().batchId();
298 + SettableFuture<CompletedBatchOperation> future
299 + = pendingFutures.getIfPresent(batchId);
300 + if (future != null) {
301 + future.set(event.result());
302 + pendingFutures.invalidate(batchId);
303 + }
268 notifyDelegate(event); 304 notifyDelegate(event);
269 } 305 }
270 } 306 }
......
...@@ -115,17 +115,25 @@ public interface OpenFlowSwitch { ...@@ -115,17 +115,25 @@ public interface OpenFlowSwitch {
115 public String serialNumber(); 115 public String serialNumber();
116 116
117 /** 117 /**
118 + * Checks if the switch is still connected.
119 + *
120 + * @return whether the switch is still connected
121 + */
122 + public boolean isConnected();
123 +
124 + /**
118 * Disconnects the switch by closing the TCP connection. Results in a call 125 * Disconnects the switch by closing the TCP connection. Results in a call
119 * to the channel handler's channelDisconnected method for cleanup 126 * to the channel handler's channelDisconnected method for cleanup
120 */ 127 */
121 public void disconnectSwitch(); 128 public void disconnectSwitch();
122 129
123 /** 130 /**
124 - * Notifies the controller that role assertion has failed. 131 + * Notifies the controller that the device has responded to a set-role request.
125 * 132 *
126 - * @param role the failed role 133 + * @param requested the role requested by the controller
134 + * @param response the role set at the device
127 */ 135 */
128 - public void returnRoleAssertFailure(RoleState role); 136 + public void returnRoleReply(RoleState requested, RoleState reponse);
129 137
130 /** 138 /**
131 * Indicates if this switch is optical. 139 * Indicates if this switch is optical.
......
...@@ -53,5 +53,5 @@ public interface OpenFlowSwitchListener { ...@@ -53,5 +53,5 @@ public interface OpenFlowSwitchListener {
53 * @param dpid the switch that failed role assertion 53 * @param dpid the switch that failed role assertion
54 * @param role the role imposed by the controller 54 * @param role the role imposed by the controller
55 */ 55 */
56 - public void roleAssertFailed(Dpid dpid, RoleState role); 56 + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response);
57 } 57 }
......
...@@ -217,8 +217,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -217,8 +217,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
217 } 217 }
218 218
219 @Override 219 @Override
220 - public void returnRoleAssertFailure(RoleState role) { 220 + public void returnRoleReply(RoleState requested, RoleState response) {
221 - this.agent.returnRoleAssertFailed(dpid, role); 221 + this.agent.returnRoleReply(dpid, requested, response);
222 } 222 }
223 223
224 @Override 224 @Override
......
...@@ -97,5 +97,5 @@ public interface OpenFlowAgent { ...@@ -97,5 +97,5 @@ public interface OpenFlowAgent {
97 * @param dpid the switch that failed role assertion 97 * @param dpid the switch that failed role assertion
98 * @param role the failed role 98 * @param role the failed role
99 */ 99 */
100 - public void returnRoleAssertFailed(Dpid dpid, RoleState role); 100 + public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response);
101 } 101 }
......
...@@ -187,13 +187,6 @@ public interface OpenFlowSwitchDriver extends OpenFlowSwitch { ...@@ -187,13 +187,6 @@ public interface OpenFlowSwitchDriver extends OpenFlowSwitch {
187 public void setConnected(boolean connected); 187 public void setConnected(boolean connected);
188 188
189 /** 189 /**
190 - * Checks if the switch is still connected.
191 - *
192 - * @return whether the switch is still connected
193 - */
194 - public boolean isConnected();
195 -
196 - /**
197 * Writes the message to the output stream 190 * Writes the message to the output stream
198 * in a driver specific manner. 191 * in a driver specific manner.
199 * 192 *
......
...@@ -374,9 +374,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -374,9 +374,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
374 } 374 }
375 375
376 @Override 376 @Override
377 - public void returnRoleAssertFailed(Dpid dpid, RoleState role) { 377 + public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response) {
378 for (OpenFlowSwitchListener l : ofSwitchListener) { 378 for (OpenFlowSwitchListener l : ofSwitchListener) {
379 - l.roleAssertFailed(dpid, role); 379 + l.receivedRoleReply(dpid, requested, response);
380 } 380 }
381 } 381 }
382 } 382 }
......
...@@ -17,6 +17,7 @@ package org.onlab.onos.openflow.controller.impl; ...@@ -17,6 +17,7 @@ package org.onlab.onos.openflow.controller.impl;
17 17
18 import java.io.IOException; 18 import java.io.IOException;
19 import java.util.Collections; 19 import java.util.Collections;
20 +import java.util.concurrent.TimeUnit;
20 21
21 import org.onlab.onos.openflow.controller.RoleState; 22 import org.onlab.onos.openflow.controller.RoleState;
22 import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver; 23 import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
...@@ -41,31 +42,29 @@ import org.projectfloodlight.openflow.types.U64; ...@@ -41,31 +42,29 @@ import org.projectfloodlight.openflow.types.U64;
41 import org.slf4j.Logger; 42 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory; 43 import org.slf4j.LoggerFactory;
43 44
45 +import com.google.common.cache.Cache;
46 +import com.google.common.cache.CacheBuilder;
47 +
44 48
45 /** 49 /**
46 * A utility class to handle role requests and replies for this channel. 50 * A utility class to handle role requests and replies for this channel.
47 * After a role request is submitted the role changer keeps track of the 51 * After a role request is submitted the role changer keeps track of the
48 * pending request, collects the reply (if any) and times out the request 52 * pending request, collects the reply (if any) and times out the request
49 * if necessary. 53 * if necessary.
50 - *
51 - * To simplify role handling we only keep track of the /last/ pending
52 - * role reply send to the switch. If multiple requests are pending and
53 - * we receive replies for earlier requests we ignore them. However, this
54 - * way of handling pending requests implies that we could wait forever if
55 - * a new request is submitted before the timeout triggers. If necessary
56 - * we could work around that though.
57 */ 54 */
58 class RoleManager implements RoleHandler { 55 class RoleManager implements RoleHandler {
59 protected static final long NICIRA_EXPERIMENTER = 0x2320; 56 protected static final long NICIRA_EXPERIMENTER = 0x2320;
60 57
61 private static Logger log = LoggerFactory.getLogger(RoleManager.class); 58 private static Logger log = LoggerFactory.getLogger(RoleManager.class);
62 - // indicates that a request is currently pending 59 +
63 - // needs to be volatile to allow correct double-check idiom 60 + // The time until cached XID is evicted. Arbitray for now.
64 - private volatile boolean requestPending; 61 + private final int pendingXidTimeoutSeconds = 60;
65 - // the transaction Id of the pending request 62 +
66 - private int pendingXid; 63 + // The cache for pending expected RoleReplies keyed on expected XID
67 - // the role that's pending 64 + private Cache<Integer, RoleState> pendingReplies =
68 - private RoleState pendingRole; 65 + CacheBuilder.newBuilder()
66 + .expireAfterWrite(pendingXidTimeoutSeconds, TimeUnit.SECONDS)
67 + .build();
69 68
70 // the expectation set by the caller for the returned role 69 // the expectation set by the caller for the returned role
71 private RoleRecvStatus expectation; 70 private RoleRecvStatus expectation;
...@@ -73,9 +72,6 @@ class RoleManager implements RoleHandler { ...@@ -73,9 +72,6 @@ class RoleManager implements RoleHandler {
73 72
74 73
75 public RoleManager(OpenFlowSwitchDriver sw) { 74 public RoleManager(OpenFlowSwitchDriver sw) {
76 - this.requestPending = false;
77 - this.pendingXid = -1;
78 - this.pendingRole = null;
79 this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE; 75 this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
80 this.sw = sw; 76 this.sw = sw;
81 } 77 }
...@@ -157,15 +153,11 @@ class RoleManager implements RoleHandler { ...@@ -157,15 +153,11 @@ class RoleManager implements RoleHandler {
157 } 153 }
158 // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn. 154 // OF1.0 switch with support for NX_ROLE_REQUEST vendor extn.
159 // make Role.EQUAL become Role.SLAVE 155 // make Role.EQUAL become Role.SLAVE
160 - pendingRole = role; 156 + RoleState roleToSend = (role == RoleState.EQUAL) ? RoleState.SLAVE : role;
161 - role = (role == RoleState.EQUAL) ? RoleState.SLAVE : role; 157 + pendingReplies.put(sendNxRoleRequest(roleToSend), role);
162 - pendingXid = sendNxRoleRequest(role);
163 - requestPending = true;
164 } else { 158 } else {
165 // OF1.3 switch, use OFPT_ROLE_REQUEST message 159 // OF1.3 switch, use OFPT_ROLE_REQUEST message
166 - pendingXid = sendOF13RoleRequest(role); 160 + pendingReplies.put(sendOF13RoleRequest(role), role);
167 - pendingRole = role;
168 - requestPending = true;
169 } 161 }
170 return true; 162 return true;
171 } 163 }
...@@ -192,12 +184,17 @@ class RoleManager implements RoleHandler { ...@@ -192,12 +184,17 @@ class RoleManager implements RoleHandler {
192 @Override 184 @Override
193 public synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri) 185 public synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
194 throws SwitchStateException { 186 throws SwitchStateException {
195 - if (!requestPending) { 187 + int xid = (int) rri.getXid();
188 + RoleState receivedRole = rri.getRole();
189 + RoleState expectedRole = pendingReplies.getIfPresent(xid);
190 +
191 + if (expectedRole == null) {
196 RoleState currentRole = (sw != null) ? sw.getRole() : null; 192 RoleState currentRole = (sw != null) ? sw.getRole() : null;
197 if (currentRole != null) { 193 if (currentRole != null) {
198 if (currentRole == rri.getRole()) { 194 if (currentRole == rri.getRole()) {
199 // Don't disconnect if the role reply we received is 195 // Don't disconnect if the role reply we received is
200 // for the same role we are already in. 196 // for the same role we are already in.
197 + // FIXME: but we do from the caller anyways.
201 log.debug("Received unexpected RoleReply from " 198 log.debug("Received unexpected RoleReply from "
202 + "Switch: {}. " 199 + "Switch: {}. "
203 + "Role in reply is same as current role of this " 200 + "Role in reply is same as current role of this "
...@@ -223,34 +220,33 @@ class RoleManager implements RoleHandler { ...@@ -223,34 +220,33 @@ class RoleManager implements RoleHandler {
223 return RoleRecvStatus.OTHER_EXPECTATION; 220 return RoleRecvStatus.OTHER_EXPECTATION;
224 } 221 }
225 222
226 - int xid = (int) rri.getXid(); 223 + // XXX Should check generation id meaningfully and other cases of expectations
227 - RoleState role = rri.getRole(); 224 + //if (pendingXid != xid) {
228 - // XXX S should check generation id meaningfully and other cases of expectations 225 + // log.info("Received older role reply from " +
229 - 226 + // "switch {} ({}). Ignoring. " +
230 - if (pendingXid != xid) { 227 + // "Waiting for {}, xid={}",
231 - log.debug("Received older role reply from " + 228 + // new Object[] {sw.getStringId(), rri,
232 - "switch {} ({}). Ignoring. " + 229 + // pendingRole, pendingXid });
233 - "Waiting for {}, xid={}", 230 + // return RoleRecvStatus.OLD_REPLY;
234 - new Object[] {sw.getStringId(), rri, 231 + //}
235 - pendingRole, pendingXid }); 232 + sw.returnRoleReply(expectedRole, receivedRole);
236 - return RoleRecvStatus.OLD_REPLY; 233 +
237 - } 234 + if (expectedRole == receivedRole) {
238 -
239 - if (pendingRole == role) {
240 log.debug("Received role reply message from {} that matched " 235 log.debug("Received role reply message from {} that matched "
241 + "expected role-reply {} with expectations {}", 236 + "expected role-reply {} with expectations {}",
242 - new Object[] {sw.getStringId(), role, expectation}); 237 + new Object[] {sw.getStringId(), receivedRole, expectation});
243 238
239 + // Done with this RoleReply; Invalidate
240 + pendingReplies.invalidate(xid);
244 if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE || 241 if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
245 expectation == RoleRecvStatus.MATCHED_SET_ROLE) { 242 expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
246 return expectation; 243 return expectation;
247 } else { 244 } else {
248 return RoleRecvStatus.OTHER_EXPECTATION; 245 return RoleRecvStatus.OTHER_EXPECTATION;
249 } 246 }
250 - } else {
251 - sw.returnRoleAssertFailure(pendingRole);
252 } 247 }
253 248
249 + pendingReplies.invalidate(xid);
254 // if xids match but role's don't, perhaps its a query (OF1.3) 250 // if xids match but role's don't, perhaps its a query (OF1.3)
255 if (expectation == RoleRecvStatus.REPLY_QUERY) { 251 if (expectation == RoleRecvStatus.REPLY_QUERY) {
256 return expectation; 252 return expectation;
...@@ -270,18 +266,17 @@ class RoleManager implements RoleHandler { ...@@ -270,18 +266,17 @@ class RoleManager implements RoleHandler {
270 @Override 266 @Override
271 public synchronized RoleRecvStatus deliverError(OFErrorMsg error) 267 public synchronized RoleRecvStatus deliverError(OFErrorMsg error)
272 throws SwitchStateException { 268 throws SwitchStateException {
273 - if (!requestPending) { 269 + RoleState errorRole = pendingReplies.getIfPresent(error.getXid());
274 - log.debug("Received an error msg from sw {}, but no pending " 270 + if (errorRole == null) {
275 - + "requests in role-changer; not handling ...",
276 - sw.getStringId());
277 - return RoleRecvStatus.OTHER_EXPECTATION;
278 - }
279 - if (pendingXid != error.getXid()) {
280 if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) { 271 if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
281 log.debug("Received an error msg from sw {} for a role request," 272 log.debug("Received an error msg from sw {} for a role request,"
282 + " but not for pending request in role-changer; " 273 + " but not for pending request in role-changer; "
283 + " ignoring error {} ...", 274 + " ignoring error {} ...",
284 sw.getStringId(), error); 275 sw.getStringId(), error);
276 + } else {
277 + log.debug("Received an error msg from sw {}, but no pending "
278 + + "requests in role-changer; not handling ...",
279 + sw.getStringId());
285 } 280 }
286 return RoleRecvStatus.OTHER_EXPECTATION; 281 return RoleRecvStatus.OTHER_EXPECTATION;
287 } 282 }
...@@ -292,7 +287,7 @@ class RoleManager implements RoleHandler { ...@@ -292,7 +287,7 @@ class RoleManager implements RoleHandler {
292 + "role-messaging is supported. Possible issues in " 287 + "role-messaging is supported. Possible issues in "
293 + "switch driver configuration?", new Object[] { 288 + "switch driver configuration?", new Object[] {
294 ((OFBadRequestErrorMsg) error).toString(), 289 ((OFBadRequestErrorMsg) error).toString(),
295 - sw.getStringId(), pendingRole 290 + sw.getStringId(), errorRole
296 }); 291 });
297 return RoleRecvStatus.UNSUPPORTED; 292 return RoleRecvStatus.UNSUPPORTED;
298 } 293 }
...@@ -316,7 +311,7 @@ class RoleManager implements RoleHandler { ...@@ -316,7 +311,7 @@ class RoleManager implements RoleHandler {
316 + "received Error to for pending role request [%s]. " 311 + "received Error to for pending role request [%s]. "
317 + "Error:[%s]. Disconnecting switch ... ", 312 + "Error:[%s]. Disconnecting switch ... ",
318 sw.getStringId(), 313 sw.getStringId(),
319 - pendingRole, rrerr); 314 + errorRole, rrerr);
320 throw new SwitchStateException(msgx); 315 throw new SwitchStateException(msgx);
321 default: 316 default:
322 break; 317 break;
......
...@@ -175,11 +175,6 @@ public class RoleManagerTest { ...@@ -175,11 +175,6 @@ public class RoleManagerTest {
175 } 175 }
176 176
177 @Override 177 @Override
178 - public void returnRoleAssertFailure(RoleState role) {
179 - failed = role;
180 - }
181 -
182 - @Override
183 public boolean isOptical() { 178 public boolean isOptical() {
184 return false; 179 return false;
185 } 180 }
...@@ -300,5 +295,10 @@ public class RoleManagerTest { ...@@ -300,5 +295,10 @@ public class RoleManagerTest {
300 public void write(List<OFMessage> msgs) { 295 public void write(List<OFMessage> msgs) {
301 } 296 }
302 297
298 + @Override
299 + public void returnRoleReply(RoleState requested, RoleState response) {
300 + failed = requested;
301 + }
302 +
303 } 303 }
304 } 304 }
......
...@@ -318,6 +318,7 @@ ...@@ -318,6 +318,7 @@
318 <groupId>io.netty</groupId> 318 <groupId>io.netty</groupId>
319 <artifactId>netty-transport-native-epoll</artifactId> 319 <artifactId>netty-transport-native-epoll</artifactId>
320 <version>${netty4.version}</version> 320 <version>${netty4.version}</version>
321 + <classifier>${os.detected.classifier}</classifier>
321 </dependency> 322 </dependency>
322 <dependency> 323 <dependency>
323 <groupId>joda-time</groupId> 324 <groupId>joda-time</groupId>
...@@ -351,6 +352,13 @@ ...@@ -351,6 +352,13 @@
351 </dependencies> 352 </dependencies>
352 353
353 <build> 354 <build>
355 + <extensions>
356 + <extension>
357 + <groupId>kr.motd.maven</groupId>
358 + <artifactId>os-maven-plugin</artifactId>
359 + <version>1.2.3.Final</version>
360 + </extension>
361 + </extensions>
354 <pluginManagement> 362 <pluginManagement>
355 <plugins> 363 <plugins>
356 <plugin> 364 <plugin>
......
...@@ -120,7 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid ...@@ -120,7 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
120 if (eth.getEtherType() == Ethernet.TYPE_ARP) { 120 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
121 ARP arp = (ARP) eth.getPayload(); 121 ARP arp = (ARP) eth.getPayload();
122 IpAddress ip = 122 IpAddress ip =
123 - IpAddress.valueOf(arp.getSenderProtocolAddress()); 123 + IpAddress.valueOf(IpAddress.Version.INET,
124 + arp.getSenderProtocolAddress());
124 HostDescription hdescr = 125 HostDescription hdescr =
125 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 126 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
126 providerService.hostDetected(hid, hdescr); 127 providerService.hostDetected(hid, hdescr);
......
...@@ -216,7 +216,7 @@ public class HostLocationProviderTest { ...@@ -216,7 +216,7 @@ public class HostLocationProviderTest {
216 eth.setEtherType(Ethernet.TYPE_ARP) 216 eth.setEtherType(Ethernet.TYPE_ARP)
217 .setVlanID(VLAN.toShort()) 217 .setVlanID(VLAN.toShort())
218 .setSourceMACAddress(MAC.toBytes()) 218 .setSourceMACAddress(MAC.toBytes())
219 - .setDestinationMACAddress(BCMAC.getAddress()) 219 + .setDestinationMACAddress(BCMAC)
220 .setPayload(arp); 220 .setPayload(arp);
221 ConnectPoint receivedFrom = new ConnectPoint(DeviceId.deviceId(deviceId), 221 ConnectPoint receivedFrom = new ConnectPoint(DeviceId.deviceId(deviceId),
222 PortNumber.portNumber(INPORT)); 222 PortNumber.portNumber(INPORT));
......
...@@ -127,18 +127,19 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -127,18 +127,19 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
127 return; 127 return;
128 } 128 }
129 log.trace("{} {} {}", event.type(), event.subject(), event); 129 log.trace("{} {} {}", event.type(), event.subject(), event);
130 + final DeviceId deviceId = device.id();
130 switch (event.type()) { 131 switch (event.type()) {
131 case DEVICE_ADDED: 132 case DEVICE_ADDED:
132 case DEVICE_UPDATED: 133 case DEVICE_UPDATED:
133 - ld = discoverers.get(device.id()); 134 + ld = discoverers.get(deviceId);
134 if (ld == null) { 135 if (ld == null) {
135 - log.debug("Device added ({}) {}", event.type(), device.id()); 136 + log.debug("Device added ({}) {}", event.type(), deviceId);
136 - discoverers.put(device.id(), 137 + discoverers.put(deviceId,
137 new LinkDiscovery(device, packetSevice, masterService, 138 new LinkDiscovery(device, packetSevice, masterService,
138 providerService, useBDDP)); 139 providerService, useBDDP));
139 } else { 140 } else {
140 if (ld.isStopped()) { 141 if (ld.isStopped()) {
141 - log.debug("Device restarted ({}) {}", event.type(), device.id()); 142 + log.debug("Device restarted ({}) {}", event.type(), deviceId);
142 ld.start(); 143 ld.start();
143 } 144 }
144 } 145 }
...@@ -146,7 +147,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -146,7 +147,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
146 case PORT_ADDED: 147 case PORT_ADDED:
147 case PORT_UPDATED: 148 case PORT_UPDATED:
148 if (port.isEnabled()) { 149 if (port.isEnabled()) {
149 - ld = discoverers.get(device.id()); 150 + ld = discoverers.get(deviceId);
150 if (ld == null) { 151 if (ld == null) {
151 return; 152 return;
152 } 153 }
...@@ -156,47 +157,47 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -156,47 +157,47 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
156 } 157 }
157 } else { 158 } else {
158 log.debug("Port down {}", port); 159 log.debug("Port down {}", port);
159 - ConnectPoint point = new ConnectPoint(device.id(), 160 + ConnectPoint point = new ConnectPoint(deviceId,
160 port.number()); 161 port.number());
161 providerService.linksVanished(point); 162 providerService.linksVanished(point);
162 } 163 }
163 break; 164 break;
164 case PORT_REMOVED: 165 case PORT_REMOVED:
165 log.debug("Port removed {}", port); 166 log.debug("Port removed {}", port);
166 - ConnectPoint point = new ConnectPoint(device.id(), 167 + ConnectPoint point = new ConnectPoint(deviceId,
167 port.number()); 168 port.number());
168 providerService.linksVanished(point); 169 providerService.linksVanished(point);
169 // TODO: Don't we need to removePort from ld? 170 // TODO: Don't we need to removePort from ld?
170 break; 171 break;
171 case DEVICE_REMOVED: 172 case DEVICE_REMOVED:
172 case DEVICE_SUSPENDED: 173 case DEVICE_SUSPENDED:
173 - log.debug("Device removed {}", device.id()); 174 + log.debug("Device removed {}", deviceId);
174 - ld = discoverers.get(device.id()); 175 + ld = discoverers.get(deviceId);
175 if (ld == null) { 176 if (ld == null) {
176 return; 177 return;
177 } 178 }
178 ld.stop(); 179 ld.stop();
179 - providerService.linksVanished(device.id()); 180 + providerService.linksVanished(deviceId);
180 break; 181 break;
181 case DEVICE_AVAILABILITY_CHANGED: 182 case DEVICE_AVAILABILITY_CHANGED:
182 - ld = discoverers.get(device.id()); 183 + ld = discoverers.get(deviceId);
183 if (ld == null) { 184 if (ld == null) {
184 return; 185 return;
185 } 186 }
186 - if (deviceService.isAvailable(device.id())) { 187 + if (deviceService.isAvailable(deviceId)) {
187 - log.debug("Device up {}", device.id()); 188 + log.debug("Device up {}", deviceId);
188 ld.start(); 189 ld.start();
189 } else { 190 } else {
190 - providerService.linksVanished(device.id()); 191 + providerService.linksVanished(deviceId);
191 - log.debug("Device down {}", device.id()); 192 + log.debug("Device down {}", deviceId);
192 ld.stop(); 193 ld.stop();
193 } 194 }
194 break; 195 break;
195 case DEVICE_MASTERSHIP_CHANGED: 196 case DEVICE_MASTERSHIP_CHANGED:
196 - if (!discoverers.containsKey(device.id())) { 197 + if (!discoverers.containsKey(deviceId)) {
197 // TODO: ideally, should never reach here 198 // TODO: ideally, should never reach here
198 - log.debug("Device mastership changed ({}) {}", event.type(), device.id()); 199 + log.debug("Device mastership changed ({}) {}", event.type(), deviceId);
199 - discoverers.put(device.id(), 200 + discoverers.put(deviceId,
200 new LinkDiscovery(device, packetSevice, masterService, 201 new LinkDiscovery(device, packetSevice, masterService,
201 providerService, useBDDP)); 202 providerService, useBDDP));
202 } 203 }
......
...@@ -39,7 +39,6 @@ import org.onlab.onos.openflow.controller.OpenFlowController; ...@@ -39,7 +39,6 @@ import org.onlab.onos.openflow.controller.OpenFlowController;
39 import org.onlab.onos.openflow.controller.OpenFlowSwitch; 39 import org.onlab.onos.openflow.controller.OpenFlowSwitch;
40 import org.onlab.onos.openflow.controller.OpenFlowSwitchListener; 40 import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
41 import org.onlab.onos.openflow.controller.RoleState; 41 import org.onlab.onos.openflow.controller.RoleState;
42 -import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
43 import org.onlab.packet.ChassisId; 42 import org.onlab.packet.ChassisId;
44 import org.projectfloodlight.openflow.protocol.OFFactory; 43 import org.projectfloodlight.openflow.protocol.OFFactory;
45 import org.projectfloodlight.openflow.protocol.OFPortConfig; 44 import org.projectfloodlight.openflow.protocol.OFPortConfig;
...@@ -112,27 +111,39 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -112,27 +111,39 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
112 111
113 112
114 @Override 113 @Override
115 - public boolean isReachable(Device device) { 114 + public boolean isReachable(DeviceId deviceId) {
116 - // FIXME if possible, we might want this to be part of 115 + OpenFlowSwitch sw = controller.getSwitch(dpid(deviceId.uri()));
117 - // OpenFlowSwitch interface so the driver interface isn't misused. 116 + if (sw == null || !sw.isConnected()) {
118 - OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri()));
119 - if (sw == null || !((OpenFlowSwitchDriver) sw).isConnected()) {
120 return false; 117 return false;
121 } 118 }
122 return true; 119 return true;
123 - //return checkChannel(device, sw);
124 } 120 }
125 121
126 @Override 122 @Override
127 public void triggerProbe(Device device) { 123 public void triggerProbe(Device device) {
128 - LOG.info("Triggering probe on device {}", device.id()); 124 + final DeviceId deviceId = device.id();
125 + LOG.info("Triggering probe on device {}", deviceId);
129 126
130 - OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri())); 127 + final Dpid dpid = dpid(deviceId.uri());
131 - //if (!checkChannel(device, sw)) { 128 + OpenFlowSwitch sw = controller.getSwitch(dpid);
132 - // LOG.error("Failed to probe device {} on sw={}", device, sw); 129 + if (sw == null || !sw.isConnected()) {
133 - // providerService.deviceDisconnected(device.id()); 130 + LOG.error("Failed to probe device {} on sw={}", device, sw);
134 - //return; 131 + providerService.deviceDisconnected(deviceId);
135 - //} 132 + } else {
133 + LOG.trace("Confirmed device {} connection", device);
134 + // FIXME require something like below to match javadoc description
135 + // but this starts infinite loop with current DeviceManager
136 +// final ChassisId cId = new ChassisId(dpid.value());
137 +// final Type deviceType = device.type();
138 +// DeviceDescription description =
139 +// new DefaultDeviceDescription(deviceId.uri(), deviceType,
140 +// sw.manfacturerDescription(),
141 +// sw.hardwareDescription(),
142 +// sw.softwareDescription(),
143 +// sw.serialNumber(),
144 +// cId);
145 +// providerService.deviceConnected(deviceId, description);
146 + }
136 147
137 // Prompt an update of port information. We can use any XID for this. 148 // Prompt an update of port information. We can use any XID for this.
138 OFFactory fact = sw.factory(); 149 OFFactory fact = sw.factory();
...@@ -159,22 +170,22 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -159,22 +170,22 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
159 // } 170 // }
160 171
161 @Override 172 @Override
162 - public void roleChanged(Device device, MastershipRole newRole) { 173 + public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
163 switch (newRole) { 174 switch (newRole) {
164 case MASTER: 175 case MASTER:
165 - controller.setRole(dpid(device.id().uri()), RoleState.MASTER); 176 + controller.setRole(dpid(deviceId.uri()), RoleState.MASTER);
166 break; 177 break;
167 case STANDBY: 178 case STANDBY:
168 - controller.setRole(dpid(device.id().uri()), RoleState.EQUAL); 179 + controller.setRole(dpid(deviceId.uri()), RoleState.EQUAL);
169 break; 180 break;
170 case NONE: 181 case NONE:
171 - controller.setRole(dpid(device.id().uri()), RoleState.SLAVE); 182 + controller.setRole(dpid(deviceId.uri()), RoleState.SLAVE);
172 break; 183 break;
173 default: 184 default:
174 LOG.error("Unknown Mastership state : {}", newRole); 185 LOG.error("Unknown Mastership state : {}", newRole);
175 186
176 } 187 }
177 - LOG.info("Accepting mastership role change for device {}", device.id()); 188 + LOG.info("Accepting mastership role change for device {}", deviceId);
178 } 189 }
179 190
180 private class InternalDeviceProvider implements OpenFlowSwitchListener { 191 private class InternalDeviceProvider implements OpenFlowSwitchListener {
...@@ -226,23 +237,31 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -226,23 +237,31 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
226 } 237 }
227 238
228 @Override 239 @Override
229 - public void roleAssertFailed(Dpid dpid, RoleState role) { 240 + public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
230 - MastershipRole failed; 241 + MastershipRole request = roleOf(requested);
231 - switch (role) { 242 + MastershipRole reply = roleOf(response);
243 +
244 + providerService.receivedRoleReply(deviceId(uri(dpid)), request, reply);
245 + }
246 +
247 + /**
248 + * Translates a RoleState to the corresponding MastershipRole.
249 + *
250 + * @param response
251 + * @return a MastershipRole
252 + */
253 + private MastershipRole roleOf(RoleState response) {
254 + switch (response) {
232 case MASTER: 255 case MASTER:
233 - failed = MastershipRole.MASTER; 256 + return MastershipRole.MASTER;
234 - break;
235 case EQUAL: 257 case EQUAL:
236 - failed = MastershipRole.STANDBY; 258 + return MastershipRole.STANDBY;
237 - break;
238 case SLAVE: 259 case SLAVE:
239 - failed = MastershipRole.NONE; 260 + return MastershipRole.NONE;
240 - break;
241 default: 261 default:
242 - LOG.warn("unknown role {}", role); 262 + LOG.warn("unknown role {}", response);
243 - return; 263 + return null;
244 } 264 }
245 - providerService.unableToAssertRole(deviceId(uri(dpid)), failed);
246 } 265 }
247 266
248 /** 267 /**
......
...@@ -105,11 +105,11 @@ public class OpenFlowDeviceProviderTest { ...@@ -105,11 +105,11 @@ public class OpenFlowDeviceProviderTest {
105 105
106 @Test 106 @Test
107 public void roleChanged() { 107 public void roleChanged() {
108 - provider.roleChanged(DEV1, MASTER); 108 + provider.roleChanged(DID1, MASTER);
109 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1)); 109 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
110 - provider.roleChanged(DEV1, STANDBY); 110 + provider.roleChanged(DID1, STANDBY);
111 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1)); 111 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
112 - provider.roleChanged(DEV1, NONE); 112 + provider.roleChanged(DID1, NONE);
113 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1)); 113 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
114 } 114 }
115 115
...@@ -136,12 +136,13 @@ public class OpenFlowDeviceProviderTest { ...@@ -136,12 +136,13 @@ public class OpenFlowDeviceProviderTest {
136 } 136 }
137 137
138 @Test 138 @Test
139 - public void roleAssertFailed() { 139 + public void receivedRoleReply() {
140 - controller.listener.roleAssertFailed(DPID1, RoleState.MASTER); 140 + // check translation capabilities
141 + controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
141 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER)); 142 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
142 - controller.listener.roleAssertFailed(DPID1, RoleState.EQUAL); 143 + controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
143 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY)); 144 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
144 - controller.listener.roleAssertFailed(DPID1, RoleState.SLAVE); 145 + controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
145 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE)); 146 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
146 } 147 }
147 148
...@@ -210,8 +211,9 @@ public class OpenFlowDeviceProviderTest { ...@@ -210,8 +211,9 @@ public class OpenFlowDeviceProviderTest {
210 } 211 }
211 212
212 @Override 213 @Override
213 - public void unableToAssertRole(DeviceId deviceId, MastershipRole role) { 214 + public void receivedRoleReply(DeviceId deviceId,
214 - roles.put(role, Dpid.dpid(deviceId.uri())); 215 + MastershipRole requested, MastershipRole response) {
216 + roles.put(requested, Dpid.dpid(deviceId.uri()));
215 } 217 }
216 218
217 } 219 }
...@@ -368,11 +370,12 @@ public class OpenFlowDeviceProviderTest { ...@@ -368,11 +370,12 @@ public class OpenFlowDeviceProviderTest {
368 } 370 }
369 371
370 @Override 372 @Override
371 - public void disconnectSwitch() { 373 + public boolean isConnected() {
374 + return true;
372 } 375 }
373 376
374 @Override 377 @Override
375 - public void returnRoleAssertFailure(RoleState role) { 378 + public void disconnectSwitch() {
376 } 379 }
377 380
378 @Override 381 @Override
...@@ -380,6 +383,10 @@ public class OpenFlowDeviceProviderTest { ...@@ -380,6 +383,10 @@ public class OpenFlowDeviceProviderTest {
380 return false; 383 return false;
381 } 384 }
382 385
386 + @Override
387 + public void returnRoleReply(RoleState requested, RoleState reponse) {
388 + }
389 +
383 } 390 }
384 391
385 } 392 }
......
...@@ -147,7 +147,8 @@ public abstract class FlowModBuilder { ...@@ -147,7 +147,8 @@ public abstract class FlowModBuilder {
147 ip = (IPCriterion) c; 147 ip = (IPCriterion) c;
148 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) { 148 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) {
149 IpAddress maskAddr = 149 IpAddress maskAddr =
150 - IpAddress.makeMaskPrefix(ip.ip().prefixLength()); 150 + IpAddress.makeMaskPrefix(ip.ip().address().version(),
151 + ip.ip().prefixLength());
151 Masked<IPv4Address> maskedIp = 152 Masked<IPv4Address> maskedIp =
152 Masked.of(IPv4Address.of(ip.ip().address().toInt()), 153 Masked.of(IPv4Address.of(ip.ip().address().toInt()),
153 IPv4Address.of(maskAddr.toInt())); 154 IPv4Address.of(maskAddr.toInt()));
...@@ -161,7 +162,8 @@ public abstract class FlowModBuilder { ...@@ -161,7 +162,8 @@ public abstract class FlowModBuilder {
161 ip = (IPCriterion) c; 162 ip = (IPCriterion) c;
162 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) { 163 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) {
163 IpAddress maskAddr = 164 IpAddress maskAddr =
164 - IpAddress.makeMaskPrefix(ip.ip().prefixLength()); 165 + IpAddress.makeMaskPrefix(ip.ip().address().version(),
166 + ip.ip().prefixLength());
165 Masked<IPv4Address> maskedIp = 167 Masked<IPv4Address> maskedIp =
166 Masked.of(IPv4Address.of(ip.ip().address().toInt()), 168 Masked.of(IPv4Address.of(ip.ip().address().toInt()),
167 IPv4Address.of(maskAddr.toInt())); 169 IPv4Address.of(maskAddr.toInt()));
......
...@@ -302,7 +302,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -302,7 +302,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
302 } 302 }
303 303
304 @Override 304 @Override
305 - public void roleAssertFailed(Dpid dpid, RoleState role) {} 305 + public void receivedRoleReply(Dpid dpid, RoleState requested,
306 + RoleState response) {
307 + // Do nothing here for now.
308 + }
306 309
307 private synchronized void pushFlowMetrics(Dpid dpid, OFStatsReply stats) { 310 private synchronized void pushFlowMetrics(Dpid dpid, OFStatsReply stats) {
308 if (stats.getStatsType() != OFStatsType.FLOW) { 311 if (stats.getStatsType() != OFStatsType.FLOW) {
......
...@@ -126,7 +126,8 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid ...@@ -126,7 +126,8 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid
126 if (eth.getEtherType() == Ethernet.TYPE_ARP) { 126 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
127 ARP arp = (ARP) eth.getPayload(); 127 ARP arp = (ARP) eth.getPayload();
128 IpAddress ip = 128 IpAddress ip =
129 - IpAddress.valueOf(arp.getSenderProtocolAddress()); 129 + IpAddress.valueOf(IpAddress.Version.INET,
130 + arp.getSenderProtocolAddress());
130 HostDescription hdescr = 131 HostDescription hdescr =
131 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 132 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
132 providerService.hostDetected(hid, hdescr); 133 providerService.hostDetected(hid, hdescr);
......
...@@ -213,8 +213,8 @@ public class OpenFlowHostProviderTest { ...@@ -213,8 +213,8 @@ public class OpenFlowHostProviderTest {
213 Ethernet eth = new Ethernet(); 213 Ethernet eth = new Ethernet();
214 eth.setEtherType(Ethernet.TYPE_ARP) 214 eth.setEtherType(Ethernet.TYPE_ARP)
215 .setVlanID(VLAN.toShort()) 215 .setVlanID(VLAN.toShort())
216 - .setSourceMACAddress(MAC.toBytes()) 216 + .setSourceMACAddress(MAC)
217 - .setDestinationMACAddress(BCMAC.getAddress()) 217 + .setDestinationMACAddress(BCMAC)
218 .setPayload(arp); 218 .setPayload(arp);
219 219
220 return eth; 220 return eth;
......
...@@ -160,7 +160,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -160,7 +160,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
160 } 160 }
161 161
162 @Override 162 @Override
163 - public void roleAssertFailed(Dpid dpid, RoleState role) { 163 + public void receivedRoleReply(Dpid dpid, RoleState requested,
164 + RoleState response) {
164 // do nothing for this. 165 // do nothing for this.
165 } 166 }
166 167
......
...@@ -475,11 +475,12 @@ public class OpenFlowLinkProviderTest { ...@@ -475,11 +475,12 @@ public class OpenFlowLinkProviderTest {
475 } 475 }
476 476
477 @Override 477 @Override
478 - public void disconnectSwitch() { 478 + public boolean isConnected() {
479 + return true;
479 } 480 }
480 481
481 @Override 482 @Override
482 - public void returnRoleAssertFailure(RoleState role) { 483 + public void disconnectSwitch() {
483 } 484 }
484 485
485 @Override 486 @Override
...@@ -487,5 +488,9 @@ public class OpenFlowLinkProviderTest { ...@@ -487,5 +488,9 @@ public class OpenFlowLinkProviderTest {
487 return false; 488 return false;
488 } 489 }
489 490
491 + @Override
492 + public void returnRoleReply(RoleState requested, RoleState reponse) {
493 + }
494 +
490 } 495 }
491 } 496 }
......
...@@ -406,11 +406,12 @@ public class OpenFlowPacketProviderTest { ...@@ -406,11 +406,12 @@ public class OpenFlowPacketProviderTest {
406 } 406 }
407 407
408 @Override 408 @Override
409 - public void disconnectSwitch() { 409 + public boolean isConnected() {
410 + return true;
410 } 411 }
411 412
412 @Override 413 @Override
413 - public void returnRoleAssertFailure(RoleState role) { 414 + public void disconnectSwitch() {
414 } 415 }
415 416
416 @Override 417 @Override
...@@ -418,6 +419,10 @@ public class OpenFlowPacketProviderTest { ...@@ -418,6 +419,10 @@ public class OpenFlowPacketProviderTest {
418 return false; 419 return false;
419 } 420 }
420 421
422 + @Override
423 + public void returnRoleReply(RoleState requested, RoleState reponse) {
424 + }
425 +
421 } 426 }
422 427
423 } 428 }
......
1 +#!/bin/bash
2 +
3 +validate_number () {
4 + local re="^[0-9]+$"
5 + if [[ ! $1 =~ $re ]] ; then
6 + return 1
7 + fi
8 +
9 + return 0
10 +}
11 +
12 +find_node () {
13 + if validate_number $1 ; then
14 + # input is a number, try to find if an OC node is defined
15 +
16 + oc_try="OC$1"
17 + node=${!oc_try}
18 +
19 + if [ -n "$node" ]; then
20 + # node lookup succeeded, return node
21 + echo $node
22 + else
23 + # node lookup failed, return original input
24 + echo $1
25 + fi
26 +
27 + else
28 + echo $1
29 + fi
30 +
31 + return 0
32 +}
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
5 5
6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 . $ONOS_ROOT/tools/build/envDefaults 7 . $ONOS_ROOT/tools/build/envDefaults
8 +. $ONOS_ROOT/tools/test/bin/find-node.sh
8 9
9 [ "$1" = "-w" ] && shift && onos-wait-for-start $1 10 [ "$1" = "-w" ] && shift && onos-wait-for-start $1
10 11
11 -[ -n "$1" ] && OCI=$1 && shift 12 +[ -n "$1" ] && OCI=$(find_node $1) && shift
12 client -h $OCI -u karaf "$@" 2>/dev/null 13 client -h $OCI -u karaf "$@" 2>/dev/null
......
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
5 5
6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 6 [ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 . $ONOS_ROOT/tools/build/envDefaults 7 . $ONOS_ROOT/tools/build/envDefaults
8 +. $ONOS_ROOT/tools/test/bin/find-node.sh
8 9
9 less=0 10 less=0
10 -
11 [ "$1" = "-l" ] && shift && less=1 11 [ "$1" = "-l" ] && shift && less=1
12 12
13 -remote=$ONOS_USER@${1:-$OCI} 13 +remote=$(find_node $1)
14 +
15 +remote=$ONOS_USER@${remote:-$OCI}
14 instance=$2 16 instance=$2
15 17
16 [ -n "$instance" ] && \ 18 [ -n "$instance" ] && \
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
18 18
19 package org.onlab.packet; 19 package org.onlab.packet;
20 20
21 +import static com.google.common.base.Preconditions.checkNotNull;
22 +
21 import java.nio.ByteBuffer; 23 import java.nio.ByteBuffer;
22 import java.util.Arrays; 24 import java.util.Arrays;
23 import java.util.HashMap; 25 import java.util.HashMap;
...@@ -86,6 +88,17 @@ public class Ethernet extends BasePacket { ...@@ -86,6 +88,17 @@ public class Ethernet extends BasePacket {
86 * @param destMac the destination MAC to set 88 * @param destMac the destination MAC to set
87 * @return the Ethernet frame 89 * @return the Ethernet frame
88 */ 90 */
91 + public Ethernet setDestinationMACAddress(final MacAddress destMac) {
92 + this.destinationMACAddress = checkNotNull(destMac);
93 + return this;
94 + }
95 +
96 + /**
97 + * Sets the destination MAC address.
98 + *
99 + * @param destMac the destination MAC to set
100 + * @return the Ethernet frame
101 + */
89 public Ethernet setDestinationMACAddress(final byte[] destMac) { 102 public Ethernet setDestinationMACAddress(final byte[] destMac) {
90 this.destinationMACAddress = MacAddress.valueOf(destMac); 103 this.destinationMACAddress = MacAddress.valueOf(destMac);
91 return this; 104 return this;
...@@ -126,6 +139,17 @@ public class Ethernet extends BasePacket { ...@@ -126,6 +139,17 @@ public class Ethernet extends BasePacket {
126 * @param sourceMac the source MAC to set 139 * @param sourceMac the source MAC to set
127 * @return the Ethernet frame 140 * @return the Ethernet frame
128 */ 141 */
142 + public Ethernet setSourceMACAddress(final MacAddress sourceMac) {
143 + this.sourceMACAddress = checkNotNull(sourceMac);
144 + return this;
145 + }
146 +
147 + /**
148 + * Sets the source MAC address.
149 + *
150 + * @param sourceMac the source MAC to set
151 + * @return the Ethernet frame
152 + */
129 public Ethernet setSourceMACAddress(final byte[] sourceMac) { 153 public Ethernet setSourceMACAddress(final byte[] sourceMac) {
130 this.sourceMACAddress = MacAddress.valueOf(sourceMac); 154 this.sourceMACAddress = MacAddress.valueOf(sourceMac);
131 return this; 155 return this;
......
...@@ -15,10 +15,18 @@ ...@@ -15,10 +15,18 @@
15 */ 15 */
16 package org.onlab.packet; 16 package org.onlab.packet;
17 17
18 +import java.net.InetAddress;
19 +import java.net.Inet4Address;
20 +import java.net.Inet6Address;
21 +import java.net.UnknownHostException;
18 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
19 import java.util.Arrays; 23 import java.util.Arrays;
20 import java.util.Objects; 24 import java.util.Objects;
21 -import static com.google.common.base.Preconditions.checkNotNull; 25 +
26 +import com.google.common.net.InetAddresses;
27 +import com.google.common.primitives.UnsignedBytes;
28 +
29 +import static com.google.common.base.Preconditions.checkState;
22 30
23 /** 31 /**
24 * A class representing an IP address. 32 * A class representing an IP address.
...@@ -40,13 +48,74 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -40,13 +48,74 @@ public final class IpAddress implements Comparable<IpAddress> {
40 /** 48 /**
41 * Constructor for given IP address version and address octets. 49 * Constructor for given IP address version and address octets.
42 * 50 *
51 + * @param version the IP address version
43 * @param value the IP address value stored in network byte order 52 * @param value the IP address value stored in network byte order
44 * (i.e., the most significant byte first) 53 * (i.e., the most significant byte first)
45 - * @param value the IP address value 54 + * @throws IllegalArgumentException if the arguments are invalid
46 */ 55 */
47 private IpAddress(Version version, byte[] value) { 56 private IpAddress(Version version, byte[] value) {
57 + checkArguments(version, value, 0);
48 this.version = version; 58 this.version = version;
59 + switch (version) {
60 + case INET:
49 this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH); 61 this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH);
62 + break;
63 + case INET6:
64 + this.octets = Arrays.copyOf(value, INET6_BYTE_LENGTH);
65 + break;
66 + default:
67 + // Should not be reached
68 + this.octets = null;
69 + break;
70 + }
71 + }
72 +
73 + /**
74 + * Returns the IP version of this address.
75 + *
76 + * @return the version
77 + */
78 + public Version version() {
79 + return this.version;
80 + }
81 +
82 + /**
83 + * Returns the IP address as a byte array.
84 + *
85 + * @return a byte array
86 + */
87 + public byte[] toOctets() {
88 + return Arrays.copyOf(octets, octets.length);
89 + }
90 +
91 + /**
92 + * Returns the integral value of this IP address.
93 + * TODO: This method should be moved to Ip4Address.
94 + *
95 + * @return the IP address's value as an integer
96 + */
97 + public int toInt() {
98 + ByteBuffer bb = ByteBuffer.wrap(octets);
99 + return bb.getInt();
100 + }
101 +
102 + /**
103 + * Computes the IP address byte length for a given IP version.
104 + *
105 + * @param version the IP version
106 + * @return the IP address byte length for the IP version
107 + * @throws IllegalArgumentException if the IP version is invalid
108 + */
109 + public static int byteLength(Version version) {
110 + switch (version) {
111 + case INET:
112 + return INET_BYTE_LENGTH;
113 + case INET6:
114 + return INET6_BYTE_LENGTH;
115 + default:
116 + String msg = "Invalid IP version " + version;
117 + throw new IllegalArgumentException(msg);
118 + }
50 } 119 }
51 120
52 /** 121 /**
...@@ -64,13 +133,14 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -64,13 +133,14 @@ public final class IpAddress implements Comparable<IpAddress> {
64 /** 133 /**
65 * Converts a byte array into an IP address. 134 * Converts a byte array into an IP address.
66 * 135 *
136 + * @param version the IP address version
67 * @param value the IP address value stored in network byte order 137 * @param value the IP address value stored in network byte order
68 * (i.e., the most significant byte first) 138 * (i.e., the most significant byte first)
69 * @return an IP address 139 * @return an IP address
140 + * @throws IllegalArgumentException if the arguments are invalid
70 */ 141 */
71 - public static IpAddress valueOf(byte[] value) { 142 + public static IpAddress valueOf(Version version, byte[] value) {
72 - checkNotNull(value); 143 + return new IpAddress(version, value);
73 - return new IpAddress(Version.INET, value);
74 } 144 }
75 145
76 /** 146 /**
...@@ -80,96 +150,102 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -80,96 +150,102 @@ public final class IpAddress implements Comparable<IpAddress> {
80 * The IP address is stored in network byte order (i.e., the most 150 * The IP address is stored in network byte order (i.e., the most
81 * significant byte first). 151 * significant byte first).
82 * </p> 152 * </p>
153 + * @param version the IP address version
83 * @param value the value to use 154 * @param value the value to use
84 * @param offset the offset in bytes from the beginning of the byte array 155 * @param offset the offset in bytes from the beginning of the byte array
85 * @return an IP address 156 * @return an IP address
157 + * @throws IllegalArgumentException if the arguments are invalid
86 */ 158 */
87 - public static IpAddress valueOf(byte[] value, int offset) { 159 + public static IpAddress valueOf(Version version, byte[] value,
88 - // Verify the arguments 160 + int offset) {
89 - if ((offset < 0) || (offset + INET_BYTE_LENGTH > value.length)) { 161 + checkArguments(version, value, offset);
90 - String msg;
91 - if (value.length < INET_BYTE_LENGTH) {
92 - msg = "Invalid IPv4 address array: array length: " +
93 - value.length + ". Must be at least " + INET_BYTE_LENGTH;
94 - } else {
95 - msg = "Invalid IPv4 address array: array offset: " +
96 - offset + ". Must be in the interval [0, " +
97 - (value.length - INET_BYTE_LENGTH) + "]";
98 - }
99 - throw new IllegalArgumentException(msg);
100 - }
101 -
102 byte[] bc = Arrays.copyOfRange(value, offset, value.length); 162 byte[] bc = Arrays.copyOfRange(value, offset, value.length);
103 - return IpAddress.valueOf(bc); 163 + return IpAddress.valueOf(version, bc);
104 } 164 }
105 165
106 /** 166 /**
107 - * Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. 167 + * Converts an InetAddress into an IP address.
108 * 168 *
109 - * @param address an IP address in string form, e.g. "10.0.0.1" 169 + * @param inetAddress the InetAddress value to use
110 * @return an IP address 170 * @return an IP address
171 + * @throws IllegalArgumentException if the argument is invalid
111 */ 172 */
112 - public static IpAddress valueOf(String address) { 173 + public static IpAddress valueOf(InetAddress inetAddress) {
113 - final String[] net = address.split("\\."); 174 + byte[] bytes = inetAddress.getAddress();
114 - if (net.length != INET_BYTE_LENGTH) { 175 + if (inetAddress instanceof Inet4Address) {
115 - String msg = "Malformed IPv4 address string: " + address + "." + 176 + return new IpAddress(Version.INET, bytes);
116 - "Address must have four decimal values separated by dots (.)";
117 - throw new IllegalArgumentException(msg);
118 } 177 }
119 - final byte[] bytes = new byte[INET_BYTE_LENGTH]; 178 + if (inetAddress instanceof Inet6Address) {
120 - for (int i = 0; i < INET_BYTE_LENGTH; i++) { 179 + return new IpAddress(Version.INET6, bytes);
121 - bytes[i] = (byte) Short.parseShort(net[i], 10);
122 } 180 }
181 + // Use the number of bytes as a hint
182 + if (bytes.length == INET_BYTE_LENGTH) {
123 return new IpAddress(Version.INET, bytes); 183 return new IpAddress(Version.INET, bytes);
124 } 184 }
125 - 185 + if (bytes.length == INET6_BYTE_LENGTH) {
126 - /** 186 + return new IpAddress(Version.INET6, bytes);
127 - * Returns the IP version of this address.
128 - *
129 - * @return the version
130 - */
131 - public Version version() {
132 - return this.version;
133 } 187 }
134 - 188 + final String msg = "Unrecognized IP version address string: " +
135 - /** 189 + inetAddress.toString();
136 - * Returns the IP address as a byte array. 190 + throw new IllegalArgumentException(msg);
137 - *
138 - * @return a byte array
139 - */
140 - public byte[] toOctets() {
141 - return Arrays.copyOf(this.octets, INET_BYTE_LENGTH);
142 } 191 }
143 192
144 /** 193 /**
145 - * Returns the integral value of this IP address. 194 + * Converts an IPv4 or IPv6 string literal (e.g., "10.2.3.4" or
195 + * "1111:2222::8888") into an IP address.
146 * 196 *
147 - * @return the IP address's value as an integer 197 + * @param value an IP address value in string form
198 + * @return an IP address
199 + * @throws IllegalArgumentException if the argument is invalid
148 */ 200 */
149 - public int toInt() { 201 + public static IpAddress valueOf(String value) {
150 - ByteBuffer bb = ByteBuffer.wrap(octets); 202 + InetAddress inetAddress = null;
151 - return bb.getInt(); 203 + try {
204 + inetAddress = InetAddresses.forString(value);
205 + } catch (IllegalArgumentException e) {
206 + final String msg = "Invalid IP address string: " + value;
207 + throw new IllegalArgumentException(msg);
208 + }
209 + return valueOf(inetAddress);
152 } 210 }
153 211
154 /** 212 /**
155 * Creates an IP network mask prefix. 213 * Creates an IP network mask prefix.
156 * 214 *
215 + * @param version the IP address version
157 * @param prefixLength the length of the mask prefix. Must be in the 216 * @param prefixLength the length of the mask prefix. Must be in the
158 - * interval [0, 32] for IPv4 217 + * interval [0, 32] for IPv4, or [0, 128] for IPv6
159 * @return a new IP address that contains a mask prefix of the 218 * @return a new IP address that contains a mask prefix of the
160 * specified length 219 * specified length
220 + * @throws IllegalArgumentException if the arguments are invalid
161 */ 221 */
162 - public static IpAddress makeMaskPrefix(int prefixLength) { 222 + public static IpAddress makeMaskPrefix(Version version, int prefixLength) {
223 + int addrByteLength = byteLength(version);
224 + int addrBitLength = addrByteLength * Byte.SIZE;
225 +
163 // Verify the prefix length 226 // Verify the prefix length
164 - if ((prefixLength < 0) || (prefixLength > INET_BIT_LENGTH)) { 227 + if ((prefixLength < 0) || (prefixLength > addrBitLength)) {
165 - final String msg = "Invalid IPv4 prefix length: " + prefixLength + 228 + final String msg = "Invalid IP prefix length: " + prefixLength +
166 - ". Must be in the interval [0, 32]."; 229 + ". Must be in the interval [0, " + addrBitLength + "].";
167 throw new IllegalArgumentException(msg); 230 throw new IllegalArgumentException(msg);
168 } 231 }
169 232
170 - long v = 233 + // Number of bytes and extra bits that should be all 1s
171 - (0xffffffffL << (INET_BIT_LENGTH - prefixLength)) & 0xffffffffL; 234 + int maskBytes = prefixLength / Byte.SIZE;
172 - return IpAddress.valueOf((int) v); 235 + int maskBits = prefixLength % Byte.SIZE;
236 + byte[] mask = new byte[addrByteLength];
237 +
238 + // Set the bytes and extra bits to 1s
239 + for (int i = 0; i < maskBytes; i++) {
240 + mask[i] = (byte) 0xff; // Set mask bytes to 1s
241 + }
242 + for (int i = maskBytes; i < addrByteLength; i++) {
243 + mask[i] = 0; // Set remaining bytes to 0s
244 + }
245 + if (maskBits > 0) {
246 + mask[maskBytes] = (byte) (0xff << (Byte.SIZE - maskBits));
247 + }
248 + return new IpAddress(version, mask);
173 } 249 }
174 250
175 /** 251 /**
...@@ -178,27 +254,38 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -178,27 +254,38 @@ public final class IpAddress implements Comparable<IpAddress> {
178 * 254 *
179 * @param addr the address to mask 255 * @param addr the address to mask
180 * @param prefixLength the length of the mask prefix. Must be in the 256 * @param prefixLength the length of the mask prefix. Must be in the
181 - * interval [0, 32] for IPv4 257 + * interval [0, 32] for IPv4, or [0, 128] for IPv6
182 * @return a new IP address that is masked with a mask prefix of the 258 * @return a new IP address that is masked with a mask prefix of the
183 * specified length 259 * specified length
260 + * @throws IllegalArgumentException if the prefix length is invalid
184 */ 261 */
185 public static IpAddress makeMaskedAddress(final IpAddress addr, 262 public static IpAddress makeMaskedAddress(final IpAddress addr,
186 int prefixLength) { 263 int prefixLength) {
187 - IpAddress mask = IpAddress.makeMaskPrefix(prefixLength); 264 + IpAddress mask = IpAddress.makeMaskPrefix(addr.version(),
188 - byte[] net = new byte[INET_BYTE_LENGTH]; 265 + prefixLength);
266 + byte[] net = new byte[mask.octets.length];
189 267
190 // Mask each byte 268 // Mask each byte
191 - for (int i = 0; i < INET_BYTE_LENGTH; i++) { 269 + for (int i = 0; i < net.length; i++) {
192 net[i] = (byte) (addr.octets[i] & mask.octets[i]); 270 net[i] = (byte) (addr.octets[i] & mask.octets[i]);
193 } 271 }
194 - return IpAddress.valueOf(net); 272 + return IpAddress.valueOf(addr.version(), net);
195 } 273 }
196 274
197 @Override 275 @Override
198 public int compareTo(IpAddress o) { 276 public int compareTo(IpAddress o) {
199 - Long lv = ((long) this.toInt()) & 0xffffffffL; 277 + // Compare first the version
200 - Long rv = ((long) o.toInt()) & 0xffffffffL; 278 + if (this.version != o.version) {
201 - return lv.compareTo(rv); 279 + return this.version.compareTo(o.version);
280 + }
281 +
282 + // Compare the bytes, one-by-one
283 + for (int i = 0; i < this.octets.length; i++) {
284 + if (this.octets[i] != o.octets[i]) {
285 + return UnsignedBytes.compare(this.octets[i], o.octets[i]);
286 + }
287 + }
288 + return 0; // Equal
202 } 289 }
203 290
204 @Override 291 @Override
...@@ -222,18 +309,67 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -222,18 +309,67 @@ public final class IpAddress implements Comparable<IpAddress> {
222 @Override 309 @Override
223 /* 310 /*
224 * (non-Javadoc) 311 * (non-Javadoc)
225 - * The format is "x.x.x.x" for IPv4 addresses. 312 + * The string representation of the IP address: "x.x.x.x" for IPv4
313 + * addresses, or ':' separated string for IPv6 addresses.
226 * 314 *
227 * @see java.lang.Object#toString() 315 * @see java.lang.Object#toString()
228 */ 316 */
229 public String toString() { 317 public String toString() {
230 - final StringBuilder builder = new StringBuilder(); 318 + InetAddress inetAddr = null;
231 - for (final byte b : this.octets) { 319 + try {
232 - if (builder.length() > 0) { 320 + inetAddr = InetAddress.getByAddress(octets);
233 - builder.append("."); 321 + } catch (UnknownHostException e) {
322 + // Should never happen
323 + checkState(false, "Internal error: Ip6Address.toString()");
324 + return "[Invalid IP Address]";
325 + }
326 + return InetAddresses.toAddrString(inetAddr);
234 } 327 }
235 - builder.append(String.format("%d", b & 0xff)); 328 +
329 + /**
330 + * Gets the IP address name for the IP address version.
331 + *
332 + * @param version the IP address version
333 + * @return the IP address name for the IP address version
334 + */
335 + private static String addressName(Version version) {
336 + switch (version) {
337 + case INET:
338 + return "IPv4";
339 + case INET6:
340 + return "IPv6";
341 + default:
342 + break;
343 + }
344 + return "UnknownIP(" + version + ")";
345 + }
346 +
347 + /**
348 + * Checks whether the arguments are valid.
349 + *
350 + * @param version the IP address version
351 + * @param value the IP address value stored in a byte array
352 + * @param offset the offset in bytes from the beginning of the byte
353 + * array with the address
354 + * @throws IllegalArgumentException if any of the arguments is invalid
355 + */
356 + private static void checkArguments(Version version, byte[] value,
357 + int offset) {
358 + // Check the offset and byte array length
359 + int addrByteLength = byteLength(version);
360 + if ((offset < 0) || (offset + addrByteLength > value.length)) {
361 + String msg;
362 + if (value.length < addrByteLength) {
363 + msg = "Invalid " + addressName(version) +
364 + " address array: array length: " + value.length +
365 + ". Must be at least " + addrByteLength;
366 + } else {
367 + msg = "Invalid " + addressName(version) +
368 + " address array: array offset: " + offset +
369 + ". Must be in the interval [0, " +
370 + (value.length - addrByteLength) + "]";
371 + }
372 + throw new IllegalArgumentException(msg);
236 } 373 }
237 - return builder.toString();
238 } 374 }
239 } 375 }
......
...@@ -76,12 +76,15 @@ public final class IpPrefix { ...@@ -76,12 +76,15 @@ public final class IpPrefix {
76 /** 76 /**
77 * Converts a byte array and a prefix length into an IP prefix. 77 * Converts a byte array and a prefix length into an IP prefix.
78 * 78 *
79 + * @param version the IP address version
79 * @param address the IP address value stored in network byte order 80 * @param address the IP address value stored in network byte order
80 * @param prefixLength the prefix length 81 * @param prefixLength the prefix length
81 * @return an IP prefix 82 * @return an IP prefix
82 */ 83 */
83 - public static IpPrefix valueOf(byte[] address, int prefixLength) { 84 + public static IpPrefix valueOf(IpAddress.Version version, byte[] address,
84 - return new IpPrefix(IpAddress.valueOf(address), prefixLength); 85 + int prefixLength) {
86 + return new IpPrefix(IpAddress.valueOf(version, address),
87 + prefixLength);
85 } 88 }
86 89
87 /** 90 /**
......
...@@ -25,9 +25,6 @@ public class MacAddress { ...@@ -25,9 +25,6 @@ public class MacAddress {
25 public static final MacAddress ZERO = valueOf("00:00:00:00:00:00"); 25 public static final MacAddress ZERO = valueOf("00:00:00:00:00:00");
26 public static final MacAddress BROADCAST = valueOf("ff:ff:ff:ff:ff:ff"); 26 public static final MacAddress BROADCAST = valueOf("ff:ff:ff:ff:ff:ff");
27 27
28 - public static final byte[] ZERO_MAC_ADDRESS = ZERO.getAddress();
29 - public static final byte[] BROADCAST_MAC = BROADCAST.getAddress();
30 -
31 private static final byte[] LL = new byte[]{ 28 private static final byte[] LL = new byte[]{
32 0x01, (byte) 0x80, (byte) 0xc2, 0x00, 0x00, 29 0x01, (byte) 0x80, (byte) 0xc2, 0x00, 0x00,
33 0x00, 0x0e, 0x03 30 0x00, 0x0e, 0x03
...@@ -217,8 +214,4 @@ public class MacAddress { ...@@ -217,8 +214,4 @@ public class MacAddress {
217 } 214 }
218 return builder.toString(); 215 return builder.toString();
219 } 216 }
220 -
221 - public byte[] getAddress() {
222 - return this.address;
223 - }
224 } 217 }
......
...@@ -64,7 +64,7 @@ public class ONOSLLDP extends LLDP { ...@@ -64,7 +64,7 @@ public class ONOSLLDP extends LLDP {
64 setName(DEFAULT_NAME); 64 setName(DEFAULT_NAME);
65 setDevice(DEFAULT_DEVICE); 65 setDevice(DEFAULT_DEVICE);
66 setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV)); 66 setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV));
67 - setTtl(new LLDPTLV().setType((byte) TTL_TLV_TYPE) 67 + setTtl(new LLDPTLV().setType(TTL_TLV_TYPE)
68 .setLength((short) ttlValue.length) 68 .setLength((short) ttlValue.length)
69 .setValue(ttlValue)); 69 .setValue(ttlValue));
70 70
...@@ -94,7 +94,7 @@ public class ONOSLLDP extends LLDP { ...@@ -94,7 +94,7 @@ public class ONOSLLDP extends LLDP {
94 public void setChassisId(final ChassisId chassisId) { 94 public void setChassisId(final ChassisId chassisId) {
95 MacAddress chassisMac = MacAddress.valueOf(chassisId.value()); 95 MacAddress chassisMac = MacAddress.valueOf(chassisId.value());
96 byte[] chassis = ArrayUtils.addAll(new byte[] {CHASSIS_TLV_SUBTYPE}, 96 byte[] chassis = ArrayUtils.addAll(new byte[] {CHASSIS_TLV_SUBTYPE},
97 - chassisMac.getAddress()); 97 + chassisMac.toBytes());
98 98
99 LLDPTLV chassisTLV = new LLDPTLV(); 99 LLDPTLV chassisTLV = new LLDPTLV();
100 chassisTLV.setLength(CHASSIS_TLV_SIZE); 100 chassisTLV.setLength(CHASSIS_TLV_SIZE);
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.packet;
17 +
18 +import com.google.common.net.InetAddresses;
19 +import com.google.common.testing.EqualsTester;
20 +import org.junit.Test;
21 +
22 +import java.net.InetAddress;
23 +
24 +import static org.hamcrest.Matchers.is;
25 +import static org.junit.Assert.assertThat;
26 +import static org.junit.Assert.assertTrue;
27 +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
28 +
29 +/**
30 + * Tests for class {@link IpAddress}.
31 + */
32 +public class IpAddressTest {
33 + /**
34 + * Tests the immutability of {@link IpAddress}.
35 + */
36 + @Test
37 + public void testImmutable() {
38 + assertThatClassIsImmutable(IpAddress.class);
39 + }
40 +
41 + /**
42 + * Tests the length of the address in bytes (octets).
43 + */
44 + @Test
45 + public void testAddrByteLength() {
46 + assertThat(IpAddress.INET_BYTE_LENGTH, is(4));
47 + assertThat(IpAddress.INET6_BYTE_LENGTH, is(16));
48 + assertThat(IpAddress.byteLength(IpAddress.Version.INET), is(4));
49 + assertThat(IpAddress.byteLength(IpAddress.Version.INET6), is(16));
50 + }
51 +
52 + /**
53 + * Tests the length of the address in bits.
54 + */
55 + @Test
56 + public void testAddrBitLength() {
57 + assertThat(IpAddress.INET_BIT_LENGTH, is(32));
58 + assertThat(IpAddress.INET6_BIT_LENGTH, is(128));
59 + }
60 +
61 + /**
62 + * Tests returning the IP address version.
63 + */
64 + @Test
65 + public void testVersion() {
66 + IpAddress ipAddress;
67 +
68 + // IPv4
69 + ipAddress = IpAddress.valueOf("0.0.0.0");
70 + assertThat(ipAddress.version(), is(IpAddress.Version.INET));
71 +
72 + // IPv6
73 + ipAddress = IpAddress.valueOf("::");
74 + assertThat(ipAddress.version(), is(IpAddress.Version.INET6));
75 + }
76 +
77 + /**
78 + * Tests returning an IPv4 address as a byte array.
79 + */
80 + @Test
81 + public void testAddressToOctetsIPv4() {
82 + IpAddress ipAddress;
83 +
84 + final byte[] value1 = new byte[] {1, 2, 3, 4};
85 + ipAddress = IpAddress.valueOf("1.2.3.4");
86 + assertThat(ipAddress.toOctets(), is(value1));
87 +
88 + final byte[] value2 = new byte[] {0, 0, 0, 0};
89 + ipAddress = IpAddress.valueOf("0.0.0.0");
90 + assertThat(ipAddress.toOctets(), is(value2));
91 +
92 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
93 + (byte) 0xff, (byte) 0xff};
94 + ipAddress = IpAddress.valueOf("255.255.255.255");
95 + assertThat(ipAddress.toOctets(), is(value3));
96 + }
97 +
98 + /**
99 + * Tests returning an IPv6 address as a byte array.
100 + */
101 + @Test
102 + public void testAddressToOctetsIPv6() {
103 + IpAddress ipAddress;
104 +
105 + final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22,
106 + 0x33, 0x33, 0x44, 0x44,
107 + 0x55, 0x55, 0x66, 0x66,
108 + 0x77, 0x77,
109 + (byte) 0x88, (byte) 0x88};
110 + ipAddress =
111 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
112 + assertThat(ipAddress.toOctets(), is(value1));
113 +
114 + final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00,
115 + 0x00, 0x00, 0x00, 0x00,
116 + 0x00, 0x00, 0x00, 0x00,
117 + 0x00, 0x00, 0x00, 0x00};
118 + ipAddress = IpAddress.valueOf("::");
119 + assertThat(ipAddress.toOctets(), is(value2));
120 +
121 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
122 + (byte) 0xff, (byte) 0xff,
123 + (byte) 0xff, (byte) 0xff,
124 + (byte) 0xff, (byte) 0xff,
125 + (byte) 0xff, (byte) 0xff,
126 + (byte) 0xff, (byte) 0xff,
127 + (byte) 0xff, (byte) 0xff,
128 + (byte) 0xff, (byte) 0xff};
129 + ipAddress =
130 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
131 + assertThat(ipAddress.toOctets(), is(value3));
132 + }
133 +
134 + /**
135 + * Tests returning an IPv4 address asn an integer.
136 + */
137 + @Test
138 + public void testToint() {
139 + IpAddress ipAddress;
140 +
141 + ipAddress = IpAddress.valueOf("1.2.3.4");
142 + assertThat(ipAddress.toInt(), is(0x01020304));
143 +
144 + ipAddress = IpAddress.valueOf("0.0.0.0");
145 + assertThat(ipAddress.toInt(), is(0));
146 +
147 + ipAddress = IpAddress.valueOf("255.255.255.255");
148 + assertThat(ipAddress.toInt(), is(-1));
149 + }
150 +
151 + /**
152 + * Tests valueOf() converter for an integer value.
153 + */
154 + @Test
155 + public void testValueOfForInteger() {
156 + IpAddress ipAddress;
157 +
158 + ipAddress = IpAddress.valueOf(0x01020304);
159 + assertThat(ipAddress.toString(), is("1.2.3.4"));
160 +
161 + ipAddress = IpAddress.valueOf(0);
162 + assertThat(ipAddress.toString(), is("0.0.0.0"));
163 +
164 + ipAddress = IpAddress.valueOf(0xffffffff);
165 + assertThat(ipAddress.toString(), is("255.255.255.255"));
166 + }
167 +
168 + /**
169 + * Tests valueOf() converter for IPv4 byte array.
170 + */
171 + @Test
172 + public void testValueOfByteArrayIPv4() {
173 + IpAddress ipAddress;
174 +
175 + final byte[] value1 = new byte[] {1, 2, 3, 4};
176 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value1);
177 + assertThat(ipAddress.toString(), is("1.2.3.4"));
178 +
179 + final byte[] value2 = new byte[] {0, 0, 0, 0};
180 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value2);
181 + assertThat(ipAddress.toString(), is("0.0.0.0"));
182 +
183 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
184 + (byte) 0xff, (byte) 0xff};
185 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value3);
186 + assertThat(ipAddress.toString(), is("255.255.255.255"));
187 + }
188 +
189 + /**
190 + * Tests valueOf() converter for IPv6 byte array.
191 + */
192 + @Test
193 + public void testValueOfByteArrayIPv6() {
194 + IpAddress ipAddress;
195 +
196 + final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22,
197 + 0x33, 0x33, 0x44, 0x44,
198 + 0x55, 0x55, 0x66, 0x66,
199 + 0x77, 0x77,
200 + (byte) 0x88, (byte) 0x88};
201 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value1);
202 + assertThat(ipAddress.toString(),
203 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
204 +
205 + final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00,
206 + 0x00, 0x00, 0x00, 0x00,
207 + 0x00, 0x00, 0x00, 0x00,
208 + 0x00, 0x00, 0x00, 0x00};
209 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value2);
210 + assertThat(ipAddress.toString(), is("::"));
211 +
212 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
213 + (byte) 0xff, (byte) 0xff,
214 + (byte) 0xff, (byte) 0xff,
215 + (byte) 0xff, (byte) 0xff,
216 + (byte) 0xff, (byte) 0xff,
217 + (byte) 0xff, (byte) 0xff,
218 + (byte) 0xff, (byte) 0xff,
219 + (byte) 0xff, (byte) 0xff};
220 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value3);
221 + assertThat(ipAddress.toString(),
222 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
223 + }
224 +
225 + /**
226 + * Tests invalid valueOf() converter for a null array for IPv4.
227 + */
228 + @Test(expected = NullPointerException.class)
229 + public void testInvalidValueOfNullArrayIPv4() {
230 + IpAddress ipAddress;
231 +
232 + final byte[] fromArray = null;
233 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, fromArray);
234 + }
235 +
236 + /**
237 + * Tests invalid valueOf() converter for a null array for IPv6.
238 + */
239 + @Test(expected = NullPointerException.class)
240 + public void testInvalidValueOfNullArrayIPv6() {
241 + IpAddress ipAddress;
242 +
243 + final byte[] fromArray = null;
244 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, fromArray);
245 + }
246 +
247 + /**
248 + * Tests invalid valueOf() converger for an array that is too short for
249 + * IPv4.
250 + */
251 + @Test(expected = IllegalArgumentException.class)
252 + public void testInvalidValueOfShortArrayIPv4() {
253 + IpAddress ipAddress;
254 +
255 + final byte[] fromArray = new byte[] {1, 2, 3};
256 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, fromArray);
257 + }
258 +
259 + /**
260 + * Tests invalid valueOf() converger for an array that is too short for
261 + * IPv6.
262 + */
263 + @Test(expected = IllegalArgumentException.class)
264 + public void testInvalidValueOfShortArrayIPv6() {
265 + IpAddress ipAddress;
266 +
267 + final byte[] fromArray = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
268 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, fromArray);
269 + }
270 +
271 + /**
272 + * Tests valueOf() converter for IPv4 byte array and an offset.
273 + */
274 + @Test
275 + public void testValueOfByteArrayOffsetIPv4() {
276 + IpAddress ipAddress;
277 +
278 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
279 + 1, 2, 3, 4,
280 + 44, 55}; // Extra bytes
281 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value1, 3);
282 + assertThat(ipAddress.toString(), is("1.2.3.4"));
283 +
284 + final byte[] value2 = new byte[] {11, 22, // Preamble
285 + 0, 0, 0, 0,
286 + 33}; // Extra bytes
287 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value2, 2);
288 + assertThat(ipAddress.toString(), is("0.0.0.0"));
289 +
290 + final byte[] value3 = new byte[] {11, 22, // Preamble
291 + (byte) 0xff, (byte) 0xff,
292 + (byte) 0xff, (byte) 0xff,
293 + 33}; // Extra bytes
294 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value3, 2);
295 + assertThat(ipAddress.toString(), is("255.255.255.255"));
296 + }
297 +
298 + /**
299 + * Tests valueOf() converter for IPv6 byte array and an offset.
300 + */
301 + @Test
302 + public void testValueOfByteArrayOffsetIPv6() {
303 + IpAddress ipAddress;
304 +
305 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
306 + 0x11, 0x11, 0x22, 0x22,
307 + 0x33, 0x33, 0x44, 0x44,
308 + 0x55, 0x55, 0x66, 0x66,
309 + 0x77, 0x77,
310 + (byte) 0x88, (byte) 0x88,
311 + 44, 55}; // Extra bytes
312 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value1, 3);
313 + assertThat(ipAddress.toString(),
314 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
315 +
316 + final byte[] value2 = new byte[] {11, 22, // Preamble
317 + 0x00, 0x00, 0x00, 0x00,
318 + 0x00, 0x00, 0x00, 0x00,
319 + 0x00, 0x00, 0x00, 0x00,
320 + 0x00, 0x00, 0x00, 0x00,
321 + 33}; // Extra bytes
322 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value2, 2);
323 + assertThat(ipAddress.toString(), is("::"));
324 +
325 + final byte[] value3 = new byte[] {11, 22, // Preamble
326 + (byte) 0xff, (byte) 0xff,
327 + (byte) 0xff, (byte) 0xff,
328 + (byte) 0xff, (byte) 0xff,
329 + (byte) 0xff, (byte) 0xff,
330 + (byte) 0xff, (byte) 0xff,
331 + (byte) 0xff, (byte) 0xff,
332 + (byte) 0xff, (byte) 0xff,
333 + (byte) 0xff, (byte) 0xff,
334 + 33}; // Extra bytes
335 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value3, 2);
336 + assertThat(ipAddress.toString(),
337 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
338 + }
339 +
340 + /**
341 + * Tests invalid valueOf() converger for an array and an invalid offset
342 + * for IPv4.
343 + */
344 + @Test(expected = IllegalArgumentException.class)
345 + public void testInvalidValueOfArrayInvalidOffsetIPv4() {
346 + IpAddress ipAddress;
347 +
348 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
349 + 1, 2, 3, 4,
350 + 44, 55}; // Extra bytes
351 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value1, 6);
352 + }
353 +
354 + /**
355 + * Tests invalid valueOf() converger for an array and an invalid offset
356 + * for IPv6.
357 + */
358 + @Test(expected = IllegalArgumentException.class)
359 + public void testInvalidValueOfArrayInvalidOffsetIPv6() {
360 + IpAddress ipAddress;
361 +
362 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
363 + 0x11, 0x11, 0x22, 0x22,
364 + 0x33, 0x33, 0x44, 0x44,
365 + 0x55, 0x55, 0x66, 0x66,
366 + 0x77, 0x77,
367 + (byte) 0x88, (byte) 0x88,
368 + 44, 55}; // Extra bytes
369 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value1, 6);
370 + }
371 +
372 + /**
373 + * Tests valueOf() converter for IPv4 InetAddress.
374 + */
375 + @Test
376 + public void testValueOfInetAddressIPv4() {
377 + IpAddress ipAddress;
378 + InetAddress inetAddress;
379 +
380 + inetAddress = InetAddresses.forString("1.2.3.4");
381 + ipAddress = IpAddress.valueOf(inetAddress);
382 + assertThat(ipAddress.toString(), is("1.2.3.4"));
383 +
384 + inetAddress = InetAddresses.forString("0.0.0.0");
385 + ipAddress = IpAddress.valueOf(inetAddress);
386 + assertThat(ipAddress.toString(), is("0.0.0.0"));
387 +
388 + inetAddress = InetAddresses.forString("255.255.255.255");
389 + ipAddress = IpAddress.valueOf(inetAddress);
390 + assertThat(ipAddress.toString(), is("255.255.255.255"));
391 + }
392 +
393 + /**
394 + * Tests valueOf() converter for IPv6 InetAddress.
395 + */
396 + @Test
397 + public void testValueOfInetAddressIPv6() {
398 + IpAddress ipAddress;
399 + InetAddress inetAddress;
400 +
401 + inetAddress =
402 + InetAddresses.forString("1111:2222:3333:4444:5555:6666:7777:8888");
403 + ipAddress = IpAddress.valueOf(inetAddress);
404 + assertThat(ipAddress.toString(),
405 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
406 +
407 + inetAddress = InetAddresses.forString("::");
408 + ipAddress = IpAddress.valueOf(inetAddress);
409 + assertThat(ipAddress.toString(), is("::"));
410 +
411 + inetAddress =
412 + InetAddresses.forString("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
413 + ipAddress = IpAddress.valueOf(inetAddress);
414 + assertThat(ipAddress.toString(),
415 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
416 + }
417 +
418 + /**
419 + * Tests valueOf() converter for IPv4 string.
420 + */
421 + @Test
422 + public void testValueOfStringIPv4() {
423 + IpAddress ipAddress;
424 +
425 + ipAddress = IpAddress.valueOf("1.2.3.4");
426 + assertThat(ipAddress.toString(), is("1.2.3.4"));
427 +
428 + ipAddress = IpAddress.valueOf("0.0.0.0");
429 + assertThat(ipAddress.toString(), is("0.0.0.0"));
430 +
431 + ipAddress = IpAddress.valueOf("255.255.255.255");
432 + assertThat(ipAddress.toString(), is("255.255.255.255"));
433 + }
434 +
435 + /**
436 + * Tests valueOf() converter for IPv6 string.
437 + */
438 + @Test
439 + public void testValueOfStringIPv6() {
440 + IpAddress ipAddress;
441 +
442 + ipAddress =
443 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
444 + assertThat(ipAddress.toString(),
445 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
446 +
447 + ipAddress = IpAddress.valueOf("::");
448 + assertThat(ipAddress.toString(), is("::"));
449 +
450 + ipAddress =
451 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
452 + assertThat(ipAddress.toString(),
453 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
454 + }
455 +
456 + /**
457 + * Tests invalid valueOf() converter for a null string.
458 + */
459 + @Test(expected = NullPointerException.class)
460 + public void testInvalidValueOfNullString() {
461 + IpAddress ipAddress;
462 +
463 + String fromString = null;
464 + ipAddress = IpAddress.valueOf(fromString);
465 + }
466 +
467 + /**
468 + * Tests invalid valueOf() converter for an empty string.
469 + */
470 + @Test(expected = IllegalArgumentException.class)
471 + public void testInvalidValueOfEmptyString() {
472 + IpAddress ipAddress;
473 +
474 + String fromString = "";
475 + ipAddress = IpAddress.valueOf(fromString);
476 + }
477 +
478 + /**
479 + * Tests invalid valueOf() converter for an incorrect string.
480 + */
481 + @Test(expected = IllegalArgumentException.class)
482 + public void testInvalidValueOfIncorrectString() {
483 + IpAddress ipAddress;
484 +
485 + String fromString = "NoSuchIpAddress";
486 + ipAddress = IpAddress.valueOf(fromString);
487 + }
488 +
489 + /**
490 + * Tests making a mask prefix for a given prefix length for IPv4.
491 + */
492 + @Test
493 + public void testMakeMaskPrefixIPv4() {
494 + IpAddress ipAddress;
495 +
496 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 25);
497 + assertThat(ipAddress.toString(), is("255.255.255.128"));
498 +
499 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 0);
500 + assertThat(ipAddress.toString(), is("0.0.0.0"));
501 +
502 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 32);
503 + assertThat(ipAddress.toString(), is("255.255.255.255"));
504 + }
505 +
506 + /**
507 + * Tests making a mask prefix for a given prefix length for IPv6.
508 + */
509 + @Test
510 + public void testMakeMaskPrefixIPv6() {
511 + IpAddress ipAddress;
512 +
513 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 8);
514 + assertThat(ipAddress.toString(), is("ff00::"));
515 +
516 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 120);
517 + assertThat(ipAddress.toString(),
518 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"));
519 +
520 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 0);
521 + assertThat(ipAddress.toString(), is("::"));
522 +
523 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 128);
524 + assertThat(ipAddress.toString(),
525 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
526 +
527 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 64);
528 + assertThat(ipAddress.toString(), is("ffff:ffff:ffff:ffff::"));
529 + }
530 +
531 + /**
532 + * Tests making a mask prefix for an invalid prefix length for IPv4:
533 + * negative prefix length.
534 + */
535 + @Test(expected = IllegalArgumentException.class)
536 + public void testInvalidMakeNegativeMaskPrefixIPv4() {
537 + IpAddress ipAddress;
538 +
539 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, -1);
540 + }
541 +
542 + /**
543 + * Tests making a mask prefix for an invalid prefix length for IPv6:
544 + * negative prefix length.
545 + */
546 + @Test(expected = IllegalArgumentException.class)
547 + public void testInvalidMakeNegativeMaskPrefixIPv6() {
548 + IpAddress ipAddress;
549 +
550 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, -1);
551 + }
552 +
553 + /**
554 + * Tests making a mask prefix for an invalid prefix length for IPv4:
555 + * too long prefix length.
556 + */
557 + @Test(expected = IllegalArgumentException.class)
558 + public void testInvalidMakeTooLongMaskPrefixIPv4() {
559 + IpAddress ipAddress;
560 +
561 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 33);
562 + }
563 +
564 + /**
565 + * Tests making a mask prefix for an invalid prefix length for IPv6:
566 + * too long prefix length.
567 + */
568 + @Test(expected = IllegalArgumentException.class)
569 + public void testInvalidMakeTooLongMaskPrefixIPv6() {
570 + IpAddress ipAddress;
571 +
572 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 129);
573 + }
574 +
575 + /**
576 + * Tests making of a masked address for IPv4.
577 + */
578 + @Test
579 + public void testMakeMaskedAddressIPv4() {
580 + IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
581 + IpAddress ipAddressMasked;
582 +
583 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 24);
584 + assertThat(ipAddressMasked.toString(), is("1.2.3.0"));
585 +
586 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 0);
587 + assertThat(ipAddressMasked.toString(), is("0.0.0.0"));
588 +
589 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 32);
590 + assertThat(ipAddressMasked.toString(), is("1.2.3.5"));
591 + }
592 +
593 + /**
594 + * Tests making of a masked address for IPv6.
595 + */
596 + @Test
597 + public void testMakeMaskedAddressIPv6() {
598 + IpAddress ipAddress =
599 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
600 + IpAddress ipAddressMasked;
601 +
602 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 8);
603 + assertThat(ipAddressMasked.toString(), is("1100::"));
604 +
605 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 120);
606 + assertThat(ipAddressMasked.toString(),
607 + is("1111:2222:3333:4444:5555:6666:7777:8800"));
608 +
609 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 0);
610 + assertThat(ipAddressMasked.toString(), is("::"));
611 +
612 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 128);
613 + assertThat(ipAddressMasked.toString(),
614 + is("1111:2222:3333:4444:5555:6666:7777:8885"));
615 +
616 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 64);
617 + assertThat(ipAddressMasked.toString(), is("1111:2222:3333:4444::"));
618 + }
619 +
620 + /**
621 + * Tests making of a masked address for invalid prefix length for IPv4:
622 + * negative prefix length.
623 + */
624 + @Test(expected = IllegalArgumentException.class)
625 + public void testInvalidMakeNegativeMaskedAddressIPv4() {
626 + IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
627 + IpAddress ipAddressMasked;
628 +
629 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, -1);
630 + }
631 +
632 + /**
633 + * Tests making of a masked address for invalid prefix length for IPv6:
634 + * negative prefix length.
635 + */
636 + @Test(expected = IllegalArgumentException.class)
637 + public void testInvalidMakeNegativeMaskedAddressIPv6() {
638 + IpAddress ipAddress =
639 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
640 + IpAddress ipAddressMasked;
641 +
642 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, -1);
643 + }
644 +
645 + /**
646 + * Tests making of a masked address for an invalid prefix length for IPv4:
647 + * too long prefix length.
648 + */
649 + @Test(expected = IllegalArgumentException.class)
650 + public void testInvalidMakeTooLongMaskedAddressIPv4() {
651 + IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
652 + IpAddress ipAddressMasked;
653 +
654 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 33);
655 + }
656 +
657 + /**
658 + * Tests making of a masked address for an invalid prefix length for IPv6:
659 + * too long prefix length.
660 + */
661 + @Test(expected = IllegalArgumentException.class)
662 + public void testInvalidMakeTooLongMaskedAddressIPv6() {
663 + IpAddress ipAddress =
664 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
665 + IpAddress ipAddressMasked;
666 +
667 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 129);
668 + }
669 +
670 + /**
671 + * Tests comparison of {@link IpAddress} for IPv4.
672 + */
673 + @Test
674 + public void testComparisonIPv4() {
675 + IpAddress addr1, addr2, addr3, addr4;
676 +
677 + addr1 = IpAddress.valueOf("1.2.3.4");
678 + addr2 = IpAddress.valueOf("1.2.3.4");
679 + addr3 = IpAddress.valueOf("1.2.3.3");
680 + addr4 = IpAddress.valueOf("1.2.3.5");
681 + assertTrue(addr1.compareTo(addr2) == 0);
682 + assertTrue(addr1.compareTo(addr3) > 0);
683 + assertTrue(addr1.compareTo(addr4) < 0);
684 +
685 + addr1 = IpAddress.valueOf("255.2.3.4");
686 + addr2 = IpAddress.valueOf("255.2.3.4");
687 + addr3 = IpAddress.valueOf("255.2.3.3");
688 + addr4 = IpAddress.valueOf("255.2.3.5");
689 + assertTrue(addr1.compareTo(addr2) == 0);
690 + assertTrue(addr1.compareTo(addr3) > 0);
691 + assertTrue(addr1.compareTo(addr4) < 0);
692 + }
693 +
694 + /**
695 + * Tests comparison of {@link IpAddress} for IPv6.
696 + */
697 + @Test
698 + public void testComparisonIPv6() {
699 + IpAddress addr1, addr2, addr3, addr4;
700 +
701 + addr1 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
702 + addr2 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
703 + addr3 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8887");
704 + addr4 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8889");
705 + assertTrue(addr1.compareTo(addr2) == 0);
706 + assertTrue(addr1.compareTo(addr3) > 0);
707 + assertTrue(addr1.compareTo(addr4) < 0);
708 +
709 + addr1 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
710 + addr2 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
711 + addr3 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8887");
712 + addr4 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8889");
713 + assertTrue(addr1.compareTo(addr2) == 0);
714 + assertTrue(addr1.compareTo(addr3) > 0);
715 + assertTrue(addr1.compareTo(addr4) < 0);
716 +
717 + addr1 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
718 + addr2 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
719 + addr3 = IpAddress.valueOf("ffff:2222:3333:4443:5555:6666:7777:8888");
720 + addr4 = IpAddress.valueOf("ffff:2222:3333:4445:5555:6666:7777:8888");
721 + assertTrue(addr1.compareTo(addr2) == 0);
722 + assertTrue(addr1.compareTo(addr3) > 0);
723 + assertTrue(addr1.compareTo(addr4) < 0);
724 + }
725 +
726 + /**
727 + * Tests equality of {@link IpAddress} for IPv4.
728 + */
729 + @Test
730 + public void testEqualityIPv4() {
731 + new EqualsTester()
732 + .addEqualityGroup(IpAddress.valueOf("1.2.3.4"),
733 + IpAddress.valueOf("1.2.3.4"))
734 + .addEqualityGroup(IpAddress.valueOf("1.2.3.5"),
735 + IpAddress.valueOf("1.2.3.5"))
736 + .addEqualityGroup(IpAddress.valueOf("0.0.0.0"),
737 + IpAddress.valueOf("0.0.0.0"))
738 + .addEqualityGroup(IpAddress.valueOf("255.255.255.255"),
739 + IpAddress.valueOf("255.255.255.255"))
740 + .testEquals();
741 + }
742 +
743 + /**
744 + * Tests equality of {@link IpAddress} for IPv6.
745 + */
746 + @Test
747 + public void testEqualityIPv6() {
748 + new EqualsTester()
749 + .addEqualityGroup(
750 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888"),
751 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888"))
752 + .addEqualityGroup(
753 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:888a"),
754 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:888a"))
755 + .addEqualityGroup(
756 + IpAddress.valueOf("::"),
757 + IpAddress.valueOf("::"))
758 + .addEqualityGroup(
759 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
760 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))
761 + .testEquals();
762 + }
763 +
764 + /**
765 + * Tests object string representation for IPv4.
766 + */
767 + @Test
768 + public void testToStringIPv4() {
769 + IpAddress ipAddress;
770 +
771 + ipAddress = IpAddress.valueOf("1.2.3.4");
772 + assertThat(ipAddress.toString(), is("1.2.3.4"));
773 +
774 + ipAddress = IpAddress.valueOf("0.0.0.0");
775 + assertThat(ipAddress.toString(), is("0.0.0.0"));
776 +
777 + ipAddress = IpAddress.valueOf("255.255.255.255");
778 + assertThat(ipAddress.toString(), is("255.255.255.255"));
779 + }
780 +
781 + /**
782 + * Tests object string representation for IPv6.
783 + */
784 + @Test
785 + public void testToStringIPv6() {
786 + IpAddress ipAddress;
787 +
788 + ipAddress =
789 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
790 + assertThat(ipAddress.toString(),
791 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
792 +
793 + ipAddress = IpAddress.valueOf("1111::8888");
794 + assertThat(ipAddress.toString(), is("1111::8888"));
795 +
796 + ipAddress = IpAddress.valueOf("1111::");
797 + assertThat(ipAddress.toString(), is("1111::"));
798 +
799 + ipAddress = IpAddress.valueOf("::8888");
800 + assertThat(ipAddress.toString(), is("::8888"));
801 +
802 + ipAddress = IpAddress.valueOf("::");
803 + assertThat(ipAddress.toString(), is("::"));
804 +
805 + ipAddress =
806 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
807 + assertThat(ipAddress.toString(),
808 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
809 + }
810 +}
...@@ -38,9 +38,11 @@ public class IpPrefixTest { ...@@ -38,9 +38,11 @@ public class IpPrefixTest {
38 38
39 @Test 39 @Test
40 public void testEquality() { 40 public void testEquality() {
41 - IpPrefix ip1 = IpPrefix.valueOf(BYTES1, IpPrefix.MAX_INET_MASK_LENGTH); 41 + IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
42 + BYTES1, IpPrefix.MAX_INET_MASK_LENGTH);
42 IpPrefix ip2 = IpPrefix.valueOf(INTVAL1, IpPrefix.MAX_INET_MASK_LENGTH); 43 IpPrefix ip2 = IpPrefix.valueOf(INTVAL1, IpPrefix.MAX_INET_MASK_LENGTH);
43 - IpPrefix ip3 = IpPrefix.valueOf(BYTES2, IpPrefix.MAX_INET_MASK_LENGTH); 44 + IpPrefix ip3 = IpPrefix.valueOf(IpAddress.Version.INET,
45 + BYTES2, IpPrefix.MAX_INET_MASK_LENGTH);
44 IpPrefix ip4 = IpPrefix.valueOf(INTVAL2, IpPrefix.MAX_INET_MASK_LENGTH); 46 IpPrefix ip4 = IpPrefix.valueOf(INTVAL2, IpPrefix.MAX_INET_MASK_LENGTH);
45 IpPrefix ip5 = IpPrefix.valueOf(STRVAL); 47 IpPrefix ip5 = IpPrefix.valueOf(STRVAL);
46 48
...@@ -50,16 +52,19 @@ public class IpPrefixTest { ...@@ -50,16 +52,19 @@ public class IpPrefixTest {
50 .testEquals(); 52 .testEquals();
51 53
52 // string conversions 54 // string conversions
53 - IpPrefix ip6 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); 55 + IpPrefix ip6 = IpPrefix.valueOf(IpAddress.Version.INET,
56 + BYTES1, MASK_LENGTH);
54 IpPrefix ip7 = IpPrefix.valueOf("10.0.0.10/16"); 57 IpPrefix ip7 = IpPrefix.valueOf("10.0.0.10/16");
55 - IpPrefix ip8 = IpPrefix.valueOf(new byte [] {0xa, 0x0, 0x0, 0xc}, 16); 58 + IpPrefix ip8 = IpPrefix.valueOf(IpAddress.Version.INET,
59 + new byte [] {0xa, 0x0, 0x0, 0xc}, 16);
56 assertEquals("incorrect address conversion", ip6, ip7); 60 assertEquals("incorrect address conversion", ip6, ip7);
57 assertEquals("incorrect address conversion", ip5, ip8); 61 assertEquals("incorrect address conversion", ip5, ip8);
58 } 62 }
59 63
60 @Test 64 @Test
61 public void basics() { 65 public void basics() {
62 - IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); 66 + IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
67 + BYTES1, MASK_LENGTH);
63 final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0x0}; 68 final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0x0};
64 69
65 // check fields 70 // check fields
...@@ -74,7 +79,8 @@ public class IpPrefixTest { ...@@ -74,7 +79,8 @@ public class IpPrefixTest {
74 @Test 79 @Test
75 public void netmasks() { 80 public void netmasks() {
76 // masked 81 // masked
77 - IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); 82 + IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
83 + BYTES1, MASK_LENGTH);
78 IpPrefix ip2 = IpPrefix.valueOf("10.0.0.10/16"); 84 IpPrefix ip2 = IpPrefix.valueOf("10.0.0.10/16");
79 IpPrefix ip3 = IpPrefix.valueOf("10.0.0.0/16"); 85 IpPrefix ip3 = IpPrefix.valueOf("10.0.0.0/16");
80 assertEquals("incorrect binary masked address", 86 assertEquals("incorrect binary masked address",
...@@ -87,9 +93,12 @@ public class IpPrefixTest { ...@@ -87,9 +93,12 @@ public class IpPrefixTest {
87 93
88 @Test 94 @Test
89 public void testContainsIpPrefix() { 95 public void testContainsIpPrefix() {
90 - IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31); 96 + IpPrefix slash31 = IpPrefix.valueOf(IpAddress.Version.INET,
91 - IpPrefix slash32 = IpPrefix.valueOf(BYTES1, 32); 97 + BYTES1, 31);
92 - IpPrefix differentSlash32 = IpPrefix.valueOf(BYTES2, 32); 98 + IpPrefix slash32 = IpPrefix.valueOf(IpAddress.Version.INET,
99 + BYTES1, 32);
100 + IpPrefix differentSlash32 = IpPrefix.valueOf(IpAddress.Version.INET,
101 + BYTES2, 32);
93 102
94 assertTrue(slash31.contains(differentSlash32)); 103 assertTrue(slash31.contains(differentSlash32));
95 assertFalse(differentSlash32.contains(slash31)); 104 assertFalse(differentSlash32.contains(slash31));
...@@ -109,8 +118,9 @@ public class IpPrefixTest { ...@@ -109,8 +118,9 @@ public class IpPrefixTest {
109 118
110 @Test 119 @Test
111 public void testContainsIpAddress() { 120 public void testContainsIpAddress() {
112 - IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31); 121 + IpPrefix slash31 = IpPrefix.valueOf(IpAddress.Version.INET,
113 - IpAddress addr32 = IpAddress.valueOf(BYTES1); 122 + BYTES1, 31);
123 + IpAddress addr32 = IpAddress.valueOf(IpAddress.Version.INET, BYTES1);
114 124
115 assertTrue(slash31.contains(addr32)); 125 assertTrue(slash31.contains(addr32));
116 126
......
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
73 <dependency> 73 <dependency>
74 <groupId>io.netty</groupId> 74 <groupId>io.netty</groupId>
75 <artifactId>netty-transport-native-epoll</artifactId> 75 <artifactId>netty-transport-native-epoll</artifactId>
76 + <version>${netty4.version}</version>
76 </dependency> 77 </dependency>
77 </dependencies> 78 </dependencies>
78 79
......
...@@ -244,7 +244,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider { ...@@ -244,7 +244,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
244 } 244 }
245 245
246 @Override 246 @Override
247 - public void roleChanged(Device device, MastershipRole newRole) { 247 + public void roleChanged(DeviceId device, MastershipRole newRole) {
248 } 248 }
249 249
250 @Override 250 @Override
...@@ -257,7 +257,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider { ...@@ -257,7 +257,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
257 } 257 }
258 258
259 @Override 259 @Override
260 - public boolean isReachable(Device device) { 260 + public boolean isReachable(DeviceId device) {
261 return false; 261 return false;
262 } 262 }
263 } 263 }
......
...@@ -101,7 +101,7 @@ public class TopologyResource extends BaseResource { ...@@ -101,7 +101,7 @@ public class TopologyResource extends BaseResource {
101 new Prop("Vendor", device.manufacturer()), 101 new Prop("Vendor", device.manufacturer()),
102 new Prop("H/W Version", device.hwVersion()), 102 new Prop("H/W Version", device.hwVersion()),
103 new Prop("S/W Version", device.swVersion()), 103 new Prop("S/W Version", device.swVersion()),
104 - new Prop("S/W Version", device.serialNumber()), 104 + new Prop("Serial Number", device.serialNumber()),
105 new Separator(), 105 new Separator(),
106 new Prop("Latitude", annot.value("latitude")), 106 new Prop("Latitude", annot.value("latitude")),
107 new Prop("Longitude", annot.value("longitude")), 107 new Prop("Longitude", annot.value("longitude")),
......