Praseed Balakrishnan

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

Showing 80 changed files with 852 additions and 327 deletions
......@@ -368,12 +368,12 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro
}
@Override
public void roleChanged(Device device, MastershipRole newRole) {
public void roleChanged(DeviceId device, MastershipRole newRole) {
// TODO Auto-generated method stub.
}
@Override
public boolean isReachable(Device device) {
public boolean isReachable(DeviceId device) {
return false;
}
}
......
......@@ -246,11 +246,13 @@ public class BgpSession extends SimpleChannelHandler {
InetAddress inetAddr;
if (localAddress instanceof InetSocketAddress) {
inetAddr = ((InetSocketAddress) localAddress).getAddress();
localIp4Address = IpAddress.valueOf(inetAddr.getAddress());
localIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
inetAddr.getAddress());
}
if (remoteAddress instanceof InetSocketAddress) {
inetAddr = ((InetSocketAddress) remoteAddress).getAddress();
remoteIp4Address = IpAddress.valueOf(inetAddr.getAddress());
remoteIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
inetAddr.getAddress());
}
log.debug("BGP Session Connected from {} on {}",
......
......@@ -105,7 +105,8 @@ public class BgpSessionManager {
if (bgpSession.getLocalAddress() instanceof InetSocketAddress) {
InetAddress inetAddr =
((InetSocketAddress) bgpSession.getLocalAddress()).getAddress();
IpAddress ip4Address = IpAddress.valueOf(inetAddr.getAddress());
IpAddress ip4Address = IpAddress.valueOf(IpAddress.Version.INET,
inetAddr.getAddress());
updateMyBgpId(ip4Address);
}
return true;
......
......@@ -74,7 +74,7 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand {
* @param deviceString string representing the device/port
* @return port number as a string, empty string if the port is not found
*/
private String getPortNumber(String deviceString) {
public static String getPortNumber(String deviceString) {
int slash = deviceString.indexOf('/');
if (slash <= 0) {
return "";
......@@ -88,7 +88,7 @@ public class AddPointToPointIntentCommand extends ConnectivityIntentCommand {
* @param deviceString string representing the device/port
* @return device ID string
*/
private String getDeviceId(String deviceString) {
public static String getDeviceId(String deviceString) {
int slash = deviceString.indexOf('/');
if (slash <= 0) {
return "";
......
......@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Link;
......@@ -44,6 +45,11 @@ import java.util.Set;
description = "Lists the inventory of intents and their states")
public class IntentsListCommand extends AbstractShellCommand {
@Option(name = "-i", aliases = "--installable", description = "Output Installable Intents",
required = false, multiValued = false)
private boolean showInstallable = false;
@Override
protected void execute() {
IntentService service = get(IntentService.class);
......@@ -93,7 +99,7 @@ public class IntentsListCommand extends AbstractShellCommand {
}
List<Intent> installable = service.getInstallableIntents(intent.id());
if (installable != null && !installable.isEmpty()) {
if (showInstallable && installable != null && !installable.isEmpty()) {
print(" installable=%s", installable);
}
}
......
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.resource.LinkResourceAllocations;
import org.onlab.onos.net.resource.LinkResourceService;
import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getDeviceId;
import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getPortNumber;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.PortNumber.portNumber;
/**
* Lists allocations by link.
*/
@Command(scope = "onos", name = "resource-allocations",
description = "Lists allocations by link")
public class ResourceAllocationsCommand extends AbstractShellCommand {
private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
private static final String COMPACT = "%s/%s-%s/%s";
@Argument(index = 0, name = "srcString", description = "Link source",
required = false, multiValued = false)
String srcString = null;
@Argument(index = 1, name = "dstString", description = "Link destination",
required = false, multiValued = false)
String dstString = null;
@Override
protected void execute() {
LinkResourceService resourceService = get(LinkResourceService.class);
LinkService linkService = get(LinkService.class);
Iterable<LinkResourceAllocations> itr = null;
try {
DeviceId ingressDeviceId = deviceId(getDeviceId(srcString));
PortNumber ingressPortNumber = portNumber(getPortNumber(srcString));
ConnectPoint src = new ConnectPoint(ingressDeviceId, ingressPortNumber);
DeviceId egressDeviceId = deviceId(getDeviceId(dstString));
PortNumber egressPortNumber = portNumber(getPortNumber(dstString));
ConnectPoint dst = new ConnectPoint(egressDeviceId, egressPortNumber);
Link link = linkService.getLink(src, dst);
itr = resourceService.getAllocations(link);
for (LinkResourceAllocations allocation : itr) {
print("%s", allocation.getResourceAllocation(link));
}
} catch (Exception e) {
print("----- Displaying all resource allocations -----", e.getMessage());
itr = resourceService.getAllocations();
for (LinkResourceAllocations allocation : itr) {
print("%s", allocation);
}
}
}
}
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.resource.LinkResourceService;
import org.onlab.onos.net.resource.ResourceRequest;
import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getDeviceId;
import static org.onlab.onos.cli.net.AddPointToPointIntentCommand.getPortNumber;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.PortNumber.portNumber;
/**
* Lists allocations by link.
*/
@Command(scope = "onos", name = "resource-available",
description = "Lists available resources by link")
public class ResourceAvailableCommand extends AbstractShellCommand {
private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
private static final String COMPACT = "%s/%s-%s/%s";
@Argument(index = 0, name = "srcString", description = "Link source",
required = false, multiValued = false)
String srcString = null;
@Argument(index = 1, name = "dstString", description = "Link destination",
required = false, multiValued = false)
String dstString = null;
@Override
protected void execute() {
LinkResourceService resourceService = get(LinkResourceService.class);
LinkService linkService = get(LinkService.class);
Iterable<ResourceRequest> itr = null;
try {
DeviceId ingressDeviceId = deviceId(getDeviceId(srcString));
PortNumber ingressPortNumber = portNumber(getPortNumber(srcString));
ConnectPoint src = new ConnectPoint(ingressDeviceId, ingressPortNumber);
DeviceId egressDeviceId = deviceId(getDeviceId(dstString));
PortNumber egressPortNumber = portNumber(getPortNumber(dstString));
ConnectPoint dst = new ConnectPoint(egressDeviceId, egressPortNumber);
Link link = linkService.getLink(src, dst);
itr = resourceService.getAvailableResources(link);
int lambdaCount = 0;
for (ResourceRequest req : itr) {
switch (req.type()) {
case LAMBDA:
lambdaCount++;
break;
case BANDWIDTH:
print("%s", req);
break;
default:
break;
}
}
if (lambdaCount > 0) {
print("Number of available lambdas: %d", lambdaCount);
}
} catch (Exception e) {
print("Invalid link", e.getMessage());
}
}
}
......@@ -158,7 +158,22 @@
<null/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.ResourceAllocationsCommand"/>
<completers>
<ref component-id="connectPointCompleter"/>
<ref component-id="connectPointCompleter"/>
<null/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.ResourceAvailableCommand"/>
<completers>
<ref component-id="connectPointCompleter"/>
<ref component-id="connectPointCompleter"/>
<null/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.ClustersListCommand"/>
</command>
......
......@@ -40,7 +40,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
MASTER_CHANGED,
/**
* Signifies that the list of backup nodes has changed.
* Signifies that the list of backup nodes has changed. If
* the change in the backups list is accompanied by a change in
* master, the event is subsumed by MASTER_CHANGED.
*/
BACKUPS_CHANGED
}
......@@ -49,9 +51,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
* Creates an event of a given type and for the specified device,
* role information, and the current time.
*
* @param type device event type
* @param type mastership event type
* @param device event device subject
* @param info mastership role information subject
* @param info mastership role information
*/
public MastershipEvent(Type type, DeviceId device, RoleInfo info) {
super(type, device);
......
......@@ -16,7 +16,7 @@
package org.onlab.onos.net;
/**
* Representation of a network resource.
* Representation of a network resource, e.g. a link, lambda, MPLS tag.
*/
public interface NetworkResource {
}
......
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.onos.net;
/**
* Abstraction of a generalized network tunnel.
*/
public interface Tunnel extends Link {
/**
* Tunnel technology type.
*/
enum Type {
MPLS, VLAN, VXLAN, GRE, OPTICAL
}
/**
* Network resource backing the tunnel, e.g. lambda, VLAN id, MPLS tag.
*
* @return backing resource
*/
NetworkResource resource();
}
......@@ -25,6 +25,14 @@ import org.onlab.onos.net.DeviceId;
public interface DeviceClockProviderService {
/**
* Checks if this service can issue Timestamp for specified device.
*
* @param deviceId device identifier.
* @return true if timestamp can be issued for specified device
*/
public boolean isTimestampAvailable(DeviceId deviceId);
/**
* Updates the mastership term for the specified deviceId.
*
* @param deviceId device identifier.
......
......@@ -24,7 +24,16 @@ import org.onlab.onos.store.Timestamp;
public interface DeviceClockService {
/**
* Checks if this service can issue Timestamp for specified device.
*
* @param deviceId device identifier.
* @return true if timestamp can be issued for specified device
*/
public boolean isTimestampAvailable(DeviceId deviceId);
/**
* Returns a new timestamp for the specified deviceId.
*
* @param deviceId device identifier.
* @return timestamp.
*/
......
......@@ -16,6 +16,7 @@
package org.onlab.onos.net.device;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.provider.Provider;
......@@ -42,16 +43,16 @@ public interface DeviceProvider extends Provider {
* Notifies the provider of a mastership role change for the specified
* device as decided by the core.
*
* @param device affected device
* @param deviceId device identifier
* @param newRole newly determined mastership role
*/
void roleChanged(Device device, MastershipRole newRole);
void roleChanged(DeviceId deviceId, MastershipRole newRole);
/**
* Checks the reachability (connectivity) of a device from this provider.
*
* @param device device to check
* @param deviceId device identifier
* @return true if reachable, false otherwise
*/
boolean isReachable(Device device);
boolean isReachable(DeviceId deviceId);
}
......
......@@ -61,12 +61,12 @@ public interface DeviceProviderService extends ProviderService<DeviceProvider> {
void portStatusChanged(DeviceId deviceId, PortDescription portDescription);
/**
* Notifies the core about the providers inability to assert the specified
* mastership role on the device.
* Notifies the core about the result of a RoleRequest sent to a device.
*
* @param deviceId identity of the device
* @param role mastership role that was asserted but failed
* @param requested mastership role that was requested by the node
* @param replied mastership role the switch accepted
*/
void unableToAssertRole(DeviceId deviceId, MastershipRole role);
void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response);
}
......
......@@ -27,11 +27,14 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T
*/
public enum Type {
// Request has been forwarded to MASTER Node
/**
* Signifies that a batch operation has been initiated.
*/
BATCH_OPERATION_REQUESTED,
// MASTER Node has pushed the batch down to the Device
// (e.g., Received barrier reply)
/**
* Signifies that a batch operation has completed.
*/
......
......@@ -25,29 +25,29 @@ import com.google.common.collect.Lists;
public class FlowRuleBatchRequest {
private final int batchId;
private final List<FlowEntry> toAdd;
private final List<FlowEntry> toRemove;
private final List<FlowRule> toAdd;
private final List<FlowRule> toRemove;
public FlowRuleBatchRequest(int batchId, List<? extends FlowEntry> toAdd, List<? extends FlowEntry> toRemove) {
public FlowRuleBatchRequest(int batchId, List<? extends FlowRule> toAdd, List<? extends FlowRule> toRemove) {
this.batchId = batchId;
this.toAdd = Collections.unmodifiableList(toAdd);
this.toRemove = Collections.unmodifiableList(toRemove);
}
public List<FlowEntry> toAdd() {
public List<FlowRule> toAdd() {
return toAdd;
}
public List<FlowEntry> toRemove() {
public List<FlowRule> toRemove() {
return toRemove;
}
public FlowRuleBatchOperation asBatchOperation() {
List<FlowRuleBatchEntry> entries = Lists.newArrayList();
for (FlowEntry e : toAdd) {
for (FlowRule e : toAdd) {
entries.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, e));
}
for (FlowEntry e : toRemove) {
for (FlowRule e : toRemove) {
entries.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, e));
}
return new FlowRuleBatchOperation(entries);
......
......@@ -200,7 +200,7 @@ public final class Instructions {
}
if (obj instanceof OutputInstruction) {
OutputInstruction that = (OutputInstruction) obj;
Objects.equals(port, that.port);
return Objects.equals(port, that.port);
}
return false;
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.resource;
import com.google.common.base.MoreObjects;
/**
* Representation of allocated bandwidth resource.
*/
......@@ -35,4 +37,11 @@ public class BandwidthResourceAllocation extends BandwidthResourceRequest
public BandwidthResourceAllocation(Bandwidth bandwidth) {
super(bandwidth);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("bandwidth", bandwidth())
.toString();
}
}
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.resource;
import com.google.common.base.MoreObjects;
/**
* Representation of a request for bandwidth resource.
*/
......@@ -53,4 +55,11 @@ public class BandwidthResourceRequest implements ResourceRequest {
public ResourceType type() {
return ResourceType.BANDWIDTH;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("bandwidth", bandwidth)
.toString();
}
}
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.resource;
import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
......@@ -64,4 +66,11 @@ public class LambdaResourceAllocation extends LambdaResourceRequest
final LambdaResourceAllocation other = (LambdaResourceAllocation) obj;
return Objects.equals(this.lambda, other.lambda);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("lambda", lambda)
.toString();
}
}
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.resource;
import com.google.common.base.MoreObjects;
/**
* Representation of a request for lambda resource.
*/
......@@ -25,4 +27,9 @@ public class LambdaResourceRequest implements ResourceRequest {
return ResourceType.LAMBDA;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.toString();
}
}
......
......@@ -371,10 +371,11 @@ public class FlowRuleManager
final FlowRuleBatchRequest request = event.subject();
switch (event.type()) {
case BATCH_OPERATION_REQUESTED:
for (FlowEntry entry : request.toAdd()) {
// Request has been forwarded to MASTER Node, and was
for (FlowRule entry : request.toAdd()) {
eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADD_REQUESTED, entry));
}
for (FlowEntry entry : request.toRemove()) {
for (FlowRule entry : request.toRemove()) {
eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVE_REQUESTED, entry));
}
// FIXME: what about op.equals(FlowRuleOperation.MODIFY) ?
......@@ -392,21 +393,15 @@ public class FlowRuleManager
Futures.getUnchecked(result)));
}
}, futureListeners);
break;
case BATCH_OPERATION_COMPLETED:
Set<FlowRule> failedItems = event.result().failedItems();
for (FlowEntry entry : request.toAdd()) {
if (!failedItems.contains(entry)) {
eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED, entry));
}
}
for (FlowEntry entry : request.toRemove()) {
if (!failedItems.contains(entry)) {
eventDispatcher.post(new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVED, entry));
}
}
// MASTER Node has pushed the batch down to the Device
// Note: RULE_ADDED will be posted
// when Flow was actually confirmed by stats reply.
break;
default:
break;
}
......
......@@ -67,6 +67,7 @@ public class HostMonitor implements TimerTask {
private final ConcurrentMap<ProviderId, HostProvider> hostProviders;
private static final long DEFAULT_PROBE_RATE = 30000; // milliseconds
private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
private long probeRate = DEFAULT_PROBE_RATE;
private Timeout timeout;
......@@ -215,15 +216,15 @@ public class HostMonitor implements TimerTask {
.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH)
.setOpCode(ARP.OP_REQUEST);
arp.setSenderHardwareAddress(sourceMac.getAddress())
arp.setSenderHardwareAddress(sourceMac.toBytes())
.setSenderProtocolAddress(sourceIp.toOctets())
.setTargetHardwareAddress(MacAddress.ZERO_MAC_ADDRESS)
.setTargetHardwareAddress(ZERO_MAC_ADDRESS)
.setTargetProtocolAddress(targetIp.toOctets());
Ethernet ethernet = new Ethernet();
ethernet.setEtherType(Ethernet.TYPE_ARP)
.setDestinationMACAddress(MacAddress.BROADCAST_MAC)
.setSourceMACAddress(sourceMac.getAddress())
.setDestinationMACAddress(MacAddress.BROADCAST)
.setSourceMACAddress(sourceMac)
.setPayload(arp);
return ethernet;
......
......@@ -132,7 +132,8 @@ public class ProxyArpManager implements ProxyArpService {
// for one of our external addresses.
if (isOutsidePort(inPort)) {
IpAddress target =
IpAddress.valueOf(arp.getTargetProtocolAddress());
IpAddress.valueOf(IpAddress.Version.INET,
arp.getTargetProtocolAddress());
PortAddresses addresses =
hostService.getAddressBindingsForPort(inPort);
......@@ -149,7 +150,8 @@ public class ProxyArpManager implements ProxyArpService {
// it could be a request from an internal host to an external
// address. Forward it over to the correct port.
IpAddress source =
IpAddress.valueOf(arp.getSenderProtocolAddress());
IpAddress.valueOf(IpAddress.Version.INET,
arp.getSenderProtocolAddress());
PortAddresses sourceAddresses = findPortInSubnet(source);
if (sourceAddresses != null) {
for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) {
......@@ -164,8 +166,9 @@ public class ProxyArpManager implements ProxyArpService {
// Continue with normal proxy ARP case
VlanId vlan = VlanId.vlanId(eth.getVlanID());
Set<Host> hosts = hostService.getHostsByIp(IpAddress.valueOf(arp
.getTargetProtocolAddress()));
Set<Host> hosts =
hostService.getHostsByIp(IpAddress.valueOf(IpAddress.Version.INET,
arp.getTargetProtocolAddress()));
Host dst = null;
Host src = hostService.getHost(HostId.hostId(eth.getSourceMAC(),
......@@ -357,8 +360,8 @@ public class ProxyArpManager implements ProxyArpService {
Ethernet request) {
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(request.getSourceMACAddress());
eth.setSourceMACAddress(srcMac.getAddress());
eth.setDestinationMACAddress(request.getSourceMAC());
eth.setSourceMACAddress(srcMac);
eth.setEtherType(Ethernet.TYPE_ARP);
eth.setVlanID(request.getVlanID());
......@@ -369,7 +372,7 @@ public class ProxyArpManager implements ProxyArpService {
arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH);
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
arp.setSenderHardwareAddress(srcMac.getAddress());
arp.setSenderHardwareAddress(srcMac.toBytes());
arp.setTargetHardwareAddress(request.getSourceMACAddress());
arp.setTargetProtocolAddress(((ARP) request.getPayload())
......
......@@ -15,11 +15,7 @@
*/
package org.onlab.onos.net.resource.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import com.google.common.base.MoreObjects;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.resource.LinkResourceAllocations;
......@@ -28,6 +24,11 @@ import org.onlab.onos.net.resource.ResourceAllocation;
import org.onlab.onos.net.resource.ResourceRequest;
import org.onlab.onos.net.resource.ResourceType;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* Implementation of {@link LinkResourceAllocations}.
*/
......@@ -38,11 +39,11 @@ public class DefaultLinkResourceAllocations implements LinkResourceAllocations {
/**
* Creates a new link resource allocations.
*
* @param request requested resources
* @param request requested resources
* @param allocations allocated resources
*/
DefaultLinkResourceAllocations(LinkResourceRequest request,
Map<Link, Set<ResourceAllocation>> allocations) {
Map<Link, Set<ResourceAllocation>> allocations) {
this.request = request;
this.allocations = allocations;
}
......@@ -76,4 +77,10 @@ public class DefaultLinkResourceAllocations implements LinkResourceAllocations {
return result;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("allocations", allocations)
.toString();
}
}
......
......@@ -19,7 +19,6 @@ import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onlab.onos.cluster.ClusterEventListener;
import org.onlab.onos.cluster.ClusterService;
......@@ -181,16 +180,6 @@ public class DeviceManagerTest {
assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
}
@Ignore("disabled until we settle the device-mastership wiring")
@Test
public void setRole() throws InterruptedException {
connectDevice(DID1, SW1);
validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
assertEquals("incorrect device", DID1, provider.deviceReceived.id());
assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
}
@Test
public void updatePorts() {
connectDevice(DID1, SW1);
......@@ -262,7 +251,7 @@ public class DeviceManagerTest {
private class TestProvider extends AbstractProvider implements DeviceProvider {
private Device deviceReceived;
private DeviceId deviceReceived;
private MastershipRole roleReceived;
public TestProvider() {
......@@ -274,13 +263,13 @@ public class DeviceManagerTest {
}
@Override
public void roleChanged(Device device, MastershipRole newRole) {
public void roleChanged(DeviceId device, MastershipRole newRole) {
deviceReceived = device;
roleReceived = newRole;
}
@Override
public boolean isReachable(Device device) {
public boolean isReachable(DeviceId device) {
return false;
}
}
......@@ -360,9 +349,16 @@ public class DeviceManagerTest {
private final class TestClockProviderService implements
DeviceClockProviderService {
private Set<DeviceId> registerdBefore = Sets.newConcurrentHashSet();
@Override
public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
// TODO Auto-generated method stub
registerdBefore.add(deviceId);
}
@Override
public boolean isTimestampAvailable(DeviceId deviceId) {
return registerdBefore.contains(deviceId);
}
}
}
......
......@@ -148,7 +148,7 @@ public class FlowRuleManagerTest {
int i = 0;
System.err.println("events :" + listener.events);
for (FlowRuleEvent e : listener.events) {
assertTrue("unexpected event", e.type().equals(events[i]));
assertEquals("unexpected event", events[i], e.type());
i++;
}
......@@ -178,15 +178,13 @@ public class FlowRuleManagerTest {
RULE_ADDED, RULE_ADDED);
addFlowRule(1);
System.err.println("events :" + listener.events);
assertEquals("should still be 2 rules", 2, flowCount());
providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
validateEvents(RULE_UPDATED);
}
// TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
//backing store is sensitive to the order of additions/removals
private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
Iterable<FlowEntry> rules = service.getFlowEntries(DID);
......@@ -539,17 +537,17 @@ public class FlowRuleManagerTest {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return true;
return false;
}
@Override
public boolean isCancelled() {
return true;
return false;
}
@Override
public boolean isDone() {
return false;
return true;
}
@Override
......@@ -562,12 +560,14 @@ public class FlowRuleManagerTest {
public CompletedBatchOperation get(long timeout, TimeUnit unit)
throws InterruptedException,
ExecutionException, TimeoutException {
return null;
return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet());
}
@Override
public void addListener(Runnable task, Executor executor) {
// TODO: add stuff.
if (isDone()) {
executor.execute(task);
}
}
}
......
......@@ -20,11 +20,9 @@ import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
......@@ -155,17 +153,20 @@ public class HostMonitorTest {
Instruction instruction = packet.treatment().instructions().get(0);
assertTrue(instruction instanceof OutputInstruction);
OutputInstruction oi = (OutputInstruction) instruction;
assertTrue(oi.port().equals(portNum));
assertEquals(portNum, oi.port());
// Check the output packet is correct (well the important bits anyway)
Ethernet eth = new Ethernet();
eth.deserialize(packet.data().array(), 0, packet.data().array().length);
final byte[] pktData = new byte[packet.data().remaining()];
packet.data().get(pktData);
eth.deserialize(pktData, 0, pktData.length);
ARP arp = (ARP) eth.getPayload();
assertTrue(Arrays.equals(arp.getSenderProtocolAddress(),
SOURCE_ADDR.toOctets()));
assertTrue(Arrays.equals(arp.getSenderHardwareAddress(), sourceMac.toBytes()));
assertTrue(Arrays.equals(arp.getTargetProtocolAddress(),
TARGET_IP_ADDR.toOctets()));
assertArrayEquals(SOURCE_ADDR.toOctets(),
arp.getSenderProtocolAddress());
assertArrayEquals(sourceMac.toBytes(),
arp.getSenderHardwareAddress());
assertArrayEquals(TARGET_IP_ADDR.toOctets(),
arp.getTargetProtocolAddress());
}
class TestPacketService implements PacketService {
......
......@@ -19,12 +19,9 @@ import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
......@@ -91,6 +88,7 @@ public class ProxyArpManagerTest {
private static final PortNumber P1 = PortNumber.portNumber(1);
private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
private static final HostLocation LOC2 = new HostLocation(DID2, P1, 123L);
private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
private ProxyArpManager proxyArp;
......@@ -483,7 +481,7 @@ public class ProxyArpManagerTest {
*/
private void verifyPacketOut(Ethernet expected, ConnectPoint outPort,
OutboundPacket actual) {
assertTrue(Arrays.equals(expected.serialize(), actual.data().array()));
assertArrayEquals(expected.serialize(), actual.data().array());
assertEquals(1, actual.treatment().instructions().size());
assertEquals(outPort.deviceId(), actual.sendThrough());
Instruction instruction = actual.treatment().instructions().get(0);
......@@ -520,12 +518,12 @@ public class ProxyArpManagerTest {
Ethernet eth = new Ethernet();
if (dstMac == null) {
eth.setDestinationMACAddress(MacAddress.BROADCAST_MAC);
eth.setDestinationMACAddress(MacAddress.BROADCAST);
} else {
eth.setDestinationMACAddress(dstMac.getAddress());
eth.setDestinationMACAddress(dstMac);
}
eth.setSourceMACAddress(srcMac.getAddress());
eth.setSourceMACAddress(srcMac);
eth.setEtherType(Ethernet.TYPE_ARP);
eth.setVlanID(VLAN1.toShort());
......@@ -536,12 +534,12 @@ public class ProxyArpManagerTest {
arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH);
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
arp.setSenderHardwareAddress(srcMac.getAddress());
arp.setSenderHardwareAddress(srcMac.toBytes());
if (dstMac == null) {
arp.setTargetHardwareAddress(MacAddress.ZERO_MAC_ADDRESS);
arp.setTargetHardwareAddress(ZERO_MAC_ADDRESS);
} else {
arp.setTargetHardwareAddress(dstMac.getAddress());
arp.setTargetHardwareAddress(dstMac.toBytes());
}
arp.setSenderProtocolAddress(srcIp.toOctets());
......
......@@ -147,8 +147,7 @@ public class DistributedClusterStore
}
private IpAddress memberAddress(Member member) {
byte[] address = member.getSocketAddress().getAddress().getAddress();
return IpAddress.valueOf(address);
return IpAddress.valueOf(member.getSocketAddress().getAddress());
}
// Interceptor for membership events.
......
......@@ -85,7 +85,6 @@ public class ClusterCommunicationManager
try {
netty.activate();
} catch (Exception e) {
// TODO Auto-generated catch block
log.error("NettyMessagingService#activate", e);
}
messagingService = netty;
......@@ -95,6 +94,12 @@ public class ClusterCommunicationManager
@Deactivate
public void deactivate() {
// TODO: cleanup messageingService if needed.
// FIXME: workaround until it becomes a service.
try {
((NettyMessagingService) messagingService).deactivate();
} catch (Exception e) {
log.error("NettyMessagingService#deactivate", e);
}
log.info("Stopped");
}
......
......@@ -72,4 +72,9 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid
log.info("adding term info {} {}", deviceId, term.master());
deviceMastershipTerms.put(deviceId, term);
}
@Override
public boolean isTimestampAvailable(DeviceId deviceId) {
return deviceMastershipTerms.containsKey(deviceId);
}
}
......
......@@ -1216,7 +1216,7 @@ public class GossipDeviceStore
@Override
public void handle(ClusterMessage message) {
log.info("Received device update event from peer: {}", message.sender());
log.debug("Received device update event from peer: {}", message.sender());
InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload());
ProviderId providerId = event.providerId();
......@@ -1231,7 +1231,7 @@ public class GossipDeviceStore
@Override
public void handle(ClusterMessage message) {
log.info("Received device offline event from peer: {}", message.sender());
log.debug("Received device offline event from peer: {}", message.sender());
InternalDeviceOfflineEvent event = (InternalDeviceOfflineEvent) SERIALIZER.decode(message.payload());
DeviceId deviceId = event.deviceId();
......@@ -1245,7 +1245,7 @@ public class GossipDeviceStore
@Override
public void handle(ClusterMessage message) {
log.info("Received device removed event from peer: {}", message.sender());
log.debug("Received device removed event from peer: {}", message.sender());
InternalDeviceRemovedEvent event = (InternalDeviceRemovedEvent) SERIALIZER.decode(message.payload());
DeviceId deviceId = event.deviceId();
......@@ -1259,13 +1259,19 @@ public class GossipDeviceStore
@Override
public void handle(ClusterMessage message) {
log.info("Received port update event from peer: {}", message.sender());
log.debug("Received port update event from peer: {}", message.sender());
InternalPortEvent event = (InternalPortEvent) SERIALIZER.decode(message.payload());
ProviderId providerId = event.providerId();
DeviceId deviceId = event.deviceId();
Timestamped<List<PortDescription>> portDescriptions = event.portDescriptions();
if (getDevice(deviceId) == null) {
log.info("{} not found on this node yet, ignoring.", deviceId);
// Note: dropped information will be recovered by anti-entropy
return;
}
notifyDelegate(updatePortsInternal(providerId, deviceId, portDescriptions));
}
}
......@@ -1274,14 +1280,19 @@ public class GossipDeviceStore
@Override
public void handle(ClusterMessage message) {
log.info("Received port status update event from peer: {}", message.sender());
log.debug("Received port status update event from peer: {}", message.sender());
InternalPortStatusEvent event = (InternalPortStatusEvent) SERIALIZER.decode(message.payload());
log.info("{}", event);
ProviderId providerId = event.providerId();
DeviceId deviceId = event.deviceId();
Timestamped<PortDescription> portDescription = event.portDescription();
if (getDevice(deviceId) == null) {
log.info("{} not found on this node yet, ignoring.", deviceId);
// Note: dropped information will be recovered by anti-entropy
return;
}
notifyDelegateIfNotNull(updatePortStatusInternal(providerId, deviceId, portDescription));
}
}
......
......@@ -36,7 +36,7 @@ public class ReplicaInfoEvent extends AbstractEvent<ReplicaInfoEvent.Type, Devic
*/
MASTER_CHANGED,
//
// BACKUPS_CHANGED?
BACKUPS_CHANGED,
}
......
......@@ -284,9 +284,10 @@ public class DistributedFlowRuleStore
if (!replicaInfo.master().isPresent()) {
log.warn("No master for {}", deviceId);
// TODO: revisit if this should be returning empty collection.
// TODO: revisit if this should be returning empty collection or throwing exception.
// FIXME: throw a FlowStoreException
throw new RuntimeException("No master for " + deviceId);
//throw new RuntimeException("No master for " + deviceId);
return Collections.emptyList();
}
if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
......
......@@ -18,10 +18,9 @@ package org.onlab.onos.store.flow.impl;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import static org.onlab.onos.store.flow.ReplicaInfoEvent.Type.MASTER_CHANGED;
import static org.onlab.onos.store.flow.ReplicaInfoEvent.Type.BACKUPS_CHANGED;
import java.util.Collections;
import java.util.List;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -96,12 +95,24 @@ public class ReplicaInfoManager implements ReplicaInfoService {
@Override
public void event(MastershipEvent event) {
// TODO: distinguish stby list update, when MastershipService,
// start publishing them
final List<NodeId> standbyList = Collections.<NodeId>emptyList();
eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
event.subject(),
new ReplicaInfo(event.roleInfo().master(), standbyList)));
final ReplicaInfo replicaInfo
= new ReplicaInfo(event.roleInfo().master(),
event.roleInfo().backups());
switch (event.type()) {
case MASTER_CHANGED:
eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
event.subject(),
replicaInfo));
break;
case BACKUPS_CHANGED:
eventDispatcher.post(new ReplicaInfoEvent(BACKUPS_CHANGED,
event.subject(),
replicaInfo));
break;
default:
break;
}
}
}
......
......@@ -16,6 +16,7 @@
package org.onlab.onos.store.mastership.impl;
import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED;
import static org.onlab.onos.mastership.MastershipEvent.Type.BACKUPS_CHANGED;
import static org.apache.commons.lang3.concurrent.ConcurrentUtils.putIfAbsent;
import java.util.HashSet;
......@@ -43,6 +44,7 @@ import org.onlab.onos.store.serializers.KryoNamespaces;
import org.onlab.onos.store.serializers.KryoSerializer;
import org.onlab.util.KryoNamespace;
import com.google.common.base.Objects;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.IAtomicLong;
......@@ -297,8 +299,7 @@ implements MastershipStore {
case NONE:
rv.reassign(nodeId, NONE, STANDBY);
roleMap.put(deviceId, rv);
// TODO: BACKUPS_CHANGED?
return null;
return new MastershipEvent(BACKUPS_CHANGED, deviceId, rv.roleInfo());
default:
log.warn("unknown Mastership Role {}", currentRole);
}
......@@ -327,7 +328,8 @@ implements MastershipStore {
roleMap.put(deviceId, rv);
return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
} else {
// no master candidate
// No master candidate - no more backups, device is likely
// fully disconnected
roleMap.put(deviceId, rv);
// Should there be new event type?
return null;
......@@ -338,8 +340,7 @@ implements MastershipStore {
boolean modified = rv.reassign(nodeId, STANDBY, NONE);
if (modified) {
roleMap.put(deviceId, rv);
// TODO: BACKUPS_CHANGED?
return null;
return new MastershipEvent(BACKUPS_CHANGED, deviceId, rv.roleInfo());
}
return null;
default:
......@@ -441,8 +442,24 @@ implements MastershipStore {
@Override
public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) {
notifyDelegate(new MastershipEvent(
MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
// compare old and current RoleValues. If master is different,
// emit MASTER_CHANGED. else, emit BACKUPS_CHANGED.
RoleValue oldValue = event.getOldValue();
RoleValue newValue = event.getValue();
NodeId oldMaster = null;
if (oldValue != null) {
oldMaster = oldValue.get(MASTER);
}
NodeId newMaster = newValue.get(MASTER);
if (Objects.equal(oldMaster, newMaster)) {
notifyDelegate(new MastershipEvent(
MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
} else {
notifyDelegate(new MastershipEvent(
BACKUPS_CHANGED, event.getKey(), event.getValue().roleInfo()));
}
}
@Override
......
......@@ -55,6 +55,13 @@ final class RoleValue {
return value.get(type);
}
/**
* Returns the first node to match the MastershipRole, or if there
* are none, null.
*
* @param type the role
* @return a node ID or null
*/
public NodeId get(MastershipRole type) {
return value.get(type).isEmpty() ? null : value.get(type).get(0);
}
......
......@@ -214,11 +214,11 @@ public class DistributedMastershipStoreTest {
dms.roleMap.get(DID1).nodesOfRole(STANDBY).size());
//If STANDBY, should drop to NONE
assertNull("wrong event:", dms.relinquishRole(N1, DID1));
assertEquals("wrong event:", Type.BACKUPS_CHANGED, dms.relinquishRole(N1, DID1).type());
assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
//NONE - nothing happens
assertNull("wrong event:", dms.relinquishRole(N1, DID2));
assertEquals("wrong event:", Type.BACKUPS_CHANGED, dms.relinquishRole(N1, DID2).type());
assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
}
......
......@@ -46,7 +46,13 @@ public class IpAddressSerializer extends Serializer<IpAddress> {
final int octLen = input.readInt();
byte[] octs = new byte[octLen];
input.readBytes(octs);
return IpAddress.valueOf(octs);
// Use the address size to decide whether it is IPv4 or IPv6 address
if (octLen == IpAddress.INET_BYTE_LENGTH) {
return IpAddress.valueOf(IpAddress.Version.INET, octs);
}
if (octLen == IpAddress.INET6_BYTE_LENGTH) {
return IpAddress.valueOf(IpAddress.Version.INET6, octs);
}
return null; // Shouldn't be reached
}
}
......
......@@ -15,6 +15,7 @@
*/
package org.onlab.onos.store.serializers;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import com.esotericsoftware.kryo.Kryo;
......@@ -51,6 +52,13 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> {
byte[] octs = new byte[octLen];
input.readBytes(octs);
int prefLen = input.readInt();
return IpPrefix.valueOf(octs, prefLen);
// Use the address size to decide whether it is IPv4 or IPv6 address
if (octLen == IpAddress.INET_BYTE_LENGTH) {
return IpPrefix.valueOf(IpAddress.Version.INET, octs, prefLen);
}
if (octLen == IpAddress.INET6_BYTE_LENGTH) {
return IpPrefix.valueOf(IpAddress.Version.INET6, octs, prefLen);
}
return null; // Shouldn't be reached
}
}
......
......@@ -36,7 +36,7 @@ public class MacAddressSerializer extends Serializer<MacAddress> {
@Override
public void write(Kryo kryo, Output output, MacAddress object) {
output.writeBytes(object.getAddress());
output.writeBytes(object.toBytes());
}
@Override
......
......@@ -15,13 +15,16 @@
*/
package org.onlab.onos.store.trivial.impl;
import java.util.Set;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.mastership.MastershipTerm;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceClockProviderService;
//FIXME: Code clone in onos-core-trivial, onos-core-hz-net
import com.google.common.collect.Sets;
/**
* Dummy implementation of {@link DeviceClockProviderService}.
*/
......@@ -29,7 +32,15 @@ import org.onlab.onos.net.device.DeviceClockProviderService;
@Service
public class NoOpClockProviderService implements DeviceClockProviderService {
private Set<DeviceId> registerdBefore = Sets.newConcurrentHashSet();
@Override
public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
registerdBefore.add(deviceId);
}
@Override
public boolean isTimestampAvailable(DeviceId deviceId) {
return registerdBefore.contains(deviceId);
}
}
......
......@@ -16,8 +16,12 @@
package org.onlab.onos.store.trivial.impl;
import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.FluentIterable;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -43,13 +47,15 @@ import org.onlab.onos.store.AbstractStore;
import org.onlab.util.NewConcurrentHashMap;
import org.slf4j.Logger;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
......@@ -72,6 +78,18 @@ public class SimpleFlowRuleStore
private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>>
flowEntries = new ConcurrentHashMap<>();
private final AtomicInteger localBatchIdGen = new AtomicInteger();
// TODO: make this configurable
private int pendingFutureTimeoutMinutes = 5;
private Cache<Integer, SettableFuture<CompletedBatchOperation>> pendingFutures =
CacheBuilder.newBuilder()
.expireAfterWrite(pendingFutureTimeoutMinutes, TimeUnit.MINUTES)
// TODO Explicitly fail the future if expired?
//.removalListener(listener)
.build();
@Activate
public void activate() {
log.info("Started");
......@@ -173,10 +191,6 @@ public class SimpleFlowRuleStore
}
// new flow rule added
existing.add(f);
notifyDelegate(FlowRuleBatchEvent.requested(
new FlowRuleBatchRequest(1, /* FIXME generate something */
Arrays.<FlowEntry>asList(f),
Collections.<FlowEntry>emptyList())));
}
}
......@@ -190,11 +204,6 @@ public class SimpleFlowRuleStore
if (entry.equals(rule)) {
synchronized (entry) {
entry.setState(FlowEntryState.PENDING_REMOVE);
// TODO: Should we notify only if it's "remote" event?
notifyDelegate(FlowRuleBatchEvent.requested(
new FlowRuleBatchRequest(1, /* FIXME generate something */
Collections.<FlowEntry>emptyList(),
Arrays.<FlowEntry>asList(entry))));
}
}
}
......@@ -251,20 +260,47 @@ public class SimpleFlowRuleStore
@Override
public Future<CompletedBatchOperation> storeBatch(
FlowRuleBatchOperation batchOperation) {
List<FlowRule> toAdd = new ArrayList<>();
List<FlowRule> toRemove = new ArrayList<>();
for (FlowRuleBatchEntry entry : batchOperation.getOperations()) {
final FlowRule flowRule = entry.getTarget();
if (entry.getOperator().equals(FlowRuleOperation.ADD)) {
storeFlowRule(entry.getTarget());
if (!getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) {
storeFlowRule(flowRule);
toAdd.add(flowRule);
}
} else if (entry.getOperator().equals(FlowRuleOperation.REMOVE)) {
deleteFlowRule(entry.getTarget());
if (getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) {
deleteFlowRule(flowRule);
toRemove.add(flowRule);
}
} else {
throw new UnsupportedOperationException("Unsupported operation type");
}
}
return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowEntry>emptySet()));
if (toAdd.isEmpty() && toRemove.isEmpty()) {
return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowRule>emptySet()));
}
SettableFuture<CompletedBatchOperation> r = SettableFuture.create();
final int batchId = localBatchIdGen.incrementAndGet();
pendingFutures.put(batchId, r);
notifyDelegate(FlowRuleBatchEvent.requested(new FlowRuleBatchRequest(batchId, toAdd, toRemove)));
return r;
}
@Override
public void batchOperationComplete(FlowRuleBatchEvent event) {
final Integer batchId = event.subject().batchId();
SettableFuture<CompletedBatchOperation> future
= pendingFutures.getIfPresent(batchId);
if (future != null) {
future.set(event.result());
pendingFutures.invalidate(batchId);
}
notifyDelegate(event);
}
}
......
......@@ -115,17 +115,25 @@ public interface OpenFlowSwitch {
public String serialNumber();
/**
* Checks if the switch is still connected.
*
* @return whether the switch is still connected
*/
public boolean isConnected();
/**
* Disconnects the switch by closing the TCP connection. Results in a call
* to the channel handler's channelDisconnected method for cleanup
*/
public void disconnectSwitch();
/**
* Notifies the controller that role assertion has failed.
* Notifies the controller that the device has responded to a set-role request.
*
* @param role the failed role
* @param requested the role requested by the controller
* @param response the role set at the device
*/
public void returnRoleAssertFailure(RoleState role);
public void returnRoleReply(RoleState requested, RoleState reponse);
/**
* Indicates if this switch is optical.
......
......@@ -53,5 +53,5 @@ public interface OpenFlowSwitchListener {
* @param dpid the switch that failed role assertion
* @param role the role imposed by the controller
*/
public void roleAssertFailed(Dpid dpid, RoleState role);
public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response);
}
......
......@@ -217,8 +217,8 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
}
@Override
public void returnRoleAssertFailure(RoleState role) {
this.agent.returnRoleAssertFailed(dpid, role);
public void returnRoleReply(RoleState requested, RoleState response) {
this.agent.returnRoleReply(dpid, requested, response);
}
@Override
......
......@@ -97,5 +97,5 @@ public interface OpenFlowAgent {
* @param dpid the switch that failed role assertion
* @param role the failed role
*/
public void returnRoleAssertFailed(Dpid dpid, RoleState role);
public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response);
}
......
......@@ -187,13 +187,6 @@ public interface OpenFlowSwitchDriver extends OpenFlowSwitch {
public void setConnected(boolean connected);
/**
* Checks if the switch is still connected.
*
* @return whether the switch is still connected
*/
public boolean isConnected();
/**
* Writes the message to the output stream
* in a driver specific manner.
*
......
......@@ -374,9 +374,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
@Override
public void returnRoleAssertFailed(Dpid dpid, RoleState role) {
public void returnRoleReply(Dpid dpid, RoleState requested, RoleState response) {
for (OpenFlowSwitchListener l : ofSwitchListener) {
l.roleAssertFailed(dpid, role);
l.receivedRoleReply(dpid, requested, response);
}
}
}
......
......@@ -17,6 +17,7 @@ package org.onlab.onos.openflow.controller.impl;
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.onlab.onos.openflow.controller.RoleState;
import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
......@@ -41,31 +42,29 @@ import org.projectfloodlight.openflow.types.U64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
/**
* A utility class to handle role requests and replies for this channel.
* After a role request is submitted the role changer keeps track of the
* pending request, collects the reply (if any) and times out the request
* if necessary.
*
* To simplify role handling we only keep track of the /last/ pending
* role reply send to the switch. If multiple requests are pending and
* we receive replies for earlier requests we ignore them. However, this
* way of handling pending requests implies that we could wait forever if
* a new request is submitted before the timeout triggers. If necessary
* we could work around that though.
*/
class RoleManager implements RoleHandler {
protected static final long NICIRA_EXPERIMENTER = 0x2320;
private static Logger log = LoggerFactory.getLogger(RoleManager.class);
// indicates that a request is currently pending
// needs to be volatile to allow correct double-check idiom
private volatile boolean requestPending;
// the transaction Id of the pending request
private int pendingXid;
// the role that's pending
private RoleState pendingRole;
// The time until cached XID is evicted. Arbitray for now.
private final int pendingXidTimeoutSeconds = 60;
// The cache for pending expected RoleReplies keyed on expected XID
private Cache<Integer, RoleState> pendingReplies =
CacheBuilder.newBuilder()
.expireAfterWrite(pendingXidTimeoutSeconds, TimeUnit.SECONDS)
.build();
// the expectation set by the caller for the returned role
private RoleRecvStatus expectation;
......@@ -73,9 +72,6 @@ class RoleManager implements RoleHandler {
public RoleManager(OpenFlowSwitchDriver sw) {
this.requestPending = false;
this.pendingXid = -1;
this.pendingRole = null;
this.expectation = RoleRecvStatus.MATCHED_CURRENT_ROLE;
this.sw = sw;
}
......@@ -157,15 +153,11 @@ class RoleManager implements RoleHandler {
}
// OF1.0 switch with support for NX_ROLE_REQUEST vendor extn.
// make Role.EQUAL become Role.SLAVE
pendingRole = role;
role = (role == RoleState.EQUAL) ? RoleState.SLAVE : role;
pendingXid = sendNxRoleRequest(role);
requestPending = true;
RoleState roleToSend = (role == RoleState.EQUAL) ? RoleState.SLAVE : role;
pendingReplies.put(sendNxRoleRequest(roleToSend), role);
} else {
// OF1.3 switch, use OFPT_ROLE_REQUEST message
pendingXid = sendOF13RoleRequest(role);
pendingRole = role;
requestPending = true;
pendingReplies.put(sendOF13RoleRequest(role), role);
}
return true;
}
......@@ -192,12 +184,17 @@ class RoleManager implements RoleHandler {
@Override
public synchronized RoleRecvStatus deliverRoleReply(RoleReplyInfo rri)
throws SwitchStateException {
if (!requestPending) {
int xid = (int) rri.getXid();
RoleState receivedRole = rri.getRole();
RoleState expectedRole = pendingReplies.getIfPresent(xid);
if (expectedRole == null) {
RoleState currentRole = (sw != null) ? sw.getRole() : null;
if (currentRole != null) {
if (currentRole == rri.getRole()) {
// Don't disconnect if the role reply we received is
// for the same role we are already in.
// FIXME: but we do from the caller anyways.
log.debug("Received unexpected RoleReply from "
+ "Switch: {}. "
+ "Role in reply is same as current role of this "
......@@ -223,34 +220,33 @@ class RoleManager implements RoleHandler {
return RoleRecvStatus.OTHER_EXPECTATION;
}
int xid = (int) rri.getXid();
RoleState role = rri.getRole();
// XXX S should check generation id meaningfully and other cases of expectations
if (pendingXid != xid) {
log.debug("Received older role reply from " +
"switch {} ({}). Ignoring. " +
"Waiting for {}, xid={}",
new Object[] {sw.getStringId(), rri,
pendingRole, pendingXid });
return RoleRecvStatus.OLD_REPLY;
}
if (pendingRole == role) {
// XXX Should check generation id meaningfully and other cases of expectations
//if (pendingXid != xid) {
// log.info("Received older role reply from " +
// "switch {} ({}). Ignoring. " +
// "Waiting for {}, xid={}",
// new Object[] {sw.getStringId(), rri,
// pendingRole, pendingXid });
// return RoleRecvStatus.OLD_REPLY;
//}
sw.returnRoleReply(expectedRole, receivedRole);
if (expectedRole == receivedRole) {
log.debug("Received role reply message from {} that matched "
+ "expected role-reply {} with expectations {}",
new Object[] {sw.getStringId(), role, expectation});
new Object[] {sw.getStringId(), receivedRole, expectation});
// Done with this RoleReply; Invalidate
pendingReplies.invalidate(xid);
if (expectation == RoleRecvStatus.MATCHED_CURRENT_ROLE ||
expectation == RoleRecvStatus.MATCHED_SET_ROLE) {
return expectation;
} else {
return RoleRecvStatus.OTHER_EXPECTATION;
}
} else {
sw.returnRoleAssertFailure(pendingRole);
}
pendingReplies.invalidate(xid);
// if xids match but role's don't, perhaps its a query (OF1.3)
if (expectation == RoleRecvStatus.REPLY_QUERY) {
return expectation;
......@@ -270,18 +266,17 @@ class RoleManager implements RoleHandler {
@Override
public synchronized RoleRecvStatus deliverError(OFErrorMsg error)
throws SwitchStateException {
if (!requestPending) {
log.debug("Received an error msg from sw {}, but no pending "
+ "requests in role-changer; not handling ...",
sw.getStringId());
return RoleRecvStatus.OTHER_EXPECTATION;
}
if (pendingXid != error.getXid()) {
RoleState errorRole = pendingReplies.getIfPresent(error.getXid());
if (errorRole == null) {
if (error.getErrType() == OFErrorType.ROLE_REQUEST_FAILED) {
log.debug("Received an error msg from sw {} for a role request,"
+ " but not for pending request in role-changer; "
+ " ignoring error {} ...",
sw.getStringId(), error);
} else {
log.debug("Received an error msg from sw {}, but no pending "
+ "requests in role-changer; not handling ...",
sw.getStringId());
}
return RoleRecvStatus.OTHER_EXPECTATION;
}
......@@ -292,7 +287,7 @@ class RoleManager implements RoleHandler {
+ "role-messaging is supported. Possible issues in "
+ "switch driver configuration?", new Object[] {
((OFBadRequestErrorMsg) error).toString(),
sw.getStringId(), pendingRole
sw.getStringId(), errorRole
});
return RoleRecvStatus.UNSUPPORTED;
}
......@@ -316,7 +311,7 @@ class RoleManager implements RoleHandler {
+ "received Error to for pending role request [%s]. "
+ "Error:[%s]. Disconnecting switch ... ",
sw.getStringId(),
pendingRole, rrerr);
errorRole, rrerr);
throw new SwitchStateException(msgx);
default:
break;
......
......@@ -175,11 +175,6 @@ public class RoleManagerTest {
}
@Override
public void returnRoleAssertFailure(RoleState role) {
failed = role;
}
@Override
public boolean isOptical() {
return false;
}
......@@ -300,5 +295,10 @@ public class RoleManagerTest {
public void write(List<OFMessage> msgs) {
}
@Override
public void returnRoleReply(RoleState requested, RoleState response) {
failed = requested;
}
}
}
......
......@@ -318,6 +318,7 @@
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty4.version}</version>
<classifier>${os.detected.classifier}</classifier>
</dependency>
<dependency>
<groupId>joda-time</groupId>
......@@ -351,6 +352,13 @@
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.2.3.Final</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<plugin>
......
......@@ -120,7 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
if (eth.getEtherType() == Ethernet.TYPE_ARP) {
ARP arp = (ARP) eth.getPayload();
IpAddress ip =
IpAddress.valueOf(arp.getSenderProtocolAddress());
IpAddress.valueOf(IpAddress.Version.INET,
arp.getSenderProtocolAddress());
HostDescription hdescr =
new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
providerService.hostDetected(hid, hdescr);
......
......@@ -216,7 +216,7 @@ public class HostLocationProviderTest {
eth.setEtherType(Ethernet.TYPE_ARP)
.setVlanID(VLAN.toShort())
.setSourceMACAddress(MAC.toBytes())
.setDestinationMACAddress(BCMAC.getAddress())
.setDestinationMACAddress(BCMAC)
.setPayload(arp);
ConnectPoint receivedFrom = new ConnectPoint(DeviceId.deviceId(deviceId),
PortNumber.portNumber(INPORT));
......
......@@ -127,18 +127,19 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
return;
}
log.trace("{} {} {}", event.type(), event.subject(), event);
final DeviceId deviceId = device.id();
switch (event.type()) {
case DEVICE_ADDED:
case DEVICE_UPDATED:
ld = discoverers.get(device.id());
ld = discoverers.get(deviceId);
if (ld == null) {
log.debug("Device added ({}) {}", event.type(), device.id());
discoverers.put(device.id(),
log.debug("Device added ({}) {}", event.type(), deviceId);
discoverers.put(deviceId,
new LinkDiscovery(device, packetSevice, masterService,
providerService, useBDDP));
} else {
if (ld.isStopped()) {
log.debug("Device restarted ({}) {}", event.type(), device.id());
log.debug("Device restarted ({}) {}", event.type(), deviceId);
ld.start();
}
}
......@@ -146,7 +147,7 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
case PORT_ADDED:
case PORT_UPDATED:
if (port.isEnabled()) {
ld = discoverers.get(device.id());
ld = discoverers.get(deviceId);
if (ld == null) {
return;
}
......@@ -156,47 +157,47 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
}
} else {
log.debug("Port down {}", port);
ConnectPoint point = new ConnectPoint(device.id(),
ConnectPoint point = new ConnectPoint(deviceId,
port.number());
providerService.linksVanished(point);
}
break;
case PORT_REMOVED:
log.debug("Port removed {}", port);
ConnectPoint point = new ConnectPoint(device.id(),
ConnectPoint point = new ConnectPoint(deviceId,
port.number());
providerService.linksVanished(point);
// TODO: Don't we need to removePort from ld?
break;
case DEVICE_REMOVED:
case DEVICE_SUSPENDED:
log.debug("Device removed {}", device.id());
ld = discoverers.get(device.id());
log.debug("Device removed {}", deviceId);
ld = discoverers.get(deviceId);
if (ld == null) {
return;
}
ld.stop();
providerService.linksVanished(device.id());
providerService.linksVanished(deviceId);
break;
case DEVICE_AVAILABILITY_CHANGED:
ld = discoverers.get(device.id());
ld = discoverers.get(deviceId);
if (ld == null) {
return;
}
if (deviceService.isAvailable(device.id())) {
log.debug("Device up {}", device.id());
if (deviceService.isAvailable(deviceId)) {
log.debug("Device up {}", deviceId);
ld.start();
} else {
providerService.linksVanished(device.id());
log.debug("Device down {}", device.id());
providerService.linksVanished(deviceId);
log.debug("Device down {}", deviceId);
ld.stop();
}
break;
case DEVICE_MASTERSHIP_CHANGED:
if (!discoverers.containsKey(device.id())) {
if (!discoverers.containsKey(deviceId)) {
// TODO: ideally, should never reach here
log.debug("Device mastership changed ({}) {}", event.type(), device.id());
discoverers.put(device.id(),
log.debug("Device mastership changed ({}) {}", event.type(), deviceId);
discoverers.put(deviceId,
new LinkDiscovery(device, packetSevice, masterService,
providerService, useBDDP));
}
......
......@@ -39,7 +39,6 @@ import org.onlab.onos.openflow.controller.OpenFlowController;
import org.onlab.onos.openflow.controller.OpenFlowSwitch;
import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
import org.onlab.onos.openflow.controller.RoleState;
import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
import org.onlab.packet.ChassisId;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
......@@ -112,27 +111,39 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
@Override
public boolean isReachable(Device device) {
// FIXME if possible, we might want this to be part of
// OpenFlowSwitch interface so the driver interface isn't misused.
OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri()));
if (sw == null || !((OpenFlowSwitchDriver) sw).isConnected()) {
public boolean isReachable(DeviceId deviceId) {
OpenFlowSwitch sw = controller.getSwitch(dpid(deviceId.uri()));
if (sw == null || !sw.isConnected()) {
return false;
}
return true;
//return checkChannel(device, sw);
}
@Override
public void triggerProbe(Device device) {
LOG.info("Triggering probe on device {}", device.id());
OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri()));
//if (!checkChannel(device, sw)) {
// LOG.error("Failed to probe device {} on sw={}", device, sw);
// providerService.deviceDisconnected(device.id());
//return;
//}
final DeviceId deviceId = device.id();
LOG.info("Triggering probe on device {}", deviceId);
final Dpid dpid = dpid(deviceId.uri());
OpenFlowSwitch sw = controller.getSwitch(dpid);
if (sw == null || !sw.isConnected()) {
LOG.error("Failed to probe device {} on sw={}", device, sw);
providerService.deviceDisconnected(deviceId);
} else {
LOG.trace("Confirmed device {} connection", device);
// FIXME require something like below to match javadoc description
// but this starts infinite loop with current DeviceManager
// final ChassisId cId = new ChassisId(dpid.value());
// final Type deviceType = device.type();
// DeviceDescription description =
// new DefaultDeviceDescription(deviceId.uri(), deviceType,
// sw.manfacturerDescription(),
// sw.hardwareDescription(),
// sw.softwareDescription(),
// sw.serialNumber(),
// cId);
// providerService.deviceConnected(deviceId, description);
}
// Prompt an update of port information. We can use any XID for this.
OFFactory fact = sw.factory();
......@@ -159,22 +170,22 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
// }
@Override
public void roleChanged(Device device, MastershipRole newRole) {
public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
switch (newRole) {
case MASTER:
controller.setRole(dpid(device.id().uri()), RoleState.MASTER);
controller.setRole(dpid(deviceId.uri()), RoleState.MASTER);
break;
case STANDBY:
controller.setRole(dpid(device.id().uri()), RoleState.EQUAL);
controller.setRole(dpid(deviceId.uri()), RoleState.EQUAL);
break;
case NONE:
controller.setRole(dpid(device.id().uri()), RoleState.SLAVE);
controller.setRole(dpid(deviceId.uri()), RoleState.SLAVE);
break;
default:
LOG.error("Unknown Mastership state : {}", newRole);
}
LOG.info("Accepting mastership role change for device {}", device.id());
LOG.info("Accepting mastership role change for device {}", deviceId);
}
private class InternalDeviceProvider implements OpenFlowSwitchListener {
......@@ -226,23 +237,31 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
}
@Override
public void roleAssertFailed(Dpid dpid, RoleState role) {
MastershipRole failed;
switch (role) {
public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
MastershipRole request = roleOf(requested);
MastershipRole reply = roleOf(response);
providerService.receivedRoleReply(deviceId(uri(dpid)), request, reply);
}
/**
* Translates a RoleState to the corresponding MastershipRole.
*
* @param response
* @return a MastershipRole
*/
private MastershipRole roleOf(RoleState response) {
switch (response) {
case MASTER:
failed = MastershipRole.MASTER;
break;
return MastershipRole.MASTER;
case EQUAL:
failed = MastershipRole.STANDBY;
break;
return MastershipRole.STANDBY;
case SLAVE:
failed = MastershipRole.NONE;
break;
return MastershipRole.NONE;
default:
LOG.warn("unknown role {}", role);
return;
LOG.warn("unknown role {}", response);
return null;
}
providerService.unableToAssertRole(deviceId(uri(dpid)), failed);
}
/**
......
......@@ -105,11 +105,11 @@ public class OpenFlowDeviceProviderTest {
@Test
public void roleChanged() {
provider.roleChanged(DEV1, MASTER);
provider.roleChanged(DID1, MASTER);
assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
provider.roleChanged(DEV1, STANDBY);
provider.roleChanged(DID1, STANDBY);
assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
provider.roleChanged(DEV1, NONE);
provider.roleChanged(DID1, NONE);
assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
}
......@@ -136,12 +136,13 @@ public class OpenFlowDeviceProviderTest {
}
@Test
public void roleAssertFailed() {
controller.listener.roleAssertFailed(DPID1, RoleState.MASTER);
public void receivedRoleReply() {
// check translation capabilities
controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
controller.listener.roleAssertFailed(DPID1, RoleState.EQUAL);
controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
controller.listener.roleAssertFailed(DPID1, RoleState.SLAVE);
controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
}
......@@ -210,8 +211,9 @@ public class OpenFlowDeviceProviderTest {
}
@Override
public void unableToAssertRole(DeviceId deviceId, MastershipRole role) {
roles.put(role, Dpid.dpid(deviceId.uri()));
public void receivedRoleReply(DeviceId deviceId,
MastershipRole requested, MastershipRole response) {
roles.put(requested, Dpid.dpid(deviceId.uri()));
}
}
......@@ -368,11 +370,12 @@ public class OpenFlowDeviceProviderTest {
}
@Override
public void disconnectSwitch() {
public boolean isConnected() {
return true;
}
@Override
public void returnRoleAssertFailure(RoleState role) {
public void disconnectSwitch() {
}
@Override
......@@ -380,6 +383,10 @@ public class OpenFlowDeviceProviderTest {
return false;
}
@Override
public void returnRoleReply(RoleState requested, RoleState reponse) {
}
}
}
......
......@@ -147,7 +147,8 @@ public abstract class FlowModBuilder {
ip = (IPCriterion) c;
if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) {
IpAddress maskAddr =
IpAddress.makeMaskPrefix(ip.ip().prefixLength());
IpAddress.makeMaskPrefix(ip.ip().address().version(),
ip.ip().prefixLength());
Masked<IPv4Address> maskedIp =
Masked.of(IPv4Address.of(ip.ip().address().toInt()),
IPv4Address.of(maskAddr.toInt()));
......@@ -161,7 +162,8 @@ public abstract class FlowModBuilder {
ip = (IPCriterion) c;
if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) {
IpAddress maskAddr =
IpAddress.makeMaskPrefix(ip.ip().prefixLength());
IpAddress.makeMaskPrefix(ip.ip().address().version(),
ip.ip().prefixLength());
Masked<IPv4Address> maskedIp =
Masked.of(IPv4Address.of(ip.ip().address().toInt()),
IPv4Address.of(maskAddr.toInt()));
......
......@@ -302,7 +302,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
@Override
public void roleAssertFailed(Dpid dpid, RoleState role) {}
public void receivedRoleReply(Dpid dpid, RoleState requested,
RoleState response) {
// Do nothing here for now.
}
private synchronized void pushFlowMetrics(Dpid dpid, OFStatsReply stats) {
if (stats.getStatsType() != OFStatsType.FLOW) {
......
......@@ -126,7 +126,8 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid
if (eth.getEtherType() == Ethernet.TYPE_ARP) {
ARP arp = (ARP) eth.getPayload();
IpAddress ip =
IpAddress.valueOf(arp.getSenderProtocolAddress());
IpAddress.valueOf(IpAddress.Version.INET,
arp.getSenderProtocolAddress());
HostDescription hdescr =
new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
providerService.hostDetected(hid, hdescr);
......
......@@ -213,8 +213,8 @@ public class OpenFlowHostProviderTest {
Ethernet eth = new Ethernet();
eth.setEtherType(Ethernet.TYPE_ARP)
.setVlanID(VLAN.toShort())
.setSourceMACAddress(MAC.toBytes())
.setDestinationMACAddress(BCMAC.getAddress())
.setSourceMACAddress(MAC)
.setDestinationMACAddress(BCMAC)
.setPayload(arp);
return eth;
......
......@@ -160,7 +160,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
}
@Override
public void roleAssertFailed(Dpid dpid, RoleState role) {
public void receivedRoleReply(Dpid dpid, RoleState requested,
RoleState response) {
// do nothing for this.
}
......
......@@ -475,11 +475,12 @@ public class OpenFlowLinkProviderTest {
}
@Override
public void disconnectSwitch() {
public boolean isConnected() {
return true;
}
@Override
public void returnRoleAssertFailure(RoleState role) {
public void disconnectSwitch() {
}
@Override
......@@ -487,5 +488,9 @@ public class OpenFlowLinkProviderTest {
return false;
}
@Override
public void returnRoleReply(RoleState requested, RoleState reponse) {
}
}
}
......
......@@ -406,11 +406,12 @@ public class OpenFlowPacketProviderTest {
}
@Override
public void disconnectSwitch() {
public boolean isConnected() {
return true;
}
@Override
public void returnRoleAssertFailure(RoleState role) {
public void disconnectSwitch() {
}
@Override
......@@ -418,6 +419,10 @@ public class OpenFlowPacketProviderTest {
return false;
}
@Override
public void returnRoleReply(RoleState requested, RoleState reponse) {
}
}
}
......
#!/bin/bash
validate_number () {
local re="^[0-9]+$"
if [[ ! $1 =~ $re ]] ; then
return 1
fi
return 0
}
find_node () {
if validate_number $1 ; then
# input is a number, try to find if an OC node is defined
oc_try="OC$1"
node=${!oc_try}
if [ -n "$node" ]; then
# node lookup succeeded, return node
echo $node
else
# node lookup failed, return original input
echo $1
fi
else
echo $1
fi
return 0
}
......@@ -5,8 +5,9 @@
[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
. $ONOS_ROOT/tools/build/envDefaults
. $ONOS_ROOT/tools/test/bin/find-node.sh
[ "$1" = "-w" ] && shift && onos-wait-for-start $1
[ -n "$1" ] && OCI=$1 && shift
[ -n "$1" ] && OCI=$(find_node $1) && shift
client -h $OCI -u karaf "$@" 2>/dev/null
......
......@@ -5,12 +5,14 @@
[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
. $ONOS_ROOT/tools/build/envDefaults
. $ONOS_ROOT/tools/test/bin/find-node.sh
less=0
[ "$1" = "-l" ] && shift && less=1
remote=$ONOS_USER@${1:-$OCI}
remote=$(find_node $1)
remote=$ONOS_USER@${remote:-$OCI}
instance=$2
[ -n "$instance" ] && \
......
......@@ -18,6 +18,8 @@
package org.onlab.packet;
import static com.google.common.base.Preconditions.checkNotNull;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
......@@ -86,6 +88,17 @@ public class Ethernet extends BasePacket {
* @param destMac the destination MAC to set
* @return the Ethernet frame
*/
public Ethernet setDestinationMACAddress(final MacAddress destMac) {
this.destinationMACAddress = checkNotNull(destMac);
return this;
}
/**
* Sets the destination MAC address.
*
* @param destMac the destination MAC to set
* @return the Ethernet frame
*/
public Ethernet setDestinationMACAddress(final byte[] destMac) {
this.destinationMACAddress = MacAddress.valueOf(destMac);
return this;
......@@ -126,6 +139,17 @@ public class Ethernet extends BasePacket {
* @param sourceMac the source MAC to set
* @return the Ethernet frame
*/
public Ethernet setSourceMACAddress(final MacAddress sourceMac) {
this.sourceMACAddress = checkNotNull(sourceMac);
return this;
}
/**
* Sets the source MAC address.
*
* @param sourceMac the source MAC to set
* @return the Ethernet frame
*/
public Ethernet setSourceMACAddress(final byte[] sourceMac) {
this.sourceMACAddress = MacAddress.valueOf(sourceMac);
return this;
......
......@@ -76,12 +76,15 @@ public final class IpPrefix {
/**
* Converts a byte array and a prefix length into an IP prefix.
*
* @param version the IP address version
* @param address the IP address value stored in network byte order
* @param prefixLength the prefix length
* @return an IP prefix
*/
public static IpPrefix valueOf(byte[] address, int prefixLength) {
return new IpPrefix(IpAddress.valueOf(address), prefixLength);
public static IpPrefix valueOf(IpAddress.Version version, byte[] address,
int prefixLength) {
return new IpPrefix(IpAddress.valueOf(version, address),
prefixLength);
}
/**
......
......@@ -25,9 +25,6 @@ public class MacAddress {
public static final MacAddress ZERO = valueOf("00:00:00:00:00:00");
public static final MacAddress BROADCAST = valueOf("ff:ff:ff:ff:ff:ff");
public static final byte[] ZERO_MAC_ADDRESS = ZERO.getAddress();
public static final byte[] BROADCAST_MAC = BROADCAST.getAddress();
private static final byte[] LL = new byte[]{
0x01, (byte) 0x80, (byte) 0xc2, 0x00, 0x00,
0x00, 0x0e, 0x03
......@@ -217,8 +214,4 @@ public class MacAddress {
}
return builder.toString();
}
public byte[] getAddress() {
return this.address;
}
}
......
......@@ -64,7 +64,7 @@ public class ONOSLLDP extends LLDP {
setName(DEFAULT_NAME);
setDevice(DEFAULT_DEVICE);
setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV));
setTtl(new LLDPTLV().setType((byte) TTL_TLV_TYPE)
setTtl(new LLDPTLV().setType(TTL_TLV_TYPE)
.setLength((short) ttlValue.length)
.setValue(ttlValue));
......@@ -94,7 +94,7 @@ public class ONOSLLDP extends LLDP {
public void setChassisId(final ChassisId chassisId) {
MacAddress chassisMac = MacAddress.valueOf(chassisId.value());
byte[] chassis = ArrayUtils.addAll(new byte[] {CHASSIS_TLV_SUBTYPE},
chassisMac.getAddress());
chassisMac.toBytes());
LLDPTLV chassisTLV = new LLDPTLV();
chassisTLV.setLength(CHASSIS_TLV_SIZE);
......
This diff is collapsed. Click to expand it.
......@@ -38,9 +38,11 @@ public class IpPrefixTest {
@Test
public void testEquality() {
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip2 = IpPrefix.valueOf(INTVAL1, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip3 = IpPrefix.valueOf(BYTES2, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip3 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES2, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip4 = IpPrefix.valueOf(INTVAL2, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip5 = IpPrefix.valueOf(STRVAL);
......@@ -50,16 +52,19 @@ public class IpPrefixTest {
.testEquals();
// string conversions
IpPrefix ip6 = IpPrefix.valueOf(BYTES1, MASK_LENGTH);
IpPrefix ip6 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, MASK_LENGTH);
IpPrefix ip7 = IpPrefix.valueOf("10.0.0.10/16");
IpPrefix ip8 = IpPrefix.valueOf(new byte [] {0xa, 0x0, 0x0, 0xc}, 16);
IpPrefix ip8 = IpPrefix.valueOf(IpAddress.Version.INET,
new byte [] {0xa, 0x0, 0x0, 0xc}, 16);
assertEquals("incorrect address conversion", ip6, ip7);
assertEquals("incorrect address conversion", ip5, ip8);
}
@Test
public void basics() {
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH);
IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, MASK_LENGTH);
final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0x0};
// check fields
......@@ -74,7 +79,8 @@ public class IpPrefixTest {
@Test
public void netmasks() {
// masked
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH);
IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, MASK_LENGTH);
IpPrefix ip2 = IpPrefix.valueOf("10.0.0.10/16");
IpPrefix ip3 = IpPrefix.valueOf("10.0.0.0/16");
assertEquals("incorrect binary masked address",
......@@ -87,9 +93,12 @@ public class IpPrefixTest {
@Test
public void testContainsIpPrefix() {
IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31);
IpPrefix slash32 = IpPrefix.valueOf(BYTES1, 32);
IpPrefix differentSlash32 = IpPrefix.valueOf(BYTES2, 32);
IpPrefix slash31 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, 31);
IpPrefix slash32 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, 32);
IpPrefix differentSlash32 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES2, 32);
assertTrue(slash31.contains(differentSlash32));
assertFalse(differentSlash32.contains(slash31));
......@@ -109,8 +118,9 @@ public class IpPrefixTest {
@Test
public void testContainsIpAddress() {
IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31);
IpAddress addr32 = IpAddress.valueOf(BYTES1);
IpPrefix slash31 = IpPrefix.valueOf(IpAddress.Version.INET,
BYTES1, 31);
IpAddress addr32 = IpAddress.valueOf(IpAddress.Version.INET, BYTES1);
assertTrue(slash31.contains(addr32));
......
......@@ -73,6 +73,7 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty4.version}</version>
</dependency>
</dependencies>
......
......@@ -244,7 +244,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
}
@Override
public void roleChanged(Device device, MastershipRole newRole) {
public void roleChanged(DeviceId device, MastershipRole newRole) {
}
@Override
......@@ -257,7 +257,7 @@ class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
}
@Override
public boolean isReachable(Device device) {
public boolean isReachable(DeviceId device) {
return false;
}
}
......
......@@ -101,7 +101,7 @@ public class TopologyResource extends BaseResource {
new Prop("Vendor", device.manufacturer()),
new Prop("H/W Version", device.hwVersion()),
new Prop("S/W Version", device.swVersion()),
new Prop("S/W Version", device.serialNumber()),
new Prop("Serial Number", device.serialNumber()),
new Separator(),
new Prop("Latitude", annot.value("latitude")),
new Prop("Longitude", annot.value("longitude")),
......